diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..da548df39 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,64 @@ +name: "CodeQL" + +on: + push: + branches: [ 'master' ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 'master' ] + schedule: + - cron: '2 14 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp', 'python' ] + include: + - os: ubuntu-18.04 + DB: none + openarmor_TYPE: agent + GEOIP: no + PCRE2_SYSTEM: no + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + + - run: | + sudo apt-get update -qq + sudo apt-get install -y libevent-dev libsystemd-dev + wget https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.gz && tar xzf pcre2-10.32.tar.gz -C src/external + if [[ "${GEOIP}" == "yes" ]]; then ( sudo apt-get install geoip-bin geoip-database libgeoip-dev libgeoip1 ); fi + if [[ "${PRELUDE}" == "yes" ]]; then ( sudo apt-get install libprelude-dev ); fi + if [[ "${ZEROMQ}" == "yes" ]]; then ( sudo apt-get install libzmq3-dev libtool autoconf libczmq-dev ); fi + if [[ "${openarmor_TYPE}" == "winagent" ]]; then ( sudo apt-get install aptitude && sudo aptitude -y install mingw-w64 nsis ); fi + if [[ "${openarmor_TYPE}" == "server" ]]; then ( sudo apt-get install libsqlite3-dev sqlite3 ); fi + if [[ "${openarmor_TYPE}" == "test" ]]; then if [ `uname -m` = "aarch64"]; then (sudo apt-get install check libc6-dbg && wget -q http://ports.ubuntu.com/pool/main/v/valgrind/valgrind_3.15.0-1ubuntu9.1_arm64.deb && sudo dpkg -i valgrind_3.15.0-1ubuntu9.1_arm64.deb ) ; else ( sudo apt-get install check valgrind ); fi; fi + COMMAND="V=1 TARGET=${openarmor_TYPE}" && if ! [[ "${DB}" = "none" ]]; then COMMAND="${COMMAND} DATABASE=${DB}"; fi && if [[ "${GEOIP}" = "yes" ]]; then COMMAND="${COMMAND} USE_GEOIP=1"; fi && if [[ "${PRELUDE}" = "yes" ]]; then COMMAND="${COMMAND} USE_PRELUDE=1"; fi && if [[ "${ZEROMQ}" = "yes" ]]; then COMMAND="${COMMAND} USE_ZEROMQ=1"; fi && if [[ "${openarmor_TYPE}" = "test" ]]; then COMMAND="${COMMAND} USE_PCRE2_JIT=0"; fi && if [[ "${ARCH}" = "arm64" ]]; then ./build.sh; fi && ( cd src/ && make --warn-undefined-variables ${COMMAND} settings && make --warn-undefined-variables ${COMMAND} external -j && make --warn-undefined-variables ${COMMAND} -j ) && if ! [[ "${openarmor_TYPE}" = "test" || "${openarmor_TYPE}" = "winagent" ]]; then ( cd src/ && sudo make --warn-undefined-variables ${COMMAND} install ) fi + if [[ "${openarmor_TYPE}" == "test" ]]; then ( cd src/ && make --warn-undefined-variables test_valgrind ) fi + if [[ "${RULES}" == "test" ]]; then ( cd src/ && sudo make V=1 TARGET=server test-rules ) fi + env: + DB: '${{ matrix.DB }}' + openarmor_TYPE: '${{ matrix.openarmor_TYPE }}' + GEOIP: '${{ matrix.GEOIP }}' + PCRE2_SYSTEM: '${{ matrix.PCRE2_SYSTEM }}' + RULES: '${{ matrix.RULES }}' + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..19dd0c224 --- /dev/null +++ b/.gitignore @@ -0,0 +1,86 @@ +*.so +*.o +*.a +*.dSYM +.DS_Store +*.dll +*.exe + +# Auto generated build files +src/LOCATION +src/external/zlib-1.2.11/configure.log +src/external/zlib-1.2.11/Makefile +src/external/zlib-1.2.11/zconf.h +src/external/zlib-1.2.11/zlib.pc +src/external/zlib-1.2.11/zlib.3.pdf +src/isbigendian.c +src/analysisd/compiled_rules/compiled_rules.h +etc/openarmor.mc +src/Config.OS +src/external/zlib-1.2.8/ztest* + +# Compiled programs +src/agent-auth +src/agent_control +src/clear_stats +src/external/lua-5.2.3/src/openarmor-lua +src/external/lua-5.2.3/src/openarmor-luac +src/isbigendian +src/list_agents +src/manage_agents +src/openarmor-agentd +src/openarmor-agentlessd +src/openarmor-analysisd +src/openarmor-authd +src/openarmor-csyslogd +src/openarmor-dbd +src/openarmor-execd +src/openarmor-logcollector +src/openarmor-logtest +src/openarmor-maild +src/openarmor-makelists +src/openarmor-monitord +src/openarmor-regex +src/openarmor-regex-convert +src/openarmor-remoted +src/openarmor-reportd +src/openarmor-syscheckd +src/rootcheck_control +src/syscheck_control +src/syscheck_update +src/verify-agent-conf + + +# Eclipse files +.cproject +.project +.settings/ + +# temporary vim files +*.swp +*.swo + +# patch files +*.rej +*.orig + +# test and coverage files +*.gcno +*.gcda +src/coverage-report/ +src/openarmor.test +src/test_os_crypto +src/test_os_net +src/test_os_regex +src/test_os_xml +src/test_os_zlib +src/test_shared + +# Windows-specific build output: +src/win32/LICENSE.txt +src/win32/default-local_internal_options.conf +src/win32/default-openarmor.conf +src/win32/help_win.txt +src/win32/internal_options.conf +src/win32/restart-openarmor.cmd +src/win32/route-null.cmd diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..a7cf193e7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,94 @@ +language: c +dist: bionic + +notifications: + irc: + - "chat.freenode.net#openarmor" + slack: + secure: Cz1InEL5G+z2huuzilXe7BqfxlEjN4io5ylJa5jgPvGMlB5sIQZTQQ7PDrzcK0iwn+5xgDkXKwbNPV2k+NHNTtNFiuBrcnJbyeA8PjghtAw4hg/Vpl5+5ovySZT9pGSV7ySsA8nGD73hlcQFgWnYDhsugQ6UZyRXAN8vLLCLjPg= + +env: +- DB=mysql openarmor_TYPE=server GEOIP=yes PCRE2_SYSTEM=no +- DB=mysql openarmor_TYPE=server GEOIP=no PCRE2_SYSTEM=no +- DB=pgsql openarmor_TYPE=server GEOIP=yes PCRE2_SYSTEM=no +- DB=pgsql openarmor_TYPE=server GEOIP=no PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=server GEOIP=yes PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=server GEOIP=no PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=server PRELUDE=yes ZEROMQ=yes PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=server ZLIB_SYSTEM=yes LUA_ENABLE=no PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=local GEOIP=no PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=hybrid GEOIP=no PCRE2_SYSTEM=no +- DB=none openarmor_TYPE=agent GEOIP=no PCRE2_SYSTEM=no +- openarmor_TYPE=test PCRE2_SYSTEM=no +- openarmor_TYPE=server RULES=test PCRE2_SYSTEM=no + + +compiler: +- gcc +- clang + + +arch: +- amd64 +- arm64 + +matrix: + fast_finish: true + exclude: + - arch: arm64 + env: DB=none openarmor_TYPE=winagent GEOIP=no PCRE2_SYSTEM=no + - compiler: clang + env: DB=none openarmor_TYPE=winagent GEOIP=no PCRE2_SYSTEM=no + - compiler: clang + env: openarmor_TYPE=server RULES=test PCRE2_SYSTEM=no + +jobs: + include: + - arch: arm64 + compiler: gcc + env: DB=none openarmor_TYPE=agent GEOIP=no PCRE2_SYSTEM=yes ARCH=arm64 + env: openarmor_TYPE=server RULES=test + +before_script: +- sudo apt-get update -qq +- sudo apt-get install -y libevent-dev libsystemd-dev +- ( wget https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.gz + && tar xzf pcre2-10.32.tar.gz -C src/external ) +- if [[ "${GEOIP}" == "yes" ]]; then ( sudo apt-get install geoip-bin geoip-database libgeoip-dev libgeoip1 ); fi +- if [[ "${PRELUDE}" == "yes" ]]; then ( sudo apt-get install libprelude-dev ); fi +- if [[ "${ZEROMQ}" == "yes" ]]; then ( sudo apt-get install libzmq3-dev libtool autoconf libczmq-dev ); fi +- if [[ "${openarmor_TYPE}" == "winagent" ]]; then ( sudo apt-get install aptitude && sudo aptitude -y install mingw-w64 nsis ); fi +- if [[ "${openarmor_TYPE}" == "server" ]]; then ( sudo apt-get install libsqlite3-dev sqlite3 ); fi +- if [[ "${openarmor_TYPE}" == "test" ]]; then if [ `uname -m` = "aarch64" ]; then (sudo apt-get install check libc6-dbg && wget -q http://ports.ubuntu.com/pool/main/v/valgrind/valgrind_3.15.0-1ubuntu9.1_arm64.deb && sudo dpkg -i valgrind_3.15.0-1ubuntu9.1_arm64.deb ) ; else ( sudo apt-get install check valgrind ); fi; fi + + +script: +- COMMAND="V=1 TARGET=${openarmor_TYPE}" + && if ! [[ "${DB}" = "none" ]]; then COMMAND="${COMMAND} DATABASE=${DB}"; fi + && if [[ "${GEOIP}" = "yes" ]]; then COMMAND="${COMMAND} USE_GEOIP=1"; fi + && if [[ "${PRELUDE}" = "yes" ]]; then COMMAND="${COMMAND} USE_PRELUDE=1"; fi + && if [[ "${ZEROMQ}" = "yes" ]]; then COMMAND="${COMMAND} USE_ZEROMQ=1"; fi + && if [[ "${openarmor_TYPE}" = "test" ]]; then COMMAND="${COMMAND} USE_PCRE2_JIT=0"; fi + && if [[ "${ARCH}" = "arm64" ]]; then ./build.sh; fi + && ( cd src/ + && make --warn-undefined-variables ${COMMAND} settings + && make --warn-undefined-variables ${COMMAND} external -j + && make --warn-undefined-variables ${COMMAND} -j ) + && if ! [[ "${openarmor_TYPE}" = "test" || "${openarmor_TYPE}" = "winagent" ]]; then ( cd src/ && sudo make --warn-undefined-variables ${COMMAND} install ) fi + +- if [[ "${openarmor_TYPE}" == "test" ]]; then ( cd src/ && make --warn-undefined-variables test_valgrind ) fi +- if [[ "${RULES}" == "test" ]]; then ( cd src/ && sudo make V=1 TARGET=server test-rules ) fi + + +deploy: + provider: releases + api_key: + secure: "DiVPTCt1C8XCmFlzcpmFkqfRmxz85/RCE2euvU/c1EiABjfO20aZARCC9zsepAwAGWWsq3uGRLp0aVuJuh4LvTdGxIJDOqYR8z1pByfY4epgE7zmRCIWjx+nAwBpLlfYalMWFpt7vmPp9mKycFkUR2NFoiEfOgoO9wGN0ZgmwSM=" + file: src/win-pkg/openarmor-win32-agent.exe + skip_cleanup: true + on: + tags: true + all_branches: true + repo: openarmor/openarmor-hids + condition: $openarmor_TYPE = winagent + diff --git a/BUGS b/BUGS new file mode 100644 index 000000000..7799af99e --- /dev/null +++ b/BUGS @@ -0,0 +1,20 @@ +openarmor v3.8.0 +Copyright (C) 2019 Trend Micro Inc. + +** Reporting bugs ** + +Please, make sure to include the following information: + +-openarmor version number. +-Content of /etc/openarmor-init.conf +-Content of /var/openarmor/etc/openarmor.conf +-Content of /var/openarmor/logs/openarmor.log +-Operating system name/version (uname -a if Unix) +-Any other relevant information. + +Github (Public Issue Reporting): +https://github.com/openarmor/openarmor-hids/issues + +Email (Private Issue Reporting): +If you prefer to contact us privately or if it is a security +issue, send an e-mail to openarmor Project ( openarmor@theopenarmor.org ). diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..80ccec3a1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,597 @@ +**openarmor changelog (3.8.0) ** + +**Release Maintainers** + +Dan Parriott + +Scott R. Shinn (http://www.atomicorp.com) + +**Contributors on this release** + +**Release Notes** + +**General** + +**openarmor changelog (3.7.0) ** + +**Release Maintainers** + +Dan Parriott + +Scott R. Shinn (http://www.atomicorp.com) + +**Contributors on this release** + +- @atomicturtle +- @ddpbsd +- @ChristianBeer +- @lyellread +- @nfsec +- @tonoitp +- @swindmill +- @g3rhard +- @giannidaprile +- @seren +- @nurse +- @Skactor +- @sempervictus +- @Midi12 +- @icy + +**Release Notes** + +Support for Journald + +**General** + +- @ddpbsd [PR 1840](https://github.com/openarmor/openarmor-hids/pull/1840) Add unbound DNS rules +- @ddpbsd [PR 1941](https://github.com/openarmor/openarmor-hids/pull/1841) Silence build time warning for archive json output. +- @ddpbsd [PR 1842](https://github.com/openarmor/openarmor-hids/pull/1842) maild rework with maxminddb. This retires usage of the EOL GEOIP library. +- @midi12 [PR 1845](https://github.com/openarmor/openarmor-hids/pull/1846) Add active response for Amazon AWS WAF +- @sempervictus [PR 1852](https://github.com/openarmor/openarmor-hids/pull/1852) Add support for journald log format +- @ddpbsd [PR 1865](https://github.com/openarmor/openarmor-hids/pull/1865) Build fix for pcre2 with winagent +- @ddpbsd [PR 1878](https://github.com/openarmor/openarmor-hids/pull/1878) Build fixes for solaris +- @nurse [PR 1887](https://github.com/openarmor/openarmor-hids/pull/1887) Support Ubuntu Bionic arm64 +- @skactor [PR 1899](https://github.com/openarmor/openarmor-hids/pull/1899) Update rootkit detection for reptile rootkits +- @seren [PR 1913](https://github.com/openarmor/openarmor-hids/pull/1913) Fix regexp import in openarmor-batch-manager.pl +- @giannidaprile [PR 1919](https://github.com/openarmor/openarmor-hids/pull/1919) Fix NetBSD builds that don't support JIT regular expressions +- @ddpbsd [PR 1936](https://github.com/openarmor/openarmor-hids/pull/1936) Fix for change in named query log format +- @g3rhard [PR 1938](https://github.com/openarmor/openarmor-hids/pull/1938) fix for apparmor rules +- @swindmill [PR 1940](https://github.com/openarmor/openarmor-hids/pull/1940) closes issue [314](https://github.com/openarmor/openarmor-hids/issues/314) Add checksum to default alert "New file added to the file system" +- @atomicturtle [PR 1951](https://github.com/openarmor/openarmor-hids/pull/1951)closes issue [1949](https://github.com/openarmor/openarmor-hids/issues/1949) invalid link in README +- @atomicturtle [PR 1952](https://github.com/openarmor/openarmor-hids/pull/1952) closes issue [1528](https://github.com/openarmor/openarmor-hids/issues/1528) Rootcheck docker OverlayFS directories problem +- @tonoitp [PR 1967](https://github.com/openarmor/openarmor-hids/pull/1967) update to agentless monitoring ssh_asa-fwsmconfig_diff +- @ddpbsd [PR 1972](https://github.com/openarmor/openarmor-hids/pull/1972) Closes issue [1969](https://github.com/openarmor/openarmor-hids/pull/1972) missing systemd libraries in the INSTALL docs +- @lyellread [PR 1974](https://github.com/openarmor/openarmor-hids/pull/1974)Updating broken documentation links +- @atomicturtle [PR 1979] Closes issues [1970](https://github.com/openarmor/openarmor-hids/issues/1970) debian packaging postinst should not remove openarmor users on upgrade +- @nfsec [PR 2017](https://github.com/openarmor/openarmor-hids/pull/2017) Add rootkit signatures for Jynx and Beurk +- @ChristianBeer [PR 2029](https://github.com/openarmor/openarmor-hids/pull/2029) Add active response script for nftables + +**openarmor changelog (3.6.0) ** + +**Release Maintainers** + +Dan Parriott + +Scott R. Shinn (http://www.atomicorp.com) + +**Contributors on this release** + +@ddpbsd Dan Parriot - Maintainer + +@NicolasCARPi - Nocolas Carpi - Community + +@cpu - Daniel McCarney - Community + +@jknockaert - Jasper Knockaert - Community + +@mwidman - Mike Widman - Community + +@drsjb80 - Steve Beaty - Community + +**General** + +@ddpbsd - openarmor-dbd, Add help output to dbd, https://github.com/openarmor/openarmor-hids/pull/1833 + +@NicolasCARPi - INSTALL, updating depenency list, +https://github.com/openarmor/openarmor-hids/pull/1832 + +@cpu - PCRE2, refuse to compile empty PCRE2 patterns, fix for Issue #1811, https://github.com/openarmor/openarmor-hids/pull/1826 + +@cpu, analysisd, resolves CVE-2020-8442 Issue #1820, https://github.com/openarmor/openarmor-hids/pull/1825 + +@cpu, analysisd, resolves CVE-2020-8443 Issue #1816, https://github.com/openarmor/openarmor-hids/pull/1824 + +@cpu, analysisd, resolves CVE-2020-8448 Issue #1815, https://github.com/openarmor/openarmor-hids/pull/1823 + +@cpu, Makefile, fix for DEBUGAD, https://github.com/openarmor/openarmor-hids/pull/1822 + +@jknockaert - dropbear rules, limit brute force rule to dropbear, https://github.com/openarmor/openarmor-hids/pull/1803 + +@mwidman, analysisd, Added non-standard Sophos UTM syslog timestamp format to pre-decoding. , https://github.com/openarmor/openarmor-hids/pull/1794 + +@drsjb80 - configs, Added authentication log file location for debian-based systems , https://github.com/openarmor/openarmor-hids/pull/1784 + +@ddpbsd - maild, Fix using a program to send mail, https://github.com/openarmor/openarmor-hids/pull/1783 + +**openarmor changelog (3.5.0) ** + +**Release Maintainers** + +Dan Parriott +Scott R. Shinn (http://www.atomicorp.com) + +**Contributors on this release** + +(@atomicturtle) Scott Shinn - Maintainer +(@ddpbsd) Dan Parriot - Maintainer +(@drsjb80) Steve Beaty - Community +(@sempervictus) Boris Lukashev - Community + +**Release notes** + +This would have been a minor 3.4.1 update if it wasnt for Boris Lukashev of https://www.sempervictus.com +contributing a much needed update to multi-line log analysis. Previous usage of multi-line in openarmor in +the past was limited in processing events that did not use indentiation, a fairly common modern practice +for readability. This update adds a new type: multi-line_indented to handle this condition (Example: postgresql). + +Maintenance fixes in this release also address issue #1781, which affected maild when calling an external program, and add support for Fedora 31 + +Whats New: + +(@atomicturtle) - Fedora 31 Support +(@sempervictus) - Implement multi-line collection for indented logs #1780 +(@drsjb80) - Added authentication log file location for debian-based systems #1784 + +General + +(@ddpbsd) - Fix for Issue #1781, corrects issues with program sending mail + +openarmor changelog (3.4.0) + +Release Maintainers + +Dan Parriott +Scott R. Shinn (http://www.atomicorp.com) + +Contributors on this release + +(ddpbsd) Dan Parriot +(bchavet) +(binrush) +(mikeroyal) +(iasdeoupxe) +(aquerubin) +(Varstahl) +(atomicturtle) +(jubois) +(almirb) + +Release notes: +libevent handler https://github.com/openarmor/openarmor-hids/pull/1698 for dialog. +pcre2 rules + +Whats New +Big changes in this release add support for the following new platforms: - Debian buster - Fedora 30 - RHEL 8 - (Much awaited!) Centos 8 + +Snapcraft.io universal linux packaging support (aka Snaps) allow for a universal openarmor package across multiple linux distributions. +Last but not least, ddpbsd has a long awaited fix for agentd/maild when ipv6 is disabled and/or hostnames are used instead of IPs in PR#1698. Thanks again to all our community contributors, and dedicated team members for their work on this release! + +New Rules / Decoders + +(aquerubin) Updated IPv4-dependent regexp in ownCloud decoders. PR#1697 +(jubois) Fix Issue #1708 (Incorrect regex match) PR#1710 +(jubois) PCRE2 rulefiles conversion PR#1711 +(jubois) PCRE2 decoders conversion PR#1712 +(aquerubin) Fix owncloud decoder PR#1724 +(iasdeoupxe) Additional ownCloud decoder fix PR#1725 +(iasdeoupxe) Second ownCloud decoder fix PR#1726 +(ddpbsd) Adjust pix decoder and a firewall rule PR#1749 +(binrush) Fixed missing same_source_ip in rule 11306 PR#1751 pureftpd +(ddpbsd) Addition to sshd rule, new ntpd rule PR#1757, +(ddpbsd) Fix rule IDs PR#1760 - openbsd_rules + +General +(ddpbsd) syscheck, Try to silence the "Attempted to check FS status for" message. PR#1701 +(ddpbsd) syscheck, Add some basic error handling to syscheck_control PR#1702 +(ddpbsd) core, More unlink and fopen error handling in src/util PR#1703 +(almirb) active-response,Added Cloudflare active-response script. PR#1709 +(Varstahl) cyslogd, csyslogd CEF – Remove duplicate parameters and fix discarded hashes PR#1713 +(atomicturtle) - docs, Updating links, using https, conference links PR#1714 +(Varstahl) cyslogd, Fix: csyslogd – CEF escaping / multi-line syslog +(ddpbsd) core, Check return values for unlink(2) calls PR#1733 +(mikeroyal) packaging, snap build support PR#1737 +(ddpbsd) core, Set PCRE2_SYSTEM to no by default. PR#1738 +(ddpbsd) logtest, Remove leading space from field names PR#1741 +(bchavet) analysisd, Verify Googlebot PR#1752 , this is a code function in generic_samples.c +(ddpbsd) analysisd, Free the lf->fields memory. PR#1758, fixes issue #1727 +(ddpbsd) testing, Update some travis-ci bits PR#1759 - travis fixes + +openarmor changelog (3.3.0) + +Release Maintainers + +Dan Parriott +Scott R. Shinn (http://www.atomicorp.com) + +Contributors on this release + +almirb (Almir Bolduan) +aquerubin (Antonio Querubin) +atomicturtle (Scott R. Shinn) +Bob-Andrews (Bob Andrews) +ddpbsd (Dan Parriott) +jubois +MangyCoyote +mephesto1337 + +Release Notes + + openarmorCON 2019, from the whole team here at openarmor it was really fantastic meeting everyone at the show, and we look forward to seeing you all again at openarmorCON 2020! + PCRE2, Jubois made a major update to the IDS foundation in openarmor 3.3.0 with PCRE2 (https://www.pcre.org/current/doc/html/pcre2.html) library. This is an extremely powerful update to the overall pattern analysis functionaility in openarmor. In order to build this with the native distribution pcre2 packages (pcre2-devel, etc), you will need to use: export PCRE2_SYSTEM=yes. This adds several new xml tags: + - pcre2 (to replace regex) + - match_pcre2 + - program_name_pcre2 + - prematch_pcre2 + - srcgeoip_pcre2 + - dstgeoip_pcre2 + - srcport_pcre2 + - dstport_pcre2 + - user_pcre2 + - url_pcre2 + - id_pcre2 + - status_pcre2 + - hostname_pcre2 + - extra_data_pcre2 + + Dynamic Decoders, discussed in the "Beyond Security" talk at openarmorCON 2019, this allows for user-defined keys in decoders. These are exposed in JSON output for inclusion with other data analytics tools. This adds a new internal option: analysisd.decoder_order_size to define the maximum number keys allowed in a single decoder. + +Whats New +(jubois) - PCRE2 regular expression support - PR#1652 +(atomicturtle) - openarmor-analysisd, Dynamic decoder support. Original: Vikman Fdez-Castro - PR#1678 +(ddpbsd) - openarmor-execd, Switch "white lists" to "allow lists" - PR#1687 - NARRATE HERE + +New Rules / Decoders +(Bob-Andrews) - rootcheck, update for NullSessionShares - PR#1669 +(Bob-Andrews) - topleveldomainrules.xml, Shady TLD web traffic detection - PR#1671 +(Bob-Andrews) - last_rootlogin_rules.xml, Sensitive login detection - PR#1671 +(Bob-Andrews) - unbound_rules.xml, added rule for maybe critical TLD request - PR#1672 +(Bob-Andrews) - rootcheck, Deleted repeating rules - PR#1674 +(ddpbsd) - Update info links in Windows rules - PR#1675 +(aquerubin) - Added decoder for pam_succeed_if - PR#1684 + +General +(MangyCoyote) - openarmor-analysisd, support Syslog ISO timestamp events with optional fraction of second - PR#1664 +(ddpbsd) - Fix compilation with PCRE2_SYSTEM=yes - PR#1666 +(aquerubin) - openarmor-batch-manager.pl, update regexp for ipv6 addresses - PR#1667 +(mephesto1337) - Fix part of issue#1663, compiling with PCRE2_SYSTEM=yes - PR#1677 +(ddpbsd) - active-response, Fix for issue#1647, log disable-account.sh to the correct location - PR#1683 +(aquerubin) - Copy resolv.conf on build event - PR#1685 +(almirb) - active-response, Corrected the way active-response logs are generated on windows - PR#1689 +(atomicturtle) - openarmor-execd, Expose filename variable in AR add/delete events - PR#1695 + +openarmor changelog (3.2.0) + +Release Maintainers + +Dan Parriott +Scott R. Shinn (Atomicorp, Inc.) + +Contributors on this release + +atomicturtle +Bob-Andrews +ddpbsd +knqyf263 +jubois +mig5 +mwmahlberg +nhatking16591 +pillarsdotnet + +Release Notes +The great JSON-in-ing has begun! New features in this release focus on extending JSON output support to control commands like agent_control, syscheck_control, and rootcheck_control. Additional extensions add support for archives.log in native json format, and improving the alert.json output. This release also also brings some much needed enhancements to openarmor-authd to streamline the agent registration experience (thanks nhatking16591!), Bob-Andrews continues on major auditing improvements plus support for Solaris 11. + + We'd like to thank all the great contributors (named and anonymous!) who continue to improve openarmor and support our community. We'd also like to welcome all our new contributors to openarmor on this release. They have helped us on bug testing, documentation, new features, rules, compliance checks, code and more. There are no small contributions to a project like openarmor, and we continue to thrive with your support. Special thanks to security researchers A.P. and S.S. for their audit of the openarmor project, your work has greatly benefited the community. + + If you're interested in joining our team, or just interacting with us on slack email us at: invite@theopenarmor.org + +Whats New + + (atomicturtle) - add openarmor-configure to contrib - PR#1559 + (atomicturtle) - add audit for native audit.log support - PR#1589 + (nhatking16591) - authd, Allow reuse ID and improve search algorithm finding available ID key. Fixes issue#1587, PR#1594 + (ddpbsd) - syscheck, add option to keep FIM from going down directories. Addresses Issue#1595 - PR#1597 + (atomicturtle) - archives.json, JSON support for archives.log with yes - PR#1596, PR#1601, PR#1608 + (atomicturtle) - agent_control, -j for JSON output - PR#1625 + (atomicturtle) - syscheck/rootchec_control, add -j for JSON output - PR#1626 + (atomicturtle) - manage_agents, add -j for JSON output, -a to add new agent, -a -n add new agent with declared name - PR#1627 + (atomicturtle) - internal_options.conf, remoted.pass_empty_keyfile will toggle if remoted exits on an empty client.keys file - PR#1628 + (atomicturtle) - manage_agents, add -d modifier to -a (add) to remove an agent pinned to an already declared IP - PR#1632 + (atomicturtle) - manage_agents, add -F modifier to -a (add), this will delete an agent with the same IP if it has not been seen in -F - PR#1639 + (atomicturtle) - manage_agents, add -m flag to show the max agent limit - PR#1650 + +New Rules / Decoders +(Bob-Andrews) - rootcheck, add Solaris11 CIS checks - PR#1557 +(Bob-Andrews) - rootcheck, add password requirement checks - PR#1558, PR#1562 +(Bob-Andrews) - Kasperskey Endpoint Security rules/decoders - PR#1573 +(Bob-Andrews) - Cowrie / Dionaea Modern Honeypot Network rules/decoders - PR#1574 +(Bob-Andrews) - Dionaea/Cowrie decoder, Changed IPv4 to IPv4/IPv6 - PR#1578 +(Bob-Andrews) - Windows Powershell rules: ms_powershell_rules.xml, add powershell rules - PR#1579 +(jubois) - proftpd decoder: decoder simplification - PR#1657 +(ddpbsd) - nsd rules: nsd_rules.xml, detect zone transfer attempts - PR#1598 +(Bob-Andrews) - Windows Powershell rules: ms_powershell_rules.xml, dangerous commands/background activity - PR#1646 + +General +(mig5) - firewall-drop.sh, modify to support non-bash environments - PR#1572 +(mwmahlberg) - openarmor-agent.conf, remove double hyphen in comment. Fixes issue#1582 - PR#1583 +(ddpbsd) - openarmor-maild, allow permission changes to make it into email alerts. Fixes issue#1571 - PR#1593 +(ddpbsd) - installation, addresses issue#1570, allow installation as unpriv user - PR#1599 +(atomicturtle) - JSON output, basic json functions for agent_control - PR#1600, PR#1602 +(ddpbsd) - openarmor-authd, use IPExist to check for duplicate IP addresses - PR#1603 +(ddpbsd) - general, default to not setting the compiler optimization level - PR#1604 +(ddpbsd) - general, default to showing verbose compiler output - PR#1605 +(atomicturtle) - agent_control, JSON output prep work - PR#1606 +(atomicturtle) - JSON output, adding functions for rootcheck compliance output in JSON - PR#1607 +(atomicturtle) - JSON output, minor optimization - PR#1609 +(atomicturtle) - agent_control, minor fixes for JSON output - PR#1610 +(ddpbsd) - zlib, shifting dependencies to the system zlib - PR#1612 +(ddpbsd) - LUA, disable lua by default, shifting dependencies to the system lua - PR#1613 +(ddpbsd) - security review, coverity fixes - PR#1616 +(atomicturtle) - JSON output, minor update for JSON log dirs/files - PR#1617 +(atomicturtle) - JSON output, fix lf location array from unknown syslog - PR#1618 +(atomicturtle) - manage_agents, bugfix when generating keys from a file - PR#1619 +(atomicturtle) - openarmor-analysisd, increase default memory size from 1024 to 8192 (dcid) - PR#1620 +(ddpbsd) - security review, coverity fixes - PR#1621 +(atomicturtle) - JSON output, adding more groups, and clean up formatting - PR#1622 +(ddpbsd) - security review, coverity fixes for PR#1624 - PR#1629 +(ddpbsd) - manage_agents, add an error path for being unable to chmod authfile - PR#1629 +(pillarsdotnet) - active-response, directory traversal fix - PR#1630 +(ddpbsd) - openarmor-control, remove author tag from output - PR#1633 +(atomicturtle) - agent management cleanup, rootcheck/syscheck data is removed on a delete event - PR#1634 +(ddpbsd) - json output, add prototype for function/ fixing compile warnings - PR#1636 +(ddpbsd) - json output, cleanup for unused variables - PR#1637 +(ddpbsd) - openarmor-maild, remove legacy sms output type - PR#1638 +(ddpbsd) - agent_control, usage output update - PR#1640 +(jubois) - dotests.sh, Improved dotests.sh output - PR#1641 +(jubois) - Correct tests in contrib/logtesting - PR#1645 +(atomicturtle) - openarmor-analysisd, fix for analysisd segfault in overwrite rule condition - PR#1649 +(atomicturtle) - openarmor-csyslogd, fix for size returned from a tcp syslog event - PR#1653 +(jubois) - fix compilation warnings - PR#1654 +(knqyf263) - openarmor-maild, fix for email being sent infinitely - PR#1658 + +openarmor changelog (3.1.0) + +Release Maintainers + +Dan Parriott +Scott R. Shinn (Atomicorp, Inc.) + +Release Notes + + Special thanks on this release go out to: + davestoddard for an amazingly well thought out, and well documented update to the networking code + Bob-Andrews for the largest update to the auditing system in the project history + phamvoung for resolving some very subtle bugs and high profile issues with the authd daemon + + We'd also like to thank all the other fantastic contributors to the project, whom are referenced in parenthesis in the changelog. We cannot thank you enough! + +Whats New +(davestoddard) Modification to Correct IP Connectivity Issues on BSD Servers PR #1412 + +New Rules / Decoders +(Bob-Andrews) - linux_usbdetect_rules.xml, ms1016_usbdetect_rules.xml, ms_firewall_rules.xml +(Bob-Andrews) - Added ms_ipsec_rules PR #1549 +(Bob-Andrews) - Rootchecks for Debian 7+8, cis_debianlinux7-8_L1_rcl.txt, cis_debianlinux7-8_L2_rcl.txt, cis_win10_enterprise_L1_rcl.txt, cis_win10_enterprise_L2_rcl.txt PR #1531 +(Bob-Andrews) - acsc_office2016_rcl.txt, Added rootcheck PR #1510 +(Bob-Andrews) - added cis_win2016_memberL1_rcl.txt, cis_win2016_memberL2_rcl.txt PR #1496 +(Bob-Andrews) - cis_win2012r2_memberL1_rcl.txt, Added Check Description/Alert PR #1495 +(ddpbsd) - additional sshd decoders PR #1480 +(ddpbsd) - basic support for Dnsmasq PR #1461 + +General +(iasdeoupxe) - host-deny.sh: Move duplicate entry check into the add action PR #1554 +(iasdeoupxe) - host-deny.sh: Use consistent indentation PR #1553 +(iasdeoupxe) - host-deny.sh: Remove unnecessary echo for duplicated entry PR #1552 +(Bob-Andrews) - Added new id ranges for linux usb detection rules, ms1016 usb detection rules and ms firewall rules from PR #1543 +(Bob-Andrews) - Corrected IDs to a non user defined range PR #1547 (psad_rules.xml, sysmon_rules.xml, unbound_rules.xml) +(c0r3dump3d) - Correct and expand spanish translation PR #1541 +(ddpbsd) - Adjust the tests for sysmon rules PR #1548 +(MangyCoyote) - install.sh - case for s-nail patch can't be applied if `mail` is not installed PR #1539 +(atomicturtle) - openarmor-authd Fix for foreground flags PR #1538 +(atomicturtle) - openarmor-authd Add -f foreground flag support PR #1537 +(featzor) - psad signature match level 6 PR #1517 +(Bob-Andrews) - Corrected rootcheck CIS tests for cis_win2012r2_domainL2_rcl.txt, is_win2012r2_memberL2_rcl.txt, cis_win2016_domainL2_rcl.txt PR #1521 +(franciosi) - Updated README.md, correts small typos PR #1519 +(ddpbsd) - Fix the subject handling. Issue submitted by Michael Starks #1370 PR #1377 +(foygl) - openarmor-slack.sh, Fix and clean up output for Slack integration PR #1508 +(ddpbsd) - From issue #1514, a duplicate `_gsid1 == 0` -> `_gsid0 == 0` PR #1515 +(Bob-Andrews) - cis_win2016_domainL1_rcl.txt, Corrected Check - Registry Hive PR #1511 +(ashley-dunn) - Fix "bellow" typos in openarmor-[client|local|server].sh files PR #1512 +(ddpbsd) - Fix the log location in the openarmor-slack AR script. PR #1422 +(phamvuong) - BUGFIX: remove default value for authpass PR #1464 +(calve) - Bump version definition in defs.h PR #1504 +(ddpbsd) - More coverity fixes PR #1497 +(ddpbsd) - Modify status() to not return 1 when maild is not running PR #1501 +(ddpbsd) - Coverity fixes PR #1490 +(Bob-Andrews) - Moved file to openarmor-hids/ src/rootcheck/db/ PR #1493 +(ddpbsd) - Make sure there's room for the full alert id in json alerts PR #1487 +(ddpbsd) - Fix an issue in the nodiff option which could ignore files it isn't supposed to PR #1486 +(ddpbsd) - Hard coded user/group changed to appropriate variables PR #1484 +(ddpbsd) - Add FreeBSD's php.ini location to rootcheck db PR #1483 +(ddpbsd) - Replace hard coded directories with the appropriate variables PR #1482 +(ddpbsd) - When trying to bind to a local address, present the error on failure. PR #1457 +(ddpbsd) - version_bump.sh Quick script to make version bumping easier PR #1532 +(phamvuong) - Call select() before checking active socket PR #1529 +(stephengroat) - use nicer looking travis build badge PR #1460 +(stevhsu) - Correct lua version variable PR #1459 + +openarmor changelog (3.0.0) + +Release Maintainers + +Dan Parriott +Scott R. Shinn (Atomicorp, Inc.) + +Whats New +SQLite support for syscheck +PR #1091 - whitelist for files in sqlite DB +PR #1364 - add some ifdefs for the md5 whitelist database (USE_SQLITE) + + Update cJSON 1.7.0 + PR #1351 + + Add Pagerduty Active response + PR #1302 + + openarmor-authd + + PR #890 / #873 - Dichotomic search to add agents with authd + PR #1154 / #1210 - password support + PR #1161 - avoid IP duplication, time limit agent deletion with duplicate IP, and option for re-using an agent ID + PR #1190 - Exit handler for authd to delete PID file + PR #1208 - add cipher configuration support + + zlib update to 1.2.11 + PR #1198 + + openarmor-agent selinux module + PR #1193 + + windows agent + PR #1170 - add agent-auth.exe support + + add tcp support for agent communications + PR #1162 + + GeoIP support in rules and events + PR #840 - Support in alerts + PR #927 - add geoip support to JSON output analysisd.geoip_jsonout=0 + PR #929 - Modify rule token different_geoip rule to different_srcgeoip + PR #984 - fix some geoIP bugs + PR #1108 - decoder fixes + + Slack support + Bugfix #947 - Escape the '.' in the grep for '.ALERTLAST' #947 + Bugfix #959 - silent curl in openarmor-slack + + Decoders filename attribute + PR #915 - A few fixes, but most importantly the ability to set the filename attribute from a decoder. This will help create automated pipelines for FIM Verification. I currently need to compare FIM events against 1) Puppet, 2) GIT, and 3) RPM. This patch allows FIM events to be intercepted by my custom FIM Verification script, which generates logging events which openarmor can read and turn back into an event with the filename attribute set. + +New Rules / Decoders + +PR #1297 / #1335 - update named rules +PR #1324 - Bitcoin wallet scans to suspicious URLs +PR #1356 - Openbsd DHCP rules + +General + +Bugfix #42 - Add option to use unaltered hashes with Windows syscheck +Bugfix #210 - Time option in rules is rejecting valid syntax. +Bugfix #425 - manage_agents unable to access /dev/random due to chroot +Bugfix #454 - Prevent manage_agents from chrooting in bulk mode +Bugfix #780 - Compile warning (and potential segfault) after merge from calve/do_not_show_diff +Bugfix #829 - Segmentation fault at logcollector +Bugfix #888 - Pull Request #840 reverts some ipv6 support +Bugfix #869 - openarmor-agentd is unable to unmerge files +Bugfix #892 - Contrib tools need to be updated for IPv6. +Bugfix #911 - "any" is broken after change to sacmp for ipv4 networks #911 +Bugfix #913 - logcollector goes into loop when a NULL is in the log +Bugfix #960 - do not attempt to start openarmor-maild when it is enabled +Bugfix #961 - fix for open file handle when rotating alerts.json +Bugfix #976 - win32: 2 values in internal_options.conf ignored +Bugfix #994 - rootcheck, fix for false positive trojaned /bin/grep +Bugfix #998 - IPv6 triggers Rule 1002 +Bugfix #1065 - fix for negating IP/CIDR rules +Bugfix #1084 - fix a double free +Bugfix #1106 - openarmor-remoted, Fix for clang checks, and a potential DOS caused by a warning +Bugfix #1142 - CEF field uniqueness fix +Bugfix #1145 - if getaddrinfo fails with WAI_FAMILY try ipv4 +Bugfix #1165 - rpm spec files generate openarmor user and group in user space +Bugfix #1180 - Add last events (previous output) to JSON output +Bugfix #1205 - Avoid EOL conversion of received files in the windows receiver +Bugfix #1227 - Fix for daily reports not being sent +Bugfix #1237 - Custom CFLAGS/CXXFLAGS/LDFLAGS support +Bugfix #1274 - openarmor-authd, ipv6 returns an invalid key +Bugfix #1278 - Use getent to check for users/group +Bugfix #1366 - Update to rule ID map +Bugfix #1370 - Bugfix for full subject handling + +PR #770 - openarmor-dbd, postgresql fixes on the user colume, schema, and not null conditions +PR #778 - syscheck, Selective opening mode to extract file hash #778 +PR #792 - Check for a null from malloc +PR #802 - openarmor-dbd, allow for longer entries in the system.information column +PR #804 - openarmor-dbd, allow for mysql/postgres format changing based on MYSQLDB/POSTGDB +PR #806 - openarmor-reportd, report fixes on IP and user fields +PR #808 - Igngore openBSD's random seed +PR #824 - openarmor-dbd, fix for mysql/postgres insert condition +PR #839 - JSON output, Add group field to json output +PR #843 - Add support for CZMQ v3 +PR #848 - Fixed bug at logcollector that inhibited alerts about file reduction +PR #849 - openarmor-maild, Format string security fix +PR #855 - Fixed memory error on CDB lists management +PR #859 - added utils to rename an agent or change its IP address (rename_agent.sh, renumber_agent.sh) +PR #862 - openarmor-analysisd, fixed memory leaks +PR #864 - There is an error when running openarmor-logtest to test rules with check_diff, since it doesn't change root directory and tries to create a directory at/queue/diff`. +PR #866 - JSON output, Add timestamp for events +PR #881 - Add debugging output to active repsonse xml config read +PR #883 - Bugfix for agents failing to bind to a specific local IP address and the server is specified by hostname. +PR #887 - agent status needs to be verified before using agt->lip +PR #893 - Prelude IDS support, Do not use absolute indexes in prelude fields +PR #899 - manage_agents, openarmor agent IDs can only be numbers but they are treated as strings. Because of this, it's possible to add the agent "00" and "000", or "1" and "00001" at the same time, and they can be confused on extracting keys or on deleting agents. +PR #909 - openarmor-logtest, Bugfix for decoders.d/rules.d segfault +PR #910 - Update intcheck_op.c +PR #912 - update validate_op.c +PR #918 - openarmor-logtest, add -q "quiet" flag support +PR #920 - Bugfixes for OS_IPFound, OS_IPFoundList, OS_IsValidIP. #920 +PR #921 - JSON output, This removes the double addition of the 'action' field and adds a few other interesting fields that I need for my analysis in ELK. Most notably, the rule.group is now passed out via the zmq output. +PR #923 - openarmor-dbd, fix SQLi in al_data->location +PR #928 - openarmor-logtest, add geoip to logtest output +PR #930 - fix memory leak in decode-xml.c +PR #931 - Custom output, fix common realloc mistake in custom_output_search_replace. +PR #934 - Create openarmor users and group as system members +PR #944 - Don't pass null variables to snprintf. +PR #950 - Exclude btrfs-Filesystem from searching for hidden files inside directorie +PR #953 - Prevent manage_agents from doing invalid actions on interactive mode +PR #964 - Csyslogd patch for sending additional FIM event information +PR #991 - set default AR level to 7 +PR #1003 - JSON output, bugfix for duplicated group field +PR #1004 - memory fixes in XML decoding, no-terminated strings, and searchAndReplace() +PR #1016 - bugfix that prevents openarmor-control from starting openarmor-maild on server +PR #1017 - openarmor-remoted, fix for openbsd canary violation +PR #1020 - Allow notify_timeout to be configured server-side. #1020 +PR #1021 - Windows Agent, fix for build related issues +PR #1027 -Fx for the "USER_AGENT_CONFIG_PROFILE" preloaded-vars.conf file usage. This fixes that and adds a profile config line if the variable is defined. Very useful for unattended installs or binary installs. +PR #1089 - Retire picviz support +PR #1090 - JSON output, add "id" to the json log +PR #1093 - pf.sh, update support FreeBSD, OpenBSD, and Darwein +PR #1097 - openarmor-batch-manager.pl, support "any" IP address +PR #1099 - AR, prevent duplication in hosts.deny +PR #1100 - Windows agent, Open received files in binary mode cause of cr/lf and let hashes match. +PR #1102 - JSON output, Fix timestamp +PR #1116 - openarmor-remoted, systemd support +PR #1135 - openarmor-dbd, UMYSQL_DATABASE_ENABLED does not exist in the tree except this one place. +PR #1137 - Windows agent, administrators group might not be present on non-english installs +PR #1148 - Update for gmake to compile on Solaris 11.2 +PR #1149 - Update adduser.sh for Solaris 11.2 +PR #1158 - Update shell on openarmor-hids-solaris.init Solaris 11.2 +PR #1159 - Update Makefile for Solaris +PR #1179 - openarmor-dbd, fix readme display IP as string +PR #1235 - spelling fixes +PR #1238 - fix for edead oop in hash_op.c +PR #1255 - syscheck, update windows syscheck directories +PR #1256 - openarmor-dbd, use port for postgresql connections +PR #1257 - rootcheck, make sleep interval configurable (rootcheck.sleep) +PR #1258 - adduser.sh, fix the useradd and groupadd script for openbsd +PR #1262 - agentless ssh.exp, remove the P's entirely to support upper and lower case +PR #1304 - syscheck, Don't display the errno, show the error message +PR #1307 - Allow alerts.log to be turned off (DOUBLE CHECK, THIS WAS REVERTED) +PR #1322 - rootcheck, mysql/mariadb auditing checks +PR #1336 - Disable warning on OS_PassEmptyKeyfile +PR #1342 - remove execute flag on rules and config files +PR #1343 - Makefile fix ar warning +PR #1344 - add option to exclude lua and use system zlib +PR #1345 - gitignore, Ignore zlib paths +PR #1347 - Fix compiler warnings: Wall, Wextra +PR #1374 - Bugfix for AIX building +PR #1382 - added rootcheck file for apache 2.2/2.4 diff --git a/CONFIG b/CONFIG new file mode 100644 index 000000000..fd3ec04fc --- /dev/null +++ b/CONFIG @@ -0,0 +1,19 @@ +openarmor v3.8.0 +Copyright (C) 2019 Trend Micro Inc. + + += Information about openarmor = + +Visit http://openarmor.github.io + + += Recommended Installation = + +See INSTALL + + +== Configuring openarmor == + +Just follow the steps from the install.sh script. +More information at +https://openarmor.github.io/docs/manual/index.html diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 000000000..563229559 --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,140 @@ +openarmor v3.2.0 +Copyright (C) 2019 Trend Micro Inc. + +Many thanks to everyone who contributed and helped with +the openarmor project. Below is the list of all the people +who helped us since our first release (0.1). +(if you feel you should be here, but it is not, let scott@atomicorp.com know). + +-Development + - Daniel B. Cid + - Dan Parriott + - Jeremy Rossi + - Michael Starks + - Meir Michanie + - Slava Semushin + - Ahmet Ozturk + - Scott R. Shinn + - Dominic + - JB Cheng + - Cristobel + - jp.zurbrugg + - Bil Hays + - Andrew Widdersheim + - Wouter Clarie + - Mario Weigel + - Christian Beer + - Gael Muller + - Ky-Anh Huynh + - Dan Garthwaite + - Lance A. Brown + - danpop60 + - Martin DiViaio + - Michael Boyd + - ibatten + - rhelfter + - Peter Drake + - Mikey Austin + - Harshil Mathur + - Ryan Schulze + - navtej + - Hakisho Nukama + - Danny Fullerton + - Justin Gerace + - jknockaert + - Jason Stelzer + - Antonio Querubin + - Santiago Bassett + +-Testing/Patches Rules and other contributions. + - Cédric Bleimling + - Sebastien Tricaud + - Jeff Schroeder + - Giannis Vrentzos + - Peter Ahlert + - Rafael Capovilla + - Andre Alexandre Gaio + - Liliane A. Cid + - Marcus Maciel + - Stephen Kreusch + - Kayvan A. Sylvan + - Dianzhi Wang + - Meir Michanie + - Stephen Bunn + - Jonathan Scheidell + - |SaMaN| + - ChuckD + - Jorge Augusto Senger - openarmor2mysql (contrib) + - David J. Bianco + - Ivan Lotina + - Robert Millan [ackstorm] + - Martin West + - Rafael Capovilla + - Florian Crouzqat + - Danny Fullerton + - Jeremy Hanmer + - Pepe Sanz + - Kat Fitzgerald + - Regis Houssin + - carlopmart + - Ash Kumar + - Alexandro Silva + - Mike Downey + - Hai Nguyen + - Jeffrey Jackson + - Ben Chavet + - Bill Parker + - Schnaffon + - Ralf Spenneberg + - Darren Worrall + - aalberdi + + +-Translations + + -Dutch: + - Martijn de Boer + + -Serbian: + - Maja Michanie + + -Portuguese: + - Daniel Barcellos + - Allan Soares + - Willian Itiho Amano + - Liliane Cid + + -German: + - Peter Ahlert + + -Turkish + - Ahmet Ozturk + + -Polish + - Dziankowski Krzysztof + + -Italian + - Alberto Furia + + -French + - Yves Bigliazzi + + -Japanese + - Kuzuno Hiroki + + -Russian + - Yuri Slobodyanyuk + + -Spanish + - Meir Michanie + + -Chinese + - Brian Wang diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d177cdb46 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM ubuntu:18.04 + +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update \ + && apt-get --yes install \ + sudo \ + curl \ + wget \ + git \ + build-essential \ + debhelper \ + libssl-dev \ + linux-libc-dev \ + libpcre2-dev \ + pbuilder \ + expect \ + debconf \ + qemu-user-static +COPY ./debian_files /home/ubuntu/debian_files +COPY . /home/ubuntu/openarmor-hids +# `docker build` cannot handle `pbuilder create` because it uses `mount` which needs privilege +# RUN /home/ubuntu/openarmor-hids/contrib/debian-packages/generate_openarmor.sh -d +# RUN /home/ubuntu/openarmor-hids/contrib/debian-packages/generate_openarmor.sh -u +# RUN /home/ubuntu/openarmor-hids/contrib/debian-packages/generate_openarmor.sh -b + +CMD ["/bin/sh"] diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..a3591bfcb --- /dev/null +++ b/INSTALL @@ -0,0 +1,78 @@ +openarmor v3.8.0 +Copyright (C) 2019 Trend Micro Inc. + + += Information about openarmor = + +Visit https://www.theopenarmor.org + + += Recommended Installation = + +openarmor installation is very simple. It can be done in the +fast way (using the script install.sh with the default values) +or in the customized way (by hand or by changing the default values +in the install.sh script). I REALLY recommend EVERYONE to use the +FAST WAY! Only developers or experienced people should use the +other methods. + +Before running the script, make sure your system has the necessary +libraries and tools installed: +- libssl +- libpcre2 +- libz +- make, gcc +- libsystemd-dev + +On a Ubuntu/Debian system, these can be installed with: + +apt install libz-dev libssl-dev libpcre2-dev build-essential libsystemd-dev + +Fast way steps: + +1- Run the script ./install.sh. It will guide you through the + installation process. + +2- The script will create everything in /var/openarmor and try to + create the initialization script in your system (/etc/rc.local + or /etc/rc.d/init.d/openarmor). If the init script is not created, + make sure to follow the instructions from the install.sh to make + openarmor HIDS start during the boot. To start it by hand, just run + /var/openarmor/bin/openarmor-control start + +3- If you are running it on multiple clients, make sure to install + the server first. Use the manage_agents tool + to create the right encryption keys. + +4- Enjoy. + + += Installation and Running (99.99% should read ABOVE) = + + +By Hand Installation steps: + +1- Create the necessary directories (by default /var/openarmor). +2- Move the necessary files to the openarmor directory. +3- Compile everything. +4- Move the binaries to the default directory. +5- Create the necessary users. +6- Set the right permissions to the files. + + +This 5 steps are done in the Makefile (see make server). + +The Makefile read the options from the LOCATION file. Change +whatever you need from there. + +To compile everything by yourself: + + % make clean + % make all (step 3) + % su + # make server (will do steps 1,2,4 and 6 above) + +*Before running make server, make sure to have the necessary users created. +The Makefile will not do that. + +#EOF diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..67c97aba6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,474 @@ + + Copyright (C) 2003 - 2013 Trend Micro Inc. All rights reserved. + + openarmor HIDS is a free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License (version 2) as + published by the FSF - Free Software Foundation. + + In addition, certain source files in this program permit linking with the + OpenSSL library (http://www.openssl.org), which otherwise wouldn't be allowed + under the GPL. For purposes of identifying OpenSSL, most source files giving + this permission limit it to versions of OpenSSL having a license identical to + that listed in this file (see section "OpenSSL LICENSE" below). It is not + necessary for the copyright years to match between this file and the OpenSSL + version in question. However, note that because this file is an extension of + the license statements of these source files, this file may not be changed + except with permission from all copyright holders of source files in this + program which reference this file. + + Note that this license applies to the source code, as well as + decoders, rules and any other data file included with openarmor (unless + otherwise specified). + + For the purpose of this license, we consider an application to constitute a + "derivative work" or a work based on this program if it does any of the + following (list not exclusive): + + * Integrates source code/data files from openarmor. + * Includes openarmor copyrighted material. + * Includes/integrates openarmor into a proprietary executable installer. + * Links to a library or executes a program that does any of the above. + + This list is not exclusive, but just a clarification of our interpretation + of derived works. These restrictions only apply if you actually redistribute + openarmor (or parts of it). + + We don't consider these to be added restrictions on top of the GPL, + but just a clarification of how we interpret "derived works" as it + applies to openarmor. This is similar to the way Linus Torvalds has + announced his interpretation of how "derived works" applies to Linux kernel + modules. Our interpretation refers only to openarmor - we don't speak + for any other GPL products. + + * As a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + + openarmor HIDS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License Version 2 below for more details. + +----------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + +------------------------------------------------------------------------------- + +OpenSSL License +--------------- + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the routines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ diff --git a/README.md b/README.md new file mode 100644 index 000000000..1d54bf895 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +openarmor v3.8.0 Copyright (C) 2019 Trend Micro Inc. + +# Information about openarmor + +openarmor is a full platform to monitor and control your systems. It mixes together +all the aspects of HIDS (host-based intrusion detection), log monitoring and +SIM/SIEM together in a simple, powerful and open source solution. + +Visit our website for the latest information. [www.theopenarmor.org](https://www.theopenarmor.org) + +## Current Releases + +The current stable releases are available on the openarmor website. + +- Releases can be downloaded from: [Downloads](https://www.theopenarmor.org/downloads/) +- Release documentation is available at: [docs](https://www.theopenarmor.org/docs/) + +## Development + +The development version is hosted on GitHub and just a simple git clone away. + +[![Build Status](https://travis-ci.org/openarmor/openarmor-hids.svg?branch=master)](https://travis-ci.org/openarmor/openarmor-hids) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/1847/badge.svg)](https://scan.coverity.com/projects/1847) + +## Screenshots + +_File Integrity Monitoring_ + +![FIM](./doc/images/fim-test.gif) + +_Attack Detection_ + +![SSH Brute Force](./doc/images/ssh-attack.gif) + +## Help / Support + +Join us on slack, openarmor.slack.com: Invites to slack@theopenarmor.org + +Join us on Discord: https://discord.gg/BXzM75Xzq7 + +## Credits and Thanks + +- openarmor comes with a modified version of zlib and a small part + of openssl (sha1 and blowfish libraries) +- This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/) +- This product includes cryptographic software written by Eric + Young (eay@cryptsoft.com) +- This product include software developed by the zlib project + (Jean-loup Gailly and Mark Adler) +- This product include software developed by the cJSON project + (Dave Gamble) +- [Atomicorp](https://www.atomicorp.com) hosting the annual openarmor conference. Presentations for the 2019 conference can be found at https://www.atomicorp.com/openarmor-con2019/ diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..2df94f67a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 4.7.x | :white_check_mark: | +| 3.7.x | :white_check_mark: | +| < 3.7.0 | :x: | + +## Reporting a Vulnerability + +Please visit the URL for openarmor security contact: + +https://www.theopenarmor.org/.well-known/security.txt diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 000000000..98756e4b9 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1 @@ +Before you submit an issue, please review the project's [Support Options](https://openarmor.github.io/about.html#support-options). diff --git a/active-response/cloudflare-ban.sh b/active-response/cloudflare-ban.sh new file mode 100644 index 000000000..2bd5b2698 --- /dev/null +++ b/active-response/cloudflare-ban.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# Adds an IP to Cloudflare IP block list +# Path: /var/openarmor/active-response/bin/cloudflare-ban.sh +# Authors: Bryan Dwyer (bdtech) and Almir Bolduan (almirb) +# Last modified: May 08, 2019 +# +# Sample config (Edit /var/openarmor/etc/openarmor.conf): +# +# +# cloudflare-ban +# cloudflare-ban.sh +# yes +# srcip +# +# +# +# cloudflare-ban +# server +# 31151,31152,31153,31154,31163 +# 43200 +# + +ACTION=$1 +USER=$2 +IP=$3 +PWD=`pwd` +TOKEN='Cloudflare API Token' +USER='cloudflareuser@email.com' +MODE='block' # block or challenge + +# Logging the call +echo "`date` $0 $1 $2 $3 $4 $5" >> /var/openarmor/logs/active-responses.log + +# IP Address must be provided +if [ "x${IP}" = "x" ]; then + echo "$0: Missing argument (ip)" + exit 1; +fi + +# Adding the ip to null route +if [ "x${ACTION}" = "xadd" ]; then + curl -sSX POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \ + -H "X-Auth-Email: $USER" \ + -H "X-Auth-Key: $TOKEN" \ + -H "Content-Type: application/json" \ + --data "{\"mode\":\"$MODE\",\"configuration\":{\"target\":\"ip\",\"value\":\"$IP\"},\"notes\":\"Added via openarmor Command\"}" + exit 0; + + +# Deleting from null route +# be carefull not to remove your default route +elif [ "x${ACTION}" = "xdelete" ]; then + + # get the rule ID + JSON=$(curl -sSX GET "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=$MODE&configuration_target=ip&configuration_value=$IP" \ + -H "X-Auth-Email: $USER" \ + -H "X-Auth-Key: $TOKEN" \ + -H "Content-Type: application/json") + + ID=$(echo $JSON | jq -r '.result[].id') + + curl -sSX DELETE "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$ID" \ + -H "X-Auth-Email: $USER" \ + -H "X-Auth-Key: $TOKEN" \ + -H "Content-Type: application/json" + exit 0; + +# Invalid action +else + echo "$0: invalid action: ${ACTION}" +fi + +exit 1; diff --git a/active-response/disable-account.sh b/active-response/disable-account.sh new file mode 100644 index 000000000..70dd204b9 --- /dev/null +++ b/active-response/disable-account.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# Disable an account by setting "passwd -l" or chuser +# Requirements: System with a passwd that supports -l and -u +# or a system with chuser (AIX) +# Expect: username (can't be "root") +# Authors: Ahmet Ozturk and Daniel B. Cid +# Last modified: Jan 19, 2005 + + +UNAME=`uname` +PASSWD="/usr/bin/passwd" +CHUSER="/usr/bin/chuser" +ACTION=$1 +USER=$2 +IP=$3 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + +if [ "x${USER}" = "x" ]; then + echo "$0: [ add | delete ] " + exit 1; +elif [ "x${USER}" = "xroot" ]; then + echo "$0: Invalid username." + exit 1; +fi + + +# We should run on linux and on SunOS the passwd -u/-l +if [ "X${UNAME}" = "XLinux" -o "X${UNAME}" = "XSunOS" ]; then + # Checking if passwd is present + ls ${PASSWD} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + CMD=${PASSWD} + if [ "x${ACTION}" = "xadd" ]; then + ARGS="-l" + elif [ "x${ACTION}" = "xdelete" ]; then + ARGS="-u" + else + echo "$0: invalid action: ${ACTION}" + exit 1; + fi + + +# On AIX, we run CHUSER +elif [ "X${UNAME}" = "XAIX" ]; then + # Checking if chuser is present + ls ${CHUSER} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + CMD=${CHUSER} + + # Disabling an account + if [ "x${ACTION}" = "xadd" ]; then + ARGS="account_locked=true" + # Unblock the account + elif [ "x${ACTION}" = "xdelete" ]; then + ARGS="account_locked=false" + # Invalid action + else + echo "$0: invalid action: ${ACTION}" + exit 1; + fi + + +# We only support Linux, SunOS and AIX +else + exit 0; +fi + + +# Execute the command +${CMD} ${ARGS} ${USER} + +exit 1; + diff --git a/active-response/firewall-drop.sh b/active-response/firewall-drop.sh new file mode 100644 index 000000000..5ca7abde1 --- /dev/null +++ b/active-response/firewall-drop.sh @@ -0,0 +1,300 @@ +#!/bin/sh +# Adds an IP to the iptables drop list (if linux) +# Adds an IP to the ipfilter drop list (if solaris, freebsd or netbsd) +# Adds an IP to the ipsec drop list (if aix) +# Requirements: Linux with iptables, Solaris/FreeBSD/NetBSD with ipfilter or AIX with IPSec +# Expect: srcip +# Author: Ahmet Ozturk (ipfilter and IPSec) +# Author: Daniel B. Cid (iptables) +# Author: cgzones +# Last modified: Oct 04, 2012 + +UNAME=`uname` +ECHO="/bin/echo" +GREP="/bin/grep" +IPTABLES="" +IP4TABLES="/sbin/iptables" +IP6TABLES="/sbin/ip6tables" +IPFILTER="/sbin/ipf" +if [ "X$UNAME" = "XSunOS" ]; then + IPFILTER="/usr/sbin/ipf" +fi +GENFILT="/usr/sbin/genfilt" +LSFILT="/usr/sbin/lsfilt" +MKFILT="/usr/sbin/mkfilt" +RMFILT="/usr/sbin/rmfilt" +ARG1="" +ARG2="" +RULEID="" +ACTION=$1 +USER=$2 +IP=$3 +PWD=`pwd` +LOCK="${PWD}/fw-drop" +LOCK_PID="${PWD}/fw-drop/pid" +IPV4F="/proc/sys/net/ipv4/ip_forward" +IPV6F="/proc/sys/net/ipv6/conf/all/forwarding" + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +filename=$(basename "$0") + +LOG_FILE="${PWD}/../logs/active-responses.log" + +echo "`date` $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + +case "${IP}" in + *:* ) IPTABLES=$IP6TABLES;; + *.* ) IPTABLES=$IP4TABLES;; + * ) echo "`date` Unable to run active response (invalid IP: '${IP}')." >> ${LOG_FILE} && exit 1;; +esac + +# This number should be more than enough (even if a hundred +# instances of this script is ran together). If you have +# a really loaded env, you can increase it to 75 or 100. +MAX_ITERATION="50" + +# Lock function +lock() +{ + i=0; + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Getting currently/saved PID locking the file + C_PID=`cat ${LOCK_PID} 2>/dev/null` + if [ "x" = "x${S_PID}" ]; then + S_PID=${C_PID} + fi + + # Breaking out of the loop after X attempts + if [ "x${C_PID}" = "x${S_PID}" ]; then + i=`expr $i + 1`; + fi + + sleep $i; + + i=`expr $i + 1`; + + # So i increments 2 by 2 if the pid does not change. + # If the pid keeps changing, we will increments one + # by one and fail after MAX_ITERACTION + + if [ "$i" = "${MAX_ITERATION}" ]; then + kill="false" + for pid in `pgrep -f "${filename}"`; do + if [ "x${pid}" = "x${C_PID}" ]; then + # Unlocking and exiting + kill -9 ${C_PID} + echo "`date` Killed process ${C_PID} holding lock." >> ${LOG_FILE} + kill="true" + unlock; + i=0; + S_PID=""; + break; + fi + done + + if [ "x${kill}" = "xfalse" ]; then + echo "`date` Unable kill process ${C_PID} holding lock." >> ${LOG_FILE} + # Unlocking and exiting + unlock; + exit 1; + fi + fi + done +} + +# Unlock function +unlock() +{ + rm -rf ${LOCK} +} + + + +# Blocking IP +if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then + echo "$0: invalid action: ${ACTION}" + exit 1; +fi + + + +# We should run on linux +if [ "X${UNAME}" = "XLinux" ]; then + if [ "x${ACTION}" = "xadd" ]; then + ARG1="-I INPUT -s ${IP} -j DROP" + ARG2="-I FORWARD -s ${IP} -j DROP" + else + ARG1="-D INPUT -s ${IP} -j DROP" + ARG2="-D FORWARD -s ${IP} -j DROP" + fi + + # Checking if iptables is present + if [ ! -x ${IPTABLES} ]; then + IPTABLES="/usr"${IPTABLES} + if [ ! -x ${IPTABLES} ]; then + echo "$0: can not find iptables" + exit 0; + fi + fi + + # Executing and exiting + COUNT=0; + lock; + while [ 1 ]; do + ${IPTABLES} ${ARG1} + RES=$? + if [ $RES = 0 ]; then + break; + else + COUNT=`expr $COUNT + 1`; + echo "`date` Unable to run (iptables returning != $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + sleep $COUNT; + + if [ $COUNT -gt 4 ]; then + break; + fi + fi + done + + COUNT=0; + while [ 1 ]; do + # + # Looking for IPV4 and IPV6 FORWARD + # + if [ -e "$IPV4F" ] + then + IPV4KEY="$(cat "$IPV4F")" + else + IPV4KEY="0" + fi + if [ -e "$IPV6F" ] + then + IPV6KEY="$(cat "$IPV6F")" + else + IPV6KEY="0" + fi + + if [ "$IPV4KEY" = "0" ] && [ "$IPV6KEY" = "0" ] + then + break + fi + + ${IPTABLES} ${ARG2} + RES=$? + if [ $RES = 0 ]; then + break; + else + COUNT=`expr $COUNT + 1`; + echo "`date` Unable to run (iptables returning != $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + sleep $COUNT; + + if [ $COUNT -gt 4 ]; then + break; + fi + fi + done + unlock; + + exit 0; + +# FreeBSD, SunOS or NetBSD with ipfilter +elif [ "X${UNAME}" = "XFreeBSD" -o "X${UNAME}" = "XSunOS" -o "X${UNAME}" = "XNetBSD" ]; then + + # Checking if ipfilter is present + ls ${IPFILTER} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + # Checking if echo is present + ls ${ECHO} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + if [ "x${ACTION}" = "xadd" ]; then + ARG1="\"@1 block out quick from any to ${IP}\"" + ARG2="\"@1 block in quick from ${IP} to any\"" + IPFARG="${IPFILTER} -f -" + else + ARG1="\"@1 block out quick from any to ${IP}\"" + ARG2="\"@1 block in quick from ${IP} to any\"" + IPFARG="${IPFILTER} -rf -" + fi + + # Executing it + eval ${ECHO} ${ARG1}| ${IPFARG} + eval ${ECHO} ${ARG2}| ${IPFARG} + + exit 0; + +# AIX with ipsec +elif [ "X${UNAME}" = "XAIX" ]; then + + # Checking if genfilt is present + ls ${GENFILT} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + # Checking if lsfilt is present + ls ${LSFILT} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + # Checking if mkfilt is present + ls ${MKFILT} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + # Checking if rmfilt is present + ls ${RMFILT} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + if [ "x${ACTION}" = "xadd" ]; then + ARG1=" -v 4 -a D -s ${IP} -m 255.255.255.255 -d 0.0.0.0 -M 0.0.0.0 -w B -D \"Access Denied by openarmor-HIDS\"" + #Add filter to rule table + eval ${GENFILT} ${ARG1} + + #Deactivate and activate the filter rules. + eval ${MKFILT} -v 4 -d + eval ${MKFILT} -v 4 -u + else + # removing a specific rule is not so easy :( + eval ${LSFILT} -v 4 -O | ${GREP} ${IP} | + while read -r LINE + do + RULEID=`${ECHO} ${LINE} | cut -f 1 -d "|"` + let RULEID=${RULEID}+1 + ARG1=" -v 4 -n ${RULEID}" + eval ${RMFILT} ${ARG1} + done + #Deactivate and activate the filter rules. + eval ${MKFILT} -v 4 -d + eval ${MKFILT} -v 4 -u + fi + +else + exit 0; +fi diff --git a/active-response/firewalld-drop.sh b/active-response/firewalld-drop.sh new file mode 100644 index 000000000..8ce309740 --- /dev/null +++ b/active-response/firewalld-drop.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# Adds an IP to the firewalld drop list +# Requirements: Linux with firewalld +# Expect: srcip +# Author: Daniel B. Cid (iptables) +# Author: cgzones +# Author: ChristianBeer +# Last modified: Apr 10, 2015 + +UNAME=`uname` +ECHO="/bin/echo" +GREP="/bin/grep" +FWDCMD="/bin/firewall-cmd" +RULE="" +ARG1="" +# ARG2 can be used to specify the zone where the rich rule should be added otherwise it adds it to the default zone +ARG2="" +#ARG2="--zone=external" +RULEID="" +ACTION=$1 +USER=$2 +IP=$3 +PWD=`pwd` +LOCK="${PWD}/fw-drop" +LOCK_PID="${PWD}/fw-drop/pid" + + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +filename=$(basename "$0") + +LOG_FILE="${PWD}/../logs/active-responses.log" + +echo "`date` $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + +case "${IP}" in + *:* ) RULE="rule family='ipv6' source address='${IP}' drop";; + *.* ) RULE="rule family='ipv4' source address='${IP}' drop";; + * ) echo "`date` Unable to run active response (invalid IP: '${IP}')." >> ${LOG_FILE} && exit 1;; +esac + +# This number should be more than enough (even if a hundred +# instances of this script is ran together). If you have +# a really loaded env, you can increase it to 75 or 100. +MAX_ITERATION="50" + +# Lock function +lock() +{ + i=0; + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Getting currently/saved PID locking the file + C_PID=`cat ${LOCK_PID} 2>/dev/null` + if [ "x" = "x${S_PID}" ]; then + S_PID=${C_PID} + fi + + # Breaking out of the loop after X attempts + if [ "x${C_PID}" = "x${S_PID}" ]; then + i=`expr $i + 1`; + fi + + sleep $i; + + i=`expr $i + 1`; + + # So i increments 2 by 2 if the pid does not change. + # If the pid keeps changing, we will increments one + # by one and fail after MAX_ITERACTION + + if [ "$i" = "${MAX_ITERATION}" ]; then + kill="false" + for pid in `pgrep -f "${filename}"`; do + if [ "x${pid}" = "x${C_PID}" ]; then + # Unlocking and exiting + kill -9 ${C_PID} + echo "`date` Killed process ${C_PID} holding lock." >> ${LOG_FILE} + kill="true" + unlock; + i=0; + S_PID=""; + break; + fi + done + + if [ "x${kill}" = "xfalse" ]; then + echo "`date` Unable kill process ${C_PID} holding lock." >> ${LOG_FILE} + # Unlocking and exiting + unlock; + exit 1; + fi + fi + done +} + +# Unlock function +unlock() +{ + rm -rf ${LOCK} +} + + + +# Blocking IP +if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then + echo "$0: invalid action: ${ACTION}" + exit 1; +fi + + + +# We should run on linux +if [ "X${UNAME}" = "XLinux" ]; then + if [ "x${ACTION}" = "xadd" ]; then + ARG1="--add-rich-rule=" + else + ARG1="--remove-rich-rule=" + fi + + # Checking if firewall-cmd is present + if [ ! -x ${FWDCMD} ]; then + FWDCMD="/usr"${FWDCMD} + if [ ! -x ${FWDCMD} ]; then + echo "$0: can not find firewall-cmd" + exit 1; + fi + fi + + # Executing and exiting + COUNT=0; + lock; + while [ 1 ]; do + ${FWDCMD} ${ARG1}"${RULE}" ${ARG2} >/dev/null + RES=$? + if [ $RES = 0 ]; then + break; + else + COUNT=`expr $COUNT + 1`; + echo "`date` Unable to run (firewall-cmd returning != $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + sleep $COUNT; + + if [ $COUNT -gt 4 ]; then + break; + fi + fi + done + unlock; + + exit 0; +else + exit 0; +fi diff --git a/active-response/firewalls/ipfw.sh b/active-response/firewalls/ipfw.sh new file mode 100644 index 000000000..83a0a4329 --- /dev/null +++ b/active-response/firewalls/ipfw.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# Adds an IP to the IPFW drop list. +# Only works with IPFW. +# We use TABLE 00001. If you use this table for anything else, +# please change it here. +# Expect: srcip +# Author: Rafael Capovilla - under @ ( at ) underlinux.com.br +# Author: Daniel B. Cid - dcid @ ( at ) theopenarmor.org +# Last modified: May 07, 2006 + +UNAME=`uname` +IPFW="/sbin/ipfw" +ARG1="" +ARG2="" +ACTION=$1 +USER=$2 +IP=$3 +TABLE_ID=00001 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + + + +# Blocking IP +if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then + echo "$0: Invalid action: ${ACTION}" + exit 1; +fi + + +# We should run on FreeBSD +# We always use table 00001 and rule id 00001. +if [ "X${UNAME}" = "XFreeBSD" ]; then + ls ${IPFW} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + # Check if our table is set + ${IPFW} show | grep "^00001" | grep "table(1)" >/dev/null 2>&1 + if [ ! $? = 0 ]; then + # We need to add the table + ${IPFW} -q 00001 add deny ip from table\(${TABLE_ID}\) to any + ${IPFW} -q 00001 add deny ip from any to table\(${TABLE_ID}\) + fi + + + # Executing and exiting + ${IPFW} -q table ${TABLE_ID} ${ACTION} ${IP} + + exit 0; +fi + + +# Not FreeBSD +exit 1; diff --git a/active-response/firewalls/ipfw_mac.sh b/active-response/firewalls/ipfw_mac.sh new file mode 100644 index 000000000..6a4dcea6a --- /dev/null +++ b/active-response/firewalls/ipfw_mac.sh @@ -0,0 +1,78 @@ +#!/bin/sh +# Adds an IP to the IPFW drop list. +# Only works with IPFW. +# Expect: srcip +# Author: Rafael Capovilla - under @ ( at ) underlinux.com.br +# Author: Daniel B. Cid - dcid @ ( at ) theopenarmor.org +# Author: Charles W. Kefauver ckefauver @ ( at ) ibacom.es +# changed for Mac OS X compatibility +# Last modified: August 14, 2006 + +UNAME=`uname` +IPFW="/sbin/ipfw" +ARG1="" +ARG2="" +ACTION=$1 +USER=$2 +IP=$3 + +# warning do NOT add leading 0 in SET_ID +SET_ID=2 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + +# Blocking IP +if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then + echo "$0: Invalid action: ${ACTION}" + exit 1; +fi + + +# We should run on Darwin +if [ "X${UNAME}" = "XDarwin" ]; then + ls ${IPFW} >> /dev/null 2>&1 + if [ $? != 0 ]; then + exit 0; + fi + + + # Executing and exiting + if [ "x${ACTION}" = "xadd" ]; then + #${IPFW} set disable ${SET_ID} + ${IPFW} -q add set ${SET_ID} deny ip from ${IP} to any + ${IPFW} -q add set ${SET_ID} deny ip from any to ${IP} + ${IPFW} -q set enable ${SET_ID} + exit 0; + fi + + if [ "x${ACTION}" = "xdelete" ]; then + #${IPFW} -S show | grep "set ${SET_ID}" | grep "${IP}" >/dev/null 2>&1 + #get list of ipfw rules ID to delete + RULES_TO_DELETE=`${IPFW} -S show | grep "set ${SET_ID}" | grep "${IP}" | awk '{print $1}'` + + for RULE_ID in ${RULES_TO_DELETE} + do + ${IPFW} -q delete ${RULE_ID} + done + + exit 0; + fi + + exit 0; +fi + + +# Not Darwin +exit 1; + diff --git a/active-response/firewalls/npf.sh b/active-response/firewalls/npf.sh new file mode 100644 index 000000000..0e03922f9 --- /dev/null +++ b/active-response/firewalls/npf.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# Author: Gianni D'Aprile + +GREP=`which grep` + +ACTION=$1 +USER=$2 +IP=$3 + +# Finding path +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + +NPFCTL=/sbin/npfctl + +if [ ! -x ${NPFCTL} ]; then + echo "$0: NPF not present." + echo "$0: NPF not present." >> ${PWD}/openarmor-hids-responses.log + exit 0; +fi + +NPF_ACTIVE=`${NPFCTL} show | grep "filtering:" | ${GREP} -c active` + +if [ "x1" != "x${NPF_ACTIVE}" ]; then + echo "$0: NPF not active." + echo "$0: NPF not active." >> ${PWD}/openarmor-hids-responses.log + exit 0; +fi + +NPF_openarmor_READY=`${NPFCTL} show | ${GREP} -c "table "` + +if [ "x1" != "x${NPF_openarmor_READY}" ]; then + echo "$0: NPF not configured." + echo "$0: NPF not configured." >> ${PWD}/openarmor-hids-responses.log + exit 0; +fi + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + +case "x${ACTION}" in + + # Blocking IP + xadd) + + ${NPFCTL} table openarmor_blacklist add ${IP} >/dev/null 2>&1 + exit 0 + + ;; + + # Unblocking IP + xdelete) + + ${NPFCTL} table openarmor_blacklist del ${IP} >/dev/null 2>&1 + exit 0 + + ;; + + # No matching action + *) + + echo "$0: invalid action: ${ACTION}" + echo "$0: invalid action: ${ACTION}" >> ${PWD}/openarmor-hids-responses.log + exit 1 + + ;; + +esac diff --git a/active-response/firewalls/pf.sh b/active-response/firewalls/pf.sh new file mode 100644 index 000000000..4b833eb6d --- /dev/null +++ b/active-response/firewalls/pf.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# Author: Rafael M. Capovilla +# Last modified: Daniel B. Cid + +UNAME=`uname` +GREP="/usr/bin/grep" +PFCTL="/sbin/pfctl" +PFCTL_RULES="/etc/pf.conf" +PFCTL_TABLE="openarmor_fwtable" +ARG1="" +ARG2="" +CHECKTABLE="" +ACTION=$1 +USER=$2 +IP=$3 + +# Getting pf rules file. +if [ ! -f $PFCTL_RULES ]; then + echo "The pf rules file $PFCTL_RULES does not exist" + exit 1 +fi + +# Checking if openarmor table is configured +CHECKTABLE=`cat ${PFCTL_RULES} | $GREP $PFCTL_TABLE` +if [ -z "$CHECKTABLE" ]; then + echo "Table $PFCTL_TABLE does not exist" + exit 1 +fi + +# Finding path +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + +# Blocking IP +if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then + echo "$0: invalid action: ${ACTION}" + echo "$0: invalid action: ${ACTION}" >> ${PWD}/openarmor-hids-responses.log + exit 1; +fi + +# OpenBSD and FreeBSD pf +if [ "X${UNAME}" = "XOpenBSD" -o "X${UNAME}" = "XFreeBSD" -o "X${UNAME}" = "XDarwin" ]; then + + # Checking if pfctl is present + ls ${PFCTL} > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "$0: PF not configured." + echo "$0: PF not configured." >> ${PWD}/openarmor-hids-responses.log + exit 0; + fi + + # Checking if we have pf config file + if [ -e ${PFCTL_RULES} ]; then + + #Checking if we got the table to add the bad guys + if [ "x${PFCTL_TABLE}" = "x" ]; then + echo "$0: PF not configured." + echo "$0: PF not configured." >> ${PWD}/openarmor-hids-responses.log + exit 0; + else + if [ "x${ACTION}" = "xadd" ]; then + ARG1="-t $PFCTL_TABLE -T add ${IP}" + ARG2="-k ${IP}" + else + ARG1="-t $PFCTL_TABLE -T delete ${IP}" + fi + fi + else + exit 0; + fi + + #Executing it + ${PFCTL} ${ARG1} > /dev/null 2>&1 + ${PFCTL} ${ARG2} > /dev/null 2>&1 + exit 0; + +else + exit 0; +fi diff --git a/active-response/host-deny.sh b/active-response/host-deny.sh new file mode 100644 index 000000000..e96e1cd7e --- /dev/null +++ b/active-response/host-deny.sh @@ -0,0 +1,147 @@ +#!/bin/sh +# Adds an IP to the /etc/hosts.deny file +# Requirements: sshd and other binaries with tcp wrappers support +# Expect: srcip +# Author: Daniel B. Cid +# Last modified: Nov 09, 2005 + +ACTION=$1 +USER=$2 +IP=$3 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +LOCK="${PWD}/host-deny-lock" +LOCK_PID="${PWD}/host-deny-lock/pid" +UNAME=`uname` + + +# This number should be more than enough (even if a hundred +# instances of this script is ran together). If you have +# a really loaded env, you can increase it to 75 or 100. +MAX_ITERATION="50" + + +# Lock function +lock() +{ + i=0; + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Getting currently/saved PID locking the file + C_PID=`cat ${LOCK_PID} 2>/dev/null` + if [ "x" = "x${S_PID}" ]; then + S_PID=${C_PID} + fi + + # Breaking out of the loop after X attempts + if [ "x${C_PID}" = "x${S_PID}" ]; then + i=`expr $i + 1`; + fi + + sleep $i; + + i=`expr $i + 1`; + + # So i increments 2 by 2 if the pid does not change. + # If the pid keeps changing, we will increments one + # by one and fail after MAX_ITERACTION + if [ "$i" = "${MAX_ITERATION}" ]; then + echo "`date` Unable to execute. Locked: $0" \ + >> ${PWD}/openarmor-hids-responses.log + + # Unlocking and exiting + unlock; + exit 1; + fi + done +} + +# Unlock function +unlock() +{ + rm -rf ${LOCK} +} + + +# Logging the call +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + +# IP Address must be provided +if [ "x${IP}" = "x" ]; then + echo "$0: Missing argument (ip)" + exit 1; +fi + + +# Checking for invalid entries (lacking "." or ":", etc) +echo "${IP}" | egrep "\.|\:" > /dev/null 2>&1 +if [ ! $? = 0 ]; then + echo "`date` Invalid ip/hostname entry: ${IP}" >> ${PWD}/../logs/active-responses.log + exit 1; +fi + + +# Adding the ip to hosts.deny +if [ "x${ACTION}" = "xadd" ]; then + # Looking for duplication + IPKEY=$(grep -w "${IP}" /etc/hosts.deny) + if [ ! -z "$IPKEY" ]; then + echo "IP ${IP} already exists on host.deny..." >> ${PWD}/../logs/active-responses.log + exit 1 + fi + lock; + echo "${IP}" | grep "\:" > /dev/null 2>&1 + if [ $? = 0 ]; then + IP="[${IP}]" + fi + if [ "X$UNAME" = "XFreeBSD" ]; then + echo "ALL : ${IP} : deny" >> /etc/hosts.allow + else + echo "ALL:${IP}" >> /etc/hosts.deny + fi + unlock; + exit 0; + + +# Deleting from hosts.deny +elif [ "x${ACTION}" = "xdelete" ]; then + lock; + TMP_FILE=`mktemp ${PWD}/openarmor-hosts.XXXXXXXXXX` + if [ "X${TMP_FILE}" = "X" ]; then + # Cheap fake tmpfile, but should be harder then no random data + TMP_FILE="${PWD}/openarmor-hosts.`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -1 `" + fi + echo "${IP}" | grep "\:" > /dev/null 2>&1 + if [ $? = 0 ]; then + IP="\[${IP}\]" + fi + if [ "X$UNAME" = "XFreeBSD" ]; then + cat /etc/hosts.allow | grep -v "ALL : ${IP} : deny$"> ${TMP_FILE} + mv ${TMP_FILE} /etc/hosts.allow + else + cat /etc/hosts.deny | grep -v "ALL:${IP}$"> ${TMP_FILE} + cat ${TMP_FILE} > /etc/hosts.deny + rm ${TMP_FILE} + fi + unlock; + exit 0; + + +# Invalid action +else + echo "$0: invalid action: ${ACTION}" +fi + +exit 1; diff --git a/active-response/ip-customblock.sh b/active-response/ip-customblock.sh new file mode 100644 index 000000000..5cb38f915 --- /dev/null +++ b/active-response/ip-customblock.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# Custom openarmor block / Easily modifiable for custom responses (touch a file, insert to db, etc). +# Expect: srcip +# Author: Daniel B. Cid +# Last modified: Feb 16, 2013 + +ACTION=$1 +USER=$2 +IP=$3 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` + + +# Logging the call +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + +# IP Address must be provided +if [ "x${IP}" = "x" ]; then + echo "$0: Missing argument (ip)" + exit 1; +fi + + +# Custom block (touching a file inside /ipblock/IP) +if [ "x${ACTION}" = "xadd" ]; then + if [ ! -d /ipblock ]; then + mkdir /ipblock + fi + touch "/ipblock/${IP}" +elif [ "x${ACTION}" = "xdelete" ]; then + rm -f "/ipblock/${IP}" + +# Invalid action +else + echo "$0: invalid action: ${ACTION}" +fi + +exit 1; diff --git a/active-response/nftables-drop.sh b/active-response/nftables-drop.sh new file mode 100644 index 000000000..d3caa5056 --- /dev/null +++ b/active-response/nftables-drop.sh @@ -0,0 +1,185 @@ +#!/bin/sh +# Adds an IP to a nftables set +# Requirements: Linux with nftables +# Expect: srcip +# Author: Daniel B. Cid (iptables) +# Author: cgzones +# Author: ChristianBeer +# Last modified: Dec 26, 2021 + +# You need to create a set and a rule that uses it in order for packets to be dropped +# make sure the drop rules are checked before the accept rules +# Example: +# nft add set inet filter openarmor_ar4 { type ipv4_addr\; comment \"openarmor active response\" \; } +# nft add set inet filter openarmor_ar6 { type ipv6_addr\; comment \"openarmor active response\" \; } +# nft add rule inet filter input ip saddr @openarmor_ar4 drop +# nft add rule inet filter input ip6 saddr @openarmor_ar6 drop + + +UNAME=`uname` +ECHO="/bin/echo" +GREP="/bin/grep" +NFTCMD="/usr/sbin/nft" +RULE="" +ARG1="" +# protocol family used in nftables configuration +FAMILYIPV4="inet" # use "ip" when you have separate tables for ipv4 and ipv6 +FAMILYIPV6="inet" # use "ip6" when you have separate tables for ipv4 and ipv6 +# nftables table name +TABLEIPV4="filter" +TABLEIPV6="filter" +# Name of the sets where offending IPs should be added +SETIPV4="openarmor_ar4" +SETIPV6="openarmor_ar6" + +RULEID="" +ACTION=$1 +USER=$2 +IP=$3 +PWD=`pwd` +LOCK="${PWD}/nft-drop" +LOCK_PID="${PWD}/nft-drop/pid" + + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +filename=$(basename "$0") + +LOG_FILE="${PWD}/../logs/active-responses.log" + +echo "`date` $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + + +# Checking for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " + exit 1; +fi + +case "${IP}" in + *:* ) RULE="element ${FAMILYIPV6} ${TABLEIPV6} ${SETIPV6} { ${IP} }";; + *.* ) RULE="element ${FAMILYIPV4} ${TABLEIPV4} ${SETIPV4} { ${IP} }";; + * ) echo "`date` Unable to run active response (invalid IP: '${IP}')." >> ${LOG_FILE} && exit 1;; +esac + +# This number should be more than enough (even if a hundred +# instances of this script is ran together). If you have +# a really loaded env, you can increase it to 75 or 100. +MAX_ITERATION="50" + +# Lock function +lock() +{ + i=0; + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Getting currently/saved PID locking the file + C_PID=`cat ${LOCK_PID} 2>/dev/null` + if [ "x" = "x${S_PID}" ]; then + S_PID=${C_PID} + fi + + # Breaking out of the loop after X attempts + if [ "x${C_PID}" = "x${S_PID}" ]; then + i=`expr $i + 1`; + fi + + sleep $i; + + i=`expr $i + 1`; + + # So i increments 2 by 2 if the pid does not change. + # If the pid keeps changing, we will increments one + # by one and fail after MAX_ITERACTION + + if [ "$i" = "${MAX_ITERATION}" ]; then + kill="false" + for pid in `pgrep -f "${filename}"`; do + if [ "x${pid}" = "x${C_PID}" ]; then + # Unlocking and exiting + kill -9 ${C_PID} + echo "`date` Killed process ${C_PID} holding lock." >> ${LOG_FILE} + kill="true" + unlock; + i=0; + S_PID=""; + break; + fi + done + + if [ "x${kill}" = "xfalse" ]; then + echo "`date` Unable kill process ${C_PID} holding lock." >> ${LOG_FILE} + # Unlocking and exiting + unlock; + exit 1; + fi + fi + done +} + +# Unlock function +unlock() +{ + rm -rf ${LOCK} +} + + + +# Blocking IP +if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then + echo "$0: invalid action: ${ACTION}" + exit 1; +fi + + + +# We should run on linux +if [ "X${UNAME}" = "XLinux" ]; then + if [ "x${ACTION}" = "xadd" ]; then + ARG1="add" + else + ARG1="delete" + fi + + # Checking if nft is present + if [ ! -x ${NFTCMD} ]; then + NFTCMD="/usr"${NFTCMD} + if [ ! -x ${NFTCMD} ]; then + echo "$0: can not find nft" + exit 1; + fi + fi + + # Executing and exiting + COUNT=0; + lock; + while [ 1 ]; do + ${NFTCMD} ${ARG1} ${RULE} >/dev/null + RES=$? + if [ $RES = 0 ]; then + break; + else + COUNT=`expr $COUNT + 1`; + echo "`date` Unable to run (nft returning $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE} + sleep $COUNT; + + if [ $COUNT -gt 4 ]; then + break; + fi + fi + done + unlock; + + exit 0; +else + exit 0; +fi diff --git a/active-response/openarmor-aws-waf.sh b/active-response/openarmor-aws-waf.sh new file mode 100644 index 000000000..f940dfd7a --- /dev/null +++ b/active-response/openarmor-aws-waf.sh @@ -0,0 +1,83 @@ +#!/bin/sh +# Adds an IP to an existing IPSet in AWS Web Application Firewall +# Requirements: Linux with aws cli installed and configured (aws cli needs python) +# Expect: srcip +# Author: Midi12 +# Last modified: Feb 25, 2020 + +# Change this values +IPSETID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # target ip set identifier +REGION="xx-xxxx-x" # target waf region +IS_REGIONAL=0 # put 0 to use waf (Cloudfront) or 1 to use waf-regional (eg. API Gateway regional endpoint) + +# Setup +if ! [ -x "$(command -v aws)" ]; then + echo "aws cli is not installed" >&2 + exit 1; +fi + +AWS=$(command -v aws) +PWD=`pwd` +LOCAL=`dirname $0` +ACTION=$1 +USER=$2 +IP=$3 +P_REGION="" +P_IPTYPE="" +P_ACTION="" +P_CHGTKN="" +P_RESP="" + +cd $LOCAL +cd ../ + +FILENAME=$(basename "$0") +LOGFILE="${PWD}/../logs/active-responses.log" + +echo "`date` $0 $1 $2 $3 $4 $5" >> ${LOGFILE} + +# Check for an action +if [ "x${ACTION}" = "x" ]; then + echo "$0: " >&2 + exit 1; +fi + +# Check for an IP +if [ "x${IP}" = "x" ]; then + echo "$0: " >&2 + exit 1; +fi + +# Determining regional +case "${IS_REGIONAL}" in + 0 ) P_REGION="waf";; + 1 ) P_REGION="waf-regional";; + * ) echo "`date` Unable to run active response (invalid configuration parameter: IS_REGIONAL '${IS_REGIONAL}'" >> ${LOGFILE} && exit 1;; +esac + +# Determining action +case "${ACTION}" in + add ) P_ACTION="INSERT";; + delete ) P_ACTION="DELETE";; + * ) echo "`date` Unable to run active response (invalid argument Action: '${ACTION}'" >> ${LOGFILE} && exit 1;; +esac + +# Determining IP type +case "${IP}" in + *:* ) IP="${IP}/128" && P_IPTYPE="IPV6";; + *.* ) IP="${IP}/32" && P_IPTYPE="IPV4";; + * ) echo "`date` Unable to run active response (invalid argument IP: '${IP}')" >> ${LOGFILE} && exit 1;; +esac + +P_CHGTKN="$(${AWS} ${P_REGION} get-change-token --region ${REGION} --output text)" + +P_RESP="$(${AWS} ${P_REGION} update-ip-set --ip-set-id ${IPSETID} --change-token ${P_CHGTKN} --updates Action=\"${P_ACTION}\",IPSetDescriptor=\{Type="${P_IPTYPE}",Value="${IP}"\} --region $REGION --output text)" + + +if [ "${P_RESP}" != "${P_CHGTKN}" ]; then + echo "`date` Failed to update waf ipset: '${P_ACTION} ${IP} ${P_RESP}'" >> ${LOGFILE} + exit 1; +fi + +echo "Action ${ACTION} on IP ${IP} succeed" >&1 +echo "`date` Action ${ACTION} on IP ${IP} succeed" >> ${LOGFILE} diff --git a/active-response/openarmor-pagerduty.sh b/active-response/openarmor-pagerduty.sh new file mode 100644 index 000000000..5c18af6e9 --- /dev/null +++ b/active-response/openarmor-pagerduty.sh @@ -0,0 +1,30 @@ +#!/bin/bash -x + +# Change these values! +# APIKEY Your pagerduty api key + +APIKEY="xxxxxxx" +# Checking user arguments +if [ "x$1" = "xdelete" ]; then + exit 0; +fi +ALERTID=$4 +RULEID=$5 +LOCAL=`dirname $0`; +ALERTTIME=`echo "$ALERTID" | cut -d "." -f 1` +ALERTLAST=`echo "$ALERTID" | cut -d "." -f 2` + +# Logging +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5 $6 $7 $8" >> ${PWD}/../logs/active-responses.log +ALERTFULL=`grep -A 10 "$ALERTTIME" ${PWD}/../logs/alerts/alerts.log | grep -v "\.$ALERTLAST: " -A 10 | grep -v "Src IP: " | grep -v "User: " |grep "Rule: " -A 4 | cut -c -139 | sed 's/\"//g'` + +ALERTLOG= ${PWD}/../logs/alerts/alerts.log + +postfile=`mktemp` + +echo '{ "service_key": "'$APIKEY'", "incident_key": "Alert: '$ALERTTIME' / Rule: '$RULEID'", "event_type": "trigger", "description": "openarmor Alert: '$ALERTLAST'", "client": "openarmor IDS", "client_url": "http://dcid.me/openarmor", "details": { "location": "'$HOSTNAME'", "Rule":"'$RULEID'", "Description":"'$ALERTFULL'", "Log":"'$ALERTLOG'"} } ' > $postfile + +curl -H "Content-type: application/json" -X POST --data @$postfile "https://events.pagerduty.com/generic/2010-04-15/create_event.json" diff --git a/active-response/openarmor-slack.sh b/active-response/openarmor-slack.sh new file mode 100644 index 000000000..eef55c52f --- /dev/null +++ b/active-response/openarmor-slack.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# Change these values! +# SLACKUSER user who posts notifications +# CHANNEL which channel it should be posted +# SITE is the URL provided by the Slack's WebHook, something like: +# https://hooks.slack.com/services/TOKEN" +SLACKUSER="" +CHANNEL="" +SITE="" +SOURCE="openarmor2slack" + +# Checking user arguments +if [ "x$1" = "xdelete" ]; then + exit 0; +fi +ALERTID=$4 +RULEID=$5 +LOCAL=`dirname $0`; + +# Logging +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5 $6 $7 $8" >> ${PWD}/../logs/active-responses.log +ALERTTITLE=`grep -A 1 "$ALERTID" ${PWD}/../logs/alerts/alerts.log | tail -1` +ALERTTEXT=`grep -A 10 "$ALERTID" ${PWD}/../logs/alerts/alerts.log | grep -v "Src IP: " | grep -v "User: " | grep "Rule: " -A 4 | sed '/^$/Q' | cut -c -139 | sed 's/\"//g'` + +LEVEL=`echo "${ALERTTEXT}" | head -1 | grep "(level [0-9]*)" | sed 's/^.*(level \([0-9]*\)).*$/\1/'` +COLOR="#D3D3D3" +if [ "${LEVEL}" ] +then + [ "${LEVEL}" -ge 4 ] && COLOR="#FFCC00" + [ "${LEVEL}" -ge 7 ] && COLOR="#FF9966" + [ "${LEVEL}" -ge 12 ] && COLOR="#CC3300" +fi + +PAYLOAD='{"channel": "'"$CHANNEL"'", "username": "'"$SLACKUSER"'", "attachments": [ {"fallback": "'"$( printf "${ALERTTITLE}\n${ALERTTEXT}" )"'", "title": "'"${ALERTTITLE}"'", "text": "'"${ALERTTEXT}"'", "color": "'"${COLOR}"'"} ]}' + +ls "`which curl`" > /dev/null 2>&1 +if [ ! $? = 0 ]; then + ls "`which wget`" > /dev/null 2>&1 + if [ $? = 0 ]; then + wget --keep-session-cookies --post-data="${PAYLOAD}" ${SITE} 2>>${PWD}/../logs/active-responses.log + exit 0; + fi +else + curl -s -X POST --data-urlencode "payload=${PAYLOAD}" ${SITE} 2>>${PWD}/../logs/active-responses.log + exit 0; +fi + +echo "`date` $0: Unable to find curl or wget." >> ${PWD}/../logs/active-responses.log +exit 1; diff --git a/active-response/openarmor-tweeter.sh b/active-response/openarmor-tweeter.sh new file mode 100644 index 000000000..238a4f4ee --- /dev/null +++ b/active-response/openarmor-tweeter.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Tweeter an alert - copy at /var/openarmor/active-response/bin/openarmor-tweeter.sh +# Author: Daniel Cid + + +# Change these values! +TWITTERUSER="" +TWITTERPASS='' +DIRECTMSGUSER="" +SOURCE="openarmor2tweeter" + + + +# Checking user arguments +if [ "x$1" = "xdelete" ]; then + exit 0; +fi +ALERTID=$4 +RULEID=$5 +LOCAL=`dirname $0`; +ALERTTIME=`echo "$ALERTID" | cut -d "." -f 1` +ALERTLAST=`echo "$ALERTID" | cut -d "." -f 2` + + + +# Logging +cd $LOCAL +cd ../ +PWD=`pwd` +echo "`date` $0 $1 $2 $3 $4 $5 $6 $7 $8" >> ${PWD}/../logs/active-responses.log +ALERTFULL=`grep -A 10 "$ALERTTIME" ${PWD}/../logs/alerts/alerts.log | grep -v "\.$ALERTLAST: " -A 10 | grep -v "Src IP: " | grep -v "User: " |grep "Rule: " -A 4 | cut -c -139` + + + +# Checking if we are sending direct message or not. +if [ "x" = "x$DIRECTMSGUSER" ]; then + SITE="http://twitter.com/statuses/update.xml" + REQUESTUSER="" + REQUESTMSG="status=$ALERTFULL" +else + SITE="http://twitter.com/direct_messages/new.xml" + REQUESTUSER="user=$DIRECTMSGUSER&" + REQUESTMSG="text=$ALERTFULL" +fi + + +ls "`which curl`" > /dev/null 2>&1 +if [ ! $? = 0 ]; then + ls "`which wget`" > /dev/null 2>&1 + if [ $? = 0 ]; then + wget --keep-session-cookies --http-user=$TWITTERUSER --http-password=$TWITTERPASS --post-data="source=$SOURCE&$REQUESTUSER$REQUESTMSG" $SITE 2>>${PWD}/../logs/active-responses.log + exit 0; + fi +else + curl -u "$TWITTERUSER:$TWITTERPASS" -d "source=$SOURCE&$REQUESTUSER$REQUESTMSG" $SITE 2>>${PWD}/../logs/active-responses.log + exit 0; +fi + +echo "`date` $0: Unable to find curl or wget." >> ${PWD}/../logs/active-responses.log +exit 1; diff --git a/active-response/restart-openarmor.sh b/active-response/restart-openarmor.sh new file mode 100644 index 000000000..2b675a8ae --- /dev/null +++ b/active-response/restart-openarmor.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Restarts openarmor. +# Requirements: none +# Author: Daniel B. Cid + +ACTION=$1 +USER=$2 +IP=$3 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +UNAME=`uname` + + +# Logging the call +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + + +# Adding the ip to hosts.deny +if [ "x${ACTION}" = "xadd" ]; then + ${PWD}/../bin/openarmor-control restart + exit 0; + + +# Deleting from hosts.deny +elif [ "x${ACTION}" = "xdelete" ]; then + exit 0; + + +# Invalid action +else + echo "$0: invalid action: ${ACTION}" +fi + +exit 1; diff --git a/active-response/route-null.sh b/active-response/route-null.sh new file mode 100644 index 000000000..4a336eebb --- /dev/null +++ b/active-response/route-null.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# Adds an IP to null route +# Requirements: ip route +# Expect: srcip +# Author: Ivan Lotina +# Modifyed script host-deny from Daniel B. Cid +# Last modified: Feb 16, 2007 + +ACTION=$1 +USER=$2 +IP=$3 + +LOCAL=`dirname $0`; +cd $LOCAL +cd ../ +PWD=`pwd` +LOCK="${PWD}/host-deny-lock" +LOCK_PID="${PWD}/host-deny-lock/pid" + +UNAME=`uname` + +# Logging the call +echo "`date` $0 $1 $2 $3 $4 $5" >> ${PWD}/../logs/active-responses.log + + +# IP Address must be provided +if [ "x${IP}" = "x" ]; then + echo "$0: Missing argument (ip)" + exit 1; +fi + +# Match the loopback address to the version of the provided IP address +LOOPBACK=127.0.0.1 +echo "${IP}" | grep "\:" > /dev/null 2>&1 +if [ $? = 0 ]; then + LOOPBACK=::1 +fi + +# Adding the ip to null route +if [ "x${ACTION}" = "xadd" ]; then + if [ "X${UNAME}" = "XLinux" ]; then + route add ${IP} reject + exit 0; + fi + + if [ "X${UNAME}" = "XFreeBSD" ]; then + route -q add ${IP} $LOOPBACK -blackhole + exit 0; + fi + +# Deleting from null route +# be carefull not to remove your default route +elif [ "x${ACTION}" = "xdelete" ]; then + if [ "X${UNAME}" = "XLinux" ]; then + route del ${IP} reject + exit 0; + fi + + if [ "X${UNAME}" = "XFreeBSD" ]; then + route -q delete ${IP} $LOOPBACK -blackhole + exit 0; + fi + +# Invalid action +else + echo "$0: invalid action: ${ACTION}" +fi + +exit 1; diff --git a/active-response/win/firewall-drop.cmd b/active-response/win/firewall-drop.cmd new file mode 100644 index 000000000..e1208c0f1 --- /dev/null +++ b/active-response/win/firewall-drop.cmd @@ -0,0 +1,42 @@ +@ECHO OFF +ECHO. + +:: Set some variables +FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET DAT=%%A %%B +FOR /F "TOKENS=1-3 DELIMS=:" %%A IN ("%TIME%") DO SET TIM=%%A:%%B:%%C + +:: Block IP Address +SET ACTION=%~1 +SET SRCIP=%~3 + +:: Check for required arguments +IF /I "%ACTION%"=="" GOTO ERROR +IF /I "%2"=="" GOTO ERROR +IF /I "%SRCIP%"=="" GOTO ERROR + + +IF /I "%ACTION%"=="add" GOTO ADD +IF /I "%ACTION%"=="delete" GOTO DEL + +:ERROR +ECHO Invalid argument(s). +ECHO Usage: firewall-drop.cmd ^(add^|delete^) user IP_Address +ECHO Example: firewall-drop.cmd ADD - 1.2.3.4 +ECHO %DAT%%TIM% "%~f0" %1 %2 %3 (error) >> "%openarmorPATH%active-response\active-responses.log" +EXIT /B 1 + +:: Adding IP to be blocked + +:ADD +ECHO Adding +netsh advfirewall firewall add rule name="openarmor-%SRCIP%" dir=in interface=any action=block remoteip=%SRCIP% +ECHO %DAT%%TIM% "%~f0" %1 %2 %3 >> "%openarmorPATH%active-response\active-responses.log" +GOTO EXIT + +:DEL +ECHO Removing +netsh advfirewall firewall delete rule name="openarmor-%SRCIP%" dir=in +ECHO %DAT%%TIM% "%~f0" %1 %2 %3 >> "%openarmorPATH%active-response\active-responses.log" + + +:EXIT /B 0: \ No newline at end of file diff --git a/active-response/win/netsh.cmd b/active-response/win/netsh.cmd new file mode 100644 index 000000000..d5b79c393 --- /dev/null +++ b/active-response/win/netsh.cmd @@ -0,0 +1,33 @@ +:: Simple script to block an ip using netsh. Commands from http://windowsnerd.com/ +@ECHO OFF +ECHO. + + +:: Logging it all +FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET DATE=%%B +FOR /F "TOKENS=1* DELIMS= " %%A IN ('TIME/T') DO SET TIME=%%A +ECHO %DATE% %TIME% %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 >> active-response/active-responses.log + + +IF "%1"=="add" GOTO ADD +IF "%1"=="delete" GOTO DEL +:ERROR + +ECHO "Invalid argument. %1" +GOTO Exit; + + +:: Adding to the blocked. + +:ADD +:: Extracts last ip address from ipconfig. +netsh ipsec static add policy description="openarmor block list" +netsh ipsec static add filter filterlist="openarmorfilter" srcaddr=%3 dstaddr=me protocol=tcp mirrored=yes +netsh ipsec static add rule policy="openarmor" filterlist="openarmorfilter" filteraction="block" desc="list of blocked ips" +netsh ipsec static set policy assign=y +GOTO Exit; + +:DEL +netsh ipsec static delete filter filterlist="openarmorfilter" srcaddr=%3 dstaddr=me protocol=tcp mirrored=yes + +:Exit diff --git a/active-response/win/restart-openarmor.cmd b/active-response/win/restart-openarmor.cmd new file mode 100644 index 000000000..c62f55253 --- /dev/null +++ b/active-response/win/restart-openarmor.cmd @@ -0,0 +1,28 @@ +:: Simple script to restart openarmor agent. +@ECHO OFF +ECHO. + + +:: Logging it all +FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET DATE=%%B +FOR /F "TOKENS=1* DELIMS= " %%A IN ('TIME/T') DO SET TIME=%%A +ECHO %DATE% %TIME% %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 >> active-response/active-responses.log + + +IF "%1"=="add" GOTO ADD +IF "%1"=="delete" GOTO DEL +:ERROR + +ECHO "Invalid argument. %1" +GOTO Exit; + + +:ADD +net stop openarmorSvc +net start openarmorSvc + +GOTO Exit; + +:DEL + +:Exit diff --git a/active-response/win/route-null.cmd b/active-response/win/route-null.cmd new file mode 100644 index 000000000..a6947838b --- /dev/null +++ b/active-response/win/route-null.cmd @@ -0,0 +1,48 @@ +:: Script to null route an ip address. +@ECHO OFF +ECHO. + +:: Set some variables +FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET DAT=%%A %%B +FOR /F "TOKENS=1-3 DELIMS=:" %%A IN ("%TIME%") DO SET TIM=%%A:%%B:%%C + +:: Check for required arguments +IF /I "%1"=="" GOTO ERROR +IF /I "%2"=="" GOTO ERROR +IF /I "%3"=="" GOTO ERROR + +:: Check for a valid IP +ECHO "%3" | %WINDIR%\system32\findstr.exe /R "\." >nul || GOTO ipv6 + +set prefixlength=32 +set gateway=0.0.0.0 +goto x + +:ipv6 +set prefixlength=128 +set gateway=:: + +:x + +IF /I "%1"=="add" GOTO ADD +IF /I "%1"=="delete" GOTO DEL + +:ERROR +ECHO Invalid argument(s). +ECHO Usage: route-null.cmd ^(ADD^|DELETE^) user IP_Address +ECHO Example: route-null.cmd ADD - 1.2.3.4 +EXIT /B 1 + +:: Adding IP to be null-routed. + +:ADD +%WINDIR%\system32\route.exe ADD %3/%prefixlength% %gateway% +:: Log it +ECHO %DAT%%TIM% "%~f0" %1 %2 %3 >> "%openarmorPATH%active-response\active-responses.log" +GOTO EXIT + +:DEL +%WINDIR%\system32\route.exe DELETE %3/%prefixlength% +ECHO %DAT%%TIM% "%~f0" %1 %2 %3 >> "%openarmorPATH%active-response\active-responses.log" + +:EXIT /B 0: diff --git a/build.sh b/build.sh new file mode 100644 index 000000000..407d3a0a2 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e -o pipefail + +scriptpath=$(dirname $0) +$scriptpath/contrib/debian-packages/generate_openarmor.sh -d +$scriptpath/contrib/debian-packages/generate_openarmor.sh -u +$scriptpath/contrib/debian-packages/generate_openarmor.sh -b diff --git a/contrib/active-list.pl b/contrib/active-list.pl new file mode 100644 index 000000000..9a60883a2 --- /dev/null +++ b/contrib/active-list.pl @@ -0,0 +1,103 @@ +#!/usr/bin/perl +# +# openarmor active-response script to store a suspicious IP address in a MySQL table. +# +# Available actions are: +# 'add' - Create a new record in the MySQL DB +# 'delete' - Remove a existing record +# +# History +# ------- +# 2010/10/24 xavir@rootshell.be Created +# + +use strict; +use warnings; +use DBI; +use Regexp::IPv6 qw($IPv6_re); + +# ----------------------- +# DB access configuration +# ----------------------- +my $db_name = 'openarmor_active_lists'; +my $db_user = 'suspicious'; +my $db_pass = 'xxxxxxxxxx'; + +my ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); +my $theTime = sprintf("%d-%02d-%02d %02d:%02d:%02d", + $yearOffset+1900, $month+1, $dayOfMonth, $hour, $minute, $second); + +my $nArgs = $#ARGV + 1; +if ($nArgs != 5) { + print STDERR "Usage: active-list.pl \n"; + exit 1; +} + +my $action = $ARGV[0]; +my $ipAddr = $ARGV[2]; +my $alertId = $ARGV[3]; +my $ruleId = $ARGV[4]; + +if ($action ne "add" && $action ne "delete") { + WriteLog("Invalid action: $action\n"); + exit 1; +} + +if ($ipAddr =~ m/^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)/) { + if ($1 > 255 || $2 > 255 || $3 > 255 || $4 > 255) { + WriteLog("Invalid IP address: $ipAddr\n"); + exit 1; + } +} +else if ($ipAddr =~ m/^$IPv6_re/) { +} +else { + WriteLog("Invalid IP address: $ipAddr\n"); +} + +WriteLog("active-list.pl $action $ipAddr $alertId $ruleId\n"); + +my $dbh = DBI->connect('DBI:mysql:' . $db_name, $db_user, $db_pass) || \ + die "Could not connect to database: $DBI::errstr"; + +if ( $action eq "add" ) { + my $sth = $dbh->prepare('SELECT ip FROM ip_addresses WHERE ip = "' . $ipAddr . '"'); + $sth->execute(); + my $result = $sth->fetchrow_hashref(); + if (!$result->{ip}) { + $sth = $dbh->prepare('INSERT INTO ip_addresses VALUES ("' . $ipAddr . '","'. $theTime . '",' . $alertId . ',' . $ruleId . ',"Added by suspicious-ip Perl Script")'); + if (!$sth->execute) { + WriteLog("Cannot insert new IP address: $DBI::errstr\n"); + } + } + else { + $sth = $dbh->prepare('UPDATE ip_addresses SET timestamp = "' . $theTime . '", alertid = ' . $alertId . ', ruleid = ' . $ruleId . ' WHERE ip = "' . $ipAddr . '"'); + if (!$sth->execute) { + WriteLog("Cannot update IP address: $DBI::errstr\n"); + } + } +} +else { + my $sth = $dbh->prepare('DELETE FROM ip_addresses WHERE ip = "' . $ipAddr . '"'); + if (!$sth->execute) { + WriteLog("Cannot remove IP address: $DBI::errstr\n"); + } +} + +$dbh->disconnect; +exit 0; + +sub WriteLog +{ + if ( $_[0] eq "" ) { return; } + + my $pwd = `pwd`; + chomp($pwd); + my $date = `date`; + chomp($date); + + open(LOGH, ">>" . $pwd . "/../active-responses.log") || die "Cannot open log file."; + print LOGH $date . " " . $_[0]; + close(LOGH); + return; +} diff --git a/contrib/add_localfile.sh b/contrib/add_localfile.sh new file mode 100644 index 000000000..9f72667ee --- /dev/null +++ b/contrib/add_localfile.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Add a localfile to openarmor. +# by Daniel B. Cid - dcid ( at ) theopenarmor.org + +FILE=$1 +FORMAT=$2 + +if [ "X$FILE" = "X" ]; then + echo "$0: []" + exit 1; +fi + +if [ "X$FORMAT" = "X" ]; then + FORMAT="syslog" +fi + +# Checking if file is already configured +grep "$FILE" /var/openarmor/etc/openarmor.conf > /dev/null 2>&1 +if [ $? = 0 ]; then + echo "$0: File $FILE already configured at openarmor." + exit 1; +fi + +# Checking if file exist +ls -la $FILE > /dev/null 2>&1 +if [ ! $? = 0 ]; then + echo "$0: File $FILE does not exist." + exit 1; +fi + +echo " + + + $FORMAT + $FILE + + +" >> /var/openarmor/etc/openarmor.conf + +echo "$0: File $FILE added."; +exit 0; diff --git a/contrib/compile_alerts.pl b/contrib/compile_alerts.pl new file mode 100644 index 000000000..dba57ac53 --- /dev/null +++ b/contrib/compile_alerts.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl -w +use strict; +# Contrib by Meir Michanie +# meirm at riunx.com +# Licensed under GPL +my $VERSION='0.1'; +my $openarmor_path='/var/openarmor'; +my $rules_config="$openarmor_path/etc/rules_config.xml"; +my $usersignatures_path="$openarmor_path/user_signatures"; +my $signatures_path="$openarmor_path/signatures"; +while ( @ARGV) { + $_=shift @ARGV; + if (m/^-u$|^--user-signatures$/) { + $usersignatures_path= shift @ARGV; + &help() unless -d $usersignatures_path; + }elsif (m/^-s$|^--signatures$/){ + $signatures_path= shift @ARGV; + &help() unless -d $signatures_path; + }elsif (m/^-c$|^--rules_config$/){ + $rules_config= shift @ARGV; + &help() unless -f $rules_config; + }elsif (m/^-h$|^--help$/){ + &help; + } +} +print STDERR "Adding $rules_config\n"; +my @rules_files=($rules_config); +opendir (USERDEFINED , "$usersignatures_path") || die ("Could not open dir $usersignatures_path\n"); +my @temparray=(); +while ($_ = readdir(USERDEFINED)){ + chomp; + next unless -f "$usersignatures_path/$_"; + print STDERR "Adding $usersignatures_path/$_\n"; + push @temparray, "$usersignatures_path/$_"; +} +close (USERDEFINED); +push @rules_files , sort (@temparray); + +@temparray=(); +opendir(RULES,"$signatures_path") || die ("Could not open dir $signatures_path\n"); +while ($_ = readdir(RULES)){ + chomp; + next unless -f "$signatures_path/$_"; + print STDERR "Adding $signatures_path/$_\n"; + push @temparray, "$signatures_path/$_"; +} +close (RULES); +push @rules_files , sort (@temparray); +map { print STDERR "processing: $_\n";} @rules_files; +foreach (@rules_files){ + open (RFILE, "$_") ||die ("Could not open file $_"); + my @content=; + close (RFILE); + print join ('',@content); +} + +sub help(){ + print STDERR "$0\nRules compilation tool for openarmor \n"; + print "This tool facilitates the building of monolitic rules file to be included in openarmor.xml.\n" + . "You only need one rules include entry in openarmor.xml\n" + . "\n" + . "\topenarmor_rules.xml" + ."" + + . "$0 will print to STDOUT the result of the mixing.\n" + . "If no parameter are passed then the application will use the default locations.\n" + . "Default values:\n" + . "--user-signatures -> $usersignatures_path\n" + . "--signatures -> $signatures_path\n" + . "--rules-config -> $rules_config\n" + . "Compiling rules allows us to generate multiple configurations and even facilitate the upgrade of them.\n" + . "By instance, you can make a directory with symbolic links to rules you want to use without altering the standard repository.\n" + . "There are more examples of situation where you can use a subset of the rules repository\n" + . "I invite someone to reword this explanation.\n"; + + print STDERR "\n\nUsage:\n"; + print STDERR "$0 [-u|--user-signatures] [-s|--signatures] \n" + ."\n\nBUGS:\n" + . "I just wanted to deliver version one.\n" + . "I will change the script to read the directory sorted, so you can link signatures with names that would emulate the behavior of the sysV system.\n"; + + exit; +} diff --git a/contrib/compile_alerts.txt b/contrib/compile_alerts.txt new file mode 100644 index 000000000..9243edb24 --- /dev/null +++ b/contrib/compile_alerts.txt @@ -0,0 +1,286 @@ +openarmor rules reordering Mini Howto +by Meir Michanie + +Patching an openarmor installation +Reordering the rules + + * Stop openarmor + +root@topgun:/var/openarmor#/etc/init.d/openarmor stop + + + + * Backup the whole openarmor directory + +/root# tar -C /var -zcpvf openarmor-orig.tar.gz openarmor + + + + * Move the contrib directory from the source package to the oseec installation + +/var/openarmor# cp -a /tmp/openarmor/contrib . + + + * Create directories to host the rules + +/var/openarmor# mkdir signatures user_signatures repository + + + * Move the file rules_config.xml to the etc directory. + +/var/openarmor# mv rules/rules_config.xml etc/ + + + * Move the rest of the rules to the repository directory + +/var/openarmor# mv rules/* repository/ + + + * copy the rules tag portion to a file under /var/openarmor. i.e. rules.txt + * delete the rules opening and closing tags + * remove all xml code leaving only the list of the files. i.e. + +pam_rules.xml + sshd_rules.xml + telnetd_rules.xml + syslog_rules.xml + pix_rules.xml + named_rules.xml + smbd_rules.xml + vsftpd_rules.xml + pure-ftpd_rules.xml + proftpd_rules.xml + hordeimp_rules.xml + web_rules.xml + apache_rules.xml + ids_rules.xml + squid_rules.xml + firewall_rules.xml + netscreenfw_rules.xml + postfix_rules.xml + sendmail_rules.xml + imapd_rules.xml + spamd_rules.xml + msauth_rules.xml + policy_rules.xml + attack_rules.xml + + + * modify the rules tag to: + + + rules_openarmor.xml + + + * list of repository directory. + +/var/openarmor# ls -1 repository/ +apache_rules.xml +attack_rules.xml +firewall_rules.xml +ftpd_rules.xml +hordeimp_rules.xml +ids_rules.xml +imapd_rules.xml +msauth_rules.xml +named_rules.xml +netscreenfw_rules.xml +openarmor_rules.xml +pam_rules.xml +pix_rules.xml +policy_rules.xml +postfix_rules.xml +proftpd_rules.xml +pure-ftpd_rules.xml +rules-backup +sendmail_rules.xml +smbd_rules.xml +spamd_rules.xml +squid_rules.xml +sshd_rules.xml +syslog_rules.xml +telnetd_rules.xml +vsftpd_rules.xml +web_rules.xml + + + + * Viewing the content of file rules.txt + +/var/openarmor# cat rules.txt + pam_rules.xml + sshd_rules.xml + telnetd_rules.xml + syslog_rules.xml + pix_rules.xml + named_rules.xml + smbd_rules.xml + vsftpd_rules.xml + pure-ftpd_rules.xml + proftpd_rules.xml + hordeimp_rules.xml + web_rules.xml + apache_rules.xml + ids_rules.xml + squid_rules.xml + firewall_rules.xml + netscreenfw_rules.xml + postfix_rules.xml + sendmail_rules.xml + imapd_rules.xml + spamd_rules.xml + msauth_rules.xml + policy_rules.xml + attack_rules.xml + + + + * Build links to the original rules files under the signatures directory + +/var/openarmor# COUNT=0; for i in `cat rules.txt`; do + (( COUNT = COUNT + 1)) ; + ln -s ../repository/$i `printf "signatures/%02d%s" $COUNT $i`; +done + + + + * If you wish to alterate a rule you should remove the link of the file from signature where XX denotes the two digits number prefixing the name of the file. + +/var/openarmor# unlink signatures/XXattack_rules.xml + + + + * Copy the file to be modified + +/var/openarmor# cp repository/attack_rules.xml signatures/XXattack_rules.xml + + + + * Edit your file. + + * write your own rules file under the directory user_signatures + +/var/openarmor# cat user_signatures/user_defined.xml + + + Accepted publickey + Accepted publickey bypass + + + + + * List the rules under signature + +/var/openarmor# ls -l signatures/ +total 0 +lrwxrwxrwx 1 root root 27 2006-07-24 23:37 01pam_rules.xml -> ../repository/pam_rules.xml +lrwxrwxrwx 1 root root 28 2006-07-24 23:37 02sshd_rules.xml -> ../repository/sshd_rules.xml +lrwxrwxrwx 1 root root 31 2006-07-24 23:37 03telnetd_rules.xml -> ../repository/telnetd_rules.xml +lrwxrwxrwx 1 root root 30 2006-07-24 23:37 04syslog_rules.xml -> ../repository/syslog_rules.xml +lrwxrwxrwx 1 root root 27 2006-07-24 23:37 05pix_rules.xml -> ../repository/pix_rules.xml +lrwxrwxrwx 1 root root 29 2006-07-24 23:37 06named_rules.xml -> ../repository/named_rules.xml +lrwxrwxrwx 1 root root 28 2006-07-24 23:37 07smbd_rules.xml -> ../repository/smbd_rules.xml +lrwxrwxrwx 1 root root 30 2006-07-24 23:37 08vsftpd_rules.xml -> ../repository/vsftpd_rules.xml +lrwxrwxrwx 1 root root 33 2006-07-24 23:37 09pure-ftpd_rules.xml -> ../repository/pure-ftpd_rules.xml +lrwxrwxrwx 1 root root 31 2006-07-24 23:37 10proftpd_rules.xml -> ../repository/proftpd_rules.xml +lrwxrwxrwx 1 root root 32 2006-07-24 23:37 11hordeimp_rules.xml -> ../repository/hordeimp_rules.xml +lrwxrwxrwx 1 root root 27 2006-07-24 23:37 12web_rules.xml -> ../repository/web_rules.xml +lrwxrwxrwx 1 root root 30 2006-07-24 23:37 13apache_rules.xml -> ../repository/apache_rules.xml +lrwxrwxrwx 1 root root 27 2006-07-24 23:37 14ids_rules.xml -> ../repository/ids_rules.xml +lrwxrwxrwx 1 root root 29 2006-07-24 23:37 15squid_rules.xml -> ../repository/squid_rules.xml +lrwxrwxrwx 1 root root 32 2006-07-24 23:37 16firewall_rules.xml -> ../repository/firewall_rules.xml +lrwxrwxrwx 1 root root 35 2006-07-24 23:37 17netscreenfw_rules.xml -> ../repository/netscreenfw_rules.xml +lrwxrwxrwx 1 root root 31 2006-07-24 23:37 18postfix_rules.xml -> ../repository/postfix_rules.xml +lrwxrwxrwx 1 root root 32 2006-07-24 23:37 19sendmail_rules.xml -> ../repository/sendmail_rules.xml +lrwxrwxrwx 1 root root 29 2006-07-24 23:37 20imapd_rules.xml -> ../repository/imapd_rules.xml +lrwxrwxrwx 1 root root 29 2006-07-24 23:37 21spamd_rules.xml -> ../repository/spamd_rules.xml +lrwxrwxrwx 1 root root 30 2006-07-24 23:37 22msauth_rules.xml -> ../repository/msauth_rules.xml +lrwxrwxrwx 1 root root 30 2006-07-24 23:37 23policy_rules.xml -> ../repository/policy_rules.xml +lrwxrwxrwx 1 root root 30 2006-07-24 23:37 24attack_rules.xml -> ../repository/attack_rules.xml + + + + * Compile the alerts into a monolitic rule file. + +/var/openarmor# perl contrib/compile_alerts.pl --user-signatures /var/openarmor/user_signatures --signatures \ +/var/openarmor/signatures --rules-config /var/openarmor/etc/rules_config.xml > rules/rules_openarmor.xml +Adding /var/openarmor/etc/rules_config.xml +Adding /var/openarmor/user_signatures/user_defined_rules.xml +Adding /var/openarmor/signatures/01pam_rules.xml +Adding /var/openarmor/signatures/02sshd_rules.xml +Adding /var/openarmor/signatures/03telnetd_rules.xml +Adding /var/openarmor/signatures/04syslog_rules.xml +Adding /var/openarmor/signatures/05pix_rules.xml +Adding /var/openarmor/signatures/06named_rules.xml +Adding /var/openarmor/signatures/07smbd_rules.xml +Adding /var/openarmor/signatures/08vsftpd_rules.xml +Adding /var/openarmor/signatures/09pure-ftpd_rules.xml +Adding /var/openarmor/signatures/10proftpd_rules.xml +Adding /var/openarmor/signatures/11hordeimp_rules.xml +Adding /var/openarmor/signatures/12web_rules.xml +Adding /var/openarmor/signatures/13apache_rules.xml +Adding /var/openarmor/signatures/14ids_rules.xml +Adding /var/openarmor/signatures/15squid_rules.xml +Adding /var/openarmor/signatures/16firewall_rules.xml +Adding /var/openarmor/signatures/17netscreenfw_rules.xml +Adding /var/openarmor/signatures/18postfix_rules.xml +Adding /var/openarmor/signatures/19sendmail_rules.xml +Adding /var/openarmor/signatures/20imapd_rules.xml +Adding /var/openarmor/signatures/21spamd_rules.xml +Adding /var/openarmor/signatures/22msauth_rules.xml +Adding /var/openarmor/signatures/23policy_rules.xml +Adding /var/openarmor/signatures/24attack_rules.xml +processing: /var/openarmor/etc/rules_config.xml +processing: /var/openarmor/user_signatures/user_defined_rules.xml +processing: /var/openarmor/signatures/01pam_rules.xml +processing: /var/openarmor/signatures/02sshd_rules.xml +processing: /var/openarmor/signatures/03telnetd_rules.xml +processing: /var/openarmor/signatures/04syslog_rules.xml +processing: /var/openarmor/signatures/05pix_rules.xml +processing: /var/openarmor/signatures/06named_rules.xml +processing: /var/openarmor/signatures/07smbd_rules.xml +processing: /var/openarmor/signatures/08vsftpd_rules.xml +processing: /var/openarmor/signatures/09pure-ftpd_rules.xml +processing: /var/openarmor/signatures/10proftpd_rules.xml +processing: /var/openarmor/signatures/11hordeimp_rules.xml +processing: /var/openarmor/signatures/12web_rules.xml +processing: /var/openarmor/signatures/13apache_rules.xml +processing: /var/openarmor/signatures/14ids_rules.xml +processing: /var/openarmor/signatures/15squid_rules.xml +processing: /var/openarmor/signatures/16firewall_rules.xml +processing: /var/openarmor/signatures/17netscreenfw_rules.xml +processing: /var/openarmor/signatures/18postfix_rules.xml +processing: /var/openarmor/signatures/19sendmail_rules.xml +processing: /var/openarmor/signatures/20imapd_rules.xml +processing: /var/openarmor/signatures/21spamd_rules.xml +processing: /var/openarmor/signatures/22msauth_rules.xml +processing: /var/openarmor/signatures/23policy_rules.xml +processing: /var/openarmor/signatures/24attack_rules.xml + + + + * Now you can start again openarmor + +/var/openarmor#/etc/init.d/openarmor start + Starting openarmor Starting openarmor HIDS v0.9 (by Daniel B. Cid)... + Started openarmor-maild... + Started openarmor-execd... + Started openarmor-analysisd... + Started openarmor-logcollector... + Started openarmor-remoted... + Started openarmor-syscheckd... + Completed. + + + +Extract of openarmor.conf with the modified rules tag + +/var/openarmor# cat etc/openarmor.conf +... + + rules_openarmor.xml + +... + + + diff --git a/contrib/config2xml b/contrib/config2xml new file mode 100644 index 000000000..561084bba --- /dev/null +++ b/contrib/config2xml @@ -0,0 +1,194 @@ +#!/usr/bin/perl -w + +# +# +# config2xml +# +# Written by: Charlie Heselton (gentuxx@gmail.com) +# Date: 08/22/2006 +# Version: 0.1 +# +# Description: openarmor-HIDS uses XML for it's configuration +# and rules files. This script allows a user to use a +# more traditional "key = value" format and convert it +# to the XML required by openarmor. +# +# +require 5.006; +use strict; +use Getopt::Std; + +my (%opts, %config); +getopts('f:', \%opts); + +my $current_line = 0; +if ($opts{'f'}) { + # open the "traditional" file and parse the contents. + open CONF, $opts{'f'} or die "Couldn't open input config file ($opts{'f'}): $! \n"; + while () { + $current_line++; + # skip commented or blank lines + next if (/^#/); + next if (/^$/); + chomp; + # strip out any double quotes + #s/\"//g; + # strip out spaces or tabs + #s/(\s+|\t+)//g; + my ($key, $value); + #print STDERR "DEBUG: \$\_ ===> $_\n"; + if (/^\s*(\S+)\s*\=\s*\"?([^=]+)\"?/) { + $key = $1; $value = $2; + } else { + die "Config error! Found an extra equals sign (=) in line $current_line\. Input file not converted!\n"; + } + # the keys below will be repeated, but if the value is assigned initially, + # then the script fails when unwrapping the hash. + # key/value pairs that shouldn't be repeated throw a config error if they are repeated. + if ($key =~ /monitor_file|rules_include|active_response_command/) { + push @{$config{$key}}, $value; + } else { + if (exists($config{$key})) { die "$key has already been specified in the config file and can only be used once. Input file not converted!\n"; } + $config{$key} = $value; + } + } + close CONF; +} else { + die "No input file specified.\n"; +} +undef $current_line; + +# strip out any double-quotes +# this is handled for all the rest of the key/value pairs when the input file is initially parsed +foreach my $key ( qw/ active_response_command / ) { foreach ( @{$config{$key}} ) { s!\"!!g; } } +# separate the "complex" options into arrays +my @whitelisted = split(/\,/, $config{'whitelist_ips'}); +my @ignored = split(/\,/, $config{'ignore'}); + +# Write the xml file. Easiest way is just to be deliberate. Not the most elegant solution, but it should work. +print < + + + + $config{'email_notify'} + $config{'email_addr'} + $config{'smtp_server'} + $config{'email_from'} +END + +foreach my $wip ( sort( @whitelisted ) ) { + print " $wip\n"; +} + +print " \n\n"; +print " \n"; + +foreach my $rulesfile ( sort( @{$config{'rules_include'}} ) ) { + print " $rulesfile\n"; +} + +print < + + + + $config{'frequency'} + + + $config{'directories_check_all'} + + +END + +foreach my $ignored ( @ignored ) { + print " $ignored\n"; +} + +print < + + + $config{'rootkit_files_db'} + $config{'rootkit_trojans_db'} + + +END + +if ( exists($config{'remote'}) ) { + print " \n"; + if ((exists($config{'connection_type'})) && ($config{'connection_type'} eq 'secure')) { + print " $config{'connection_type'}\n"; + } + print " \n"; +} + +print < + $config{'log_alert_level'} + $config{'email_alert_level'} + + +END + +if ( exists($config{'active_response'}) ) { # should always be true + if ($config{'active_response'} eq 'disabled') { + print " \n yes\n \n\n"; + } else { + # Could use some comments/insight here, since I don't use the active response features. + foreach my $cmd ( sort(@{$config{'active-response-command'}}) ) { + my ( $name, $exe, $expect, $timeout ) = split(/\,/, $cmd); + print < + $name + $exe + $expect + $timeout + + +END + } + + print < + + + host-deny + local + 6 + 600 + + + + + firewall-drop + local + 6 + 600 + + + + +END + } +} + +foreach my $file ( sort( @{$config{'monitor_file'}} ) ) { + my ($fileloc, $fformat) = split(/\,/, $file); + print " \n"; + print " $fformat\n"; + print " $fileloc\n"; + print " \n"; +} + +print "\n"; diff --git a/contrib/debian-packages/Readme.txt b/contrib/debian-packages/Readme.txt new file mode 100644 index 000000000..5cddb2fc1 --- /dev/null +++ b/contrib/debian-packages/Readme.txt @@ -0,0 +1,28 @@ +openarmor-debian +============ + +openarmor is an Open Source Host-based Intrusion Detection System that performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response. + +These are the files used to create openarmor-HIDS version 2.8 debian packages, the ones included both in theopenarmor.org website and in WAZUH repository. You can find these packages at: + +http://www.theopenarmor.org/?page_id=19 + +or directly at: http://openarmor.wazuh.com/repos/apt/ + +There are two different packages that can be built with these files: + +* openarmor-hids: Package that includes both the server and the agent. +* openarmor-hids-agent: Package that includes just the agent. + +Each one of the subdirectories includes: + +* Patches +* Debian control files: changelog, compat, control, copyright, lintian-overrides, postinst, postrm, preinst, rules + +Additionally a script, ```generate_openarmor.sh```, is included to generate the Debian packages for Jessie, Sid and Wheezy Debian distributions, both for i386 and amd64 architectures. This script uses Pbuilder to build the packages, and uploads those to an APT repository, setup with Reprepro. + +For more details on how to create Debian Packages and an APT repository you can check my post at: + +http://santi-bassett.blogspot.com/2014/07/setting-up-apt-repository-with-reprepro.html + +Please don't hesitate to contribute (preferably via pull requests) to improve these packages. diff --git a/contrib/debian-packages/generate_openarmor.sh b/contrib/debian-packages/generate_openarmor.sh new file mode 100644 index 000000000..a6c9cd6d1 --- /dev/null +++ b/contrib/debian-packages/generate_openarmor.sh @@ -0,0 +1,459 @@ +#!/bin/bash +# Program to build and sign debian packages, and upload those to a public reprepro repository. +# Copyright (c) 2015 Santiago Bassett + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# +# CONFIGURATION VARIABLES +# + +openarmor_version='3.6.0' +source_file="openarmor-hids-${openarmor_version}.tar.gz" +#packages=(openarmor-hids openarmor-hids-agent) # only options available +packages=(openarmor-hids-agent) + +# codenames=(sid jessie wheezy precise trusty utopic) +codenames=(bionic) + +# For Debian use: sid, jessie or wheezy (hardcoded in update_changelog function) +# For Ubuntu use: lucid, precise, trusty or utopic +codenames_ubuntu=(precise trusty xenial bionic focal) +codenames_debian=(sid jessie wheezy) + +# architectures=(amd64 i386) only options available +architectures=(arm64) + +# Debian files +debian_files_path="/home/ubuntu/debian_files" + +# Setting up logfile +scriptpath=$( cd $(dirname $0) ; pwd -P ) +logfile=$scriptpath/openarmor_packages.log + + +# +# Function to write to LOG_FILE +# +write_log() +{ + if [ ! -e "$logfile" ] ; then + touch "$logfile" + fi + while read text + do + local logtime=`date "+%Y-%m-%d %H:%M:%S"` + echo $logtime": $text" | tee -a $logfile; + done +} + + +# +# Check if element is in an array +# Arguments: element array +# +contains_element() { + local e + for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done + return 1 +} + + +# +# Show help function +# +show_help() +{ + echo " + This tool can be used to generate openarmor packages for Ubuntu and Debian. + + CONFIGURATION: The script is currently configured with the following variables: + * Packages: ${packages[*]}. + * Distributions: ${codenames[*]}. + * Architectures: ${architectures[*]}. + * openarmor version: ${openarmor_version}. + * Source file: ${source_file}. + * Signing key: ${signing_key}. + + USAGE: Command line arguments available: + -h | --help Displays this help. + -u | --update Updates chroot environments. + -d | --download Downloads source file and prepares source directories. + -b | --build Builds deb packages. + -s | --sync Synchronizes with the apt-get repository. + " +} + + +# +# Reads latest package version from changelog file +# Argument: changelog_file +# +read_package_version() +{ + if [ ! -e "$1" ] ; then + echo "Error: Changelog file $1 does not exist" | write_log + exit 1 + fi + local regex="^openarmor-hids[A-Za-z-]* \([0-9]+.*[0-9]*.*[0-9]*-([0-9]+)[A-Za-z]*\)" + while read line + do + if [[ $line =~ $regex ]]; then + package_version="${BASH_REMATCH[1]}" + break + fi + done < $1 + local check_regex='^[0-9]+$' + if ! [[ ${package_version} =~ ${check_regex} ]]; then + echo "Error: Package version could not be read from $1" | write_log + exit 1 + fi +} + + +# +# Updates changelog file with new codename, date and debdist. +# Arguments: changelog_file codename +# +update_changelog() +{ + local changelog_file=$1 + local changelog_file_tmp="${changelog_file}.tmp" + local codename=$2 + + if [ ! -e "$1" ] ; then + echo "Error: Changelog file $1 does not exist" | write_log + exit 1 + fi + + local check_codenames=( ${codenames_debian[*]} ${codenames_ubuntu[*]} ) + if ! contains_element $codename ${check_codenames[*]} ; then + echo "Error: Codename $codename not contained in codenames for Debian or Ubuntu" | write_log + exit 1 + fi + + # For Debian + if [ $codename = "sid" ]; then + local debdist="unstable" + elif [ $codename = "jessie" ]; then + local debdist="testing" + elif [ $codename = "wheezy" ]; then + local debdist="stable" + fi + + # For Ubuntu + if contains_element $codename ${codenames_ubuntu[*]} ; then + local debdist=$codename + fi + + # Modifying file + local changelogtime=$(date -R) + local last_date_changed=0 + + local regex1="^(openarmor-hids[A-Za-z-]* \([0-9]+.*[0-9]*.*[0-9]*-[0-9]+)[A-Za-z]*\)" + local regex2="( -- [[:alnum:]]*[^>]*> )[[:alnum:]]*," + + if [ -f ${changelog_file_tmp} ]; then + rm -f ${changelog_file_tmp} + fi + touch ${changelog_file_tmp} + + IFS='' #To preserve line leading whitespaces + while read line + do + if [[ $line =~ $regex1 ]]; then + line="${BASH_REMATCH[1]}$codename) $debdist; urgency=low" + fi + if [[ $line =~ $regex2 ]] && [ $last_date_changed -eq 0 ]; then + line="${BASH_REMATCH[1]}$changelogtime" + last_date_changed=1 + fi + echo "$line" >> ${changelog_file_tmp} + done < ${changelog_file} + + mv ${changelog_file_tmp} ${changelog_file} +} + + +# +# Update chroot environments +# +update_chroots() +{ + for codename in ${codenames[@]} + do + for arch in ${architectures[@]} + do + if [ -f /var/cache/pbuilder/$codename-$arrch-base.tgz ]; then + echo "Updating chroot environment: ${codename}-${arch}" | write_log + if sudo DIST=$codename ARCH=$arch pbuilder update --configfile $scriptpath/pbuilderrc ; then + echo "Successfully updated chroot environment: ${codename}-${arch}" | write_log + else + echo "Error: Problem detected updating chroot environment: ${codename}-${arch}" | write_log + exit 1 + fi + else + echo "Creating chroot environment: ${codename}-${arch}" | write_log + if sudo DIST=$codename ARCH=$arch pbuilder create --configfile $scriptpath/pbuilderrc; then + echo "Successfully created chroot environment: ${codename}-${arch}" | write_log + else + echo "Error: Problem detected creating chroot environment: ${codename}-${arch}" | write_log + exit 1 + fi + fi + done + done +} + + +# +# Downloads packages and prepare source directories. +# This is needed before building the packages. +# +download_source() +{ + cd ${scriptpath} + + # Checking that Debian files exist for this version + for package in ${packages[*]} + do + if [ ! -d ${debian_files_path}/${openarmor_version}/$package/debian ]; then + echo "Error: Couldn't find debian files directory for $package, version ${openarmor_version}" | write_log + exit 1 + fi + done + + # Downloading file + if wget -O $scriptpath/${source_file} -U openarmor https://github.com/openarmor/openarmor-hids/archive/${openarmor_version}.tar.gz ; then + echo "Successfully downloaded source file ${source_file} from theopenarmor.org" | write_log + else + echo "Error: File ${source_file} was could not be downloaded" | write_log + exit 1 + fi + + # Uncompressing files + tmp_directory=$(echo ${source_file} | sed -e 's/.tar.gz$//') + if [ -d ${scriptpath}/${tmp_directory} ]; then + echo " + Deleting previous directory ${scriptpath}/${tmp_directory}" | write_log + sudo rm -rf ${scriptpath}/${tmp_directory} + fi + tar -xvzf ${scriptpath}/${source_file} + if [ ! -d ${scriptpath}/${tmp_directory} ]; then + echo "Error: Couldn't find uncompressed directory, named ${tmp_directory}" | write_log + exit 1 + fi + + # Organizing directories structure + for package in ${packages[*]} + do + if [ -d ${scriptpath}/$package ]; then + echo " + Deleting previous source directory ${scriptpath}/$package" | write_log + sudo rm -rf ${scriptpath}/$package + fi + mkdir $scriptpath/$package + cp -pr $scriptpath/${tmp_directory} $scriptpath/$package/$package-${openarmor_version} + cp -p $scriptpath/${source_file} $scriptpath/$package/${package}_${openarmor_version}.orig.tar.gz + cp -pr ${debian_files_path}/${openarmor_version}/$package/debian $scriptpath/$package/${package}-${openarmor_version}/debian + done + rm -rf $scriptpath/${tmp_directory} + + echo "The packages directories for ${packages[*]} version ${openarmor_version} have been successfully prepared." | write_log +} + + +# +# Build packages +# +build_packages() +{ + +for package in ${packages[@]} +do + for codename in ${codenames[@]} + do + for arch in ${architectures[@]} + do + + echo "Building Debian package ${package} ${codename}-${arch}" | write_log + + local source_path="$scriptpath/${package}/${package}-${openarmor_version}" + local changelog_file="${source_path}/debian/changelog" + if [ ! -f ${changelog_file} ] ; then + echo "Error: Couldn't find changelog file for ${package}-${openarmor_version}" | write_log + exit 1 + fi + + # Updating changelog file with new codename, date and debdist. + if update_changelog ${changelog_file} ${codename} ; then + echo " + Changelog file ${changelog_file} updated for $package ${codename}-${arch}" | write_log + else + echo "Error: Changelog file ${changelog_file} for $package ${codename}-${arch} could not be updated" | write_log + exit 1 + fi + + # Setting up global variable package_version, used for deb_file and changes_file + read_package_version ${changelog_file} + local deb_file="${package}_${openarmor_version}-${package_version}${codename}_${arch}.deb" + local changes_file="${package}_${openarmor_version}-${package_version}${codename}_${arch}.changes" + local dsc_file="${package}_${openarmor_version}-${package_version}${codename}.dsc" + local results_dir="/var/cache/pbuilder/${codename}-${arch}/result/${package}" + local base_tgz="/var/cache/pbuilder/${codename}-${arch}-base.tgz" + local cache_dir="/var/cache/pbuilder/${codename}-${arch}/aptcache" + + # Creating results directory if it does not exist + if [ ! -d ${results_dir} ]; then + sudo mkdir -p ${results_dir} + fi + + # Building the package + cd ${source_path} + if sudo DIST=$codename ARCH=$arch /usr/bin/pdebuild --configfile $scriptpath/pbuilderrc --use-pdebuild-internal --architecture ${arch} --buildresult ${results_dir} -- --basetgz \ + ${base_tgz} --distribution ${codename} --architecture ${arch} --aptcache ${cache_dir} --override-config ; then + echo " + Successfully built Debian package ${package} ${codename}-${arch}" | write_log + else + echo "Error: Could not build package $package ${codename}-${arch}" | write_log + exit 1 + fi + + # Checking that resulting debian package exists + if [ ! -f ${results_dir}/${deb_file} ] ; then + echo "Error: Could not find ${results_dir}/${deb_file}" | write_log + exit 1 + fi + + # Checking that package has at least 50 files to confirm it has been built correctly + local files=$(sudo /usr/bin/dpkg --contents ${results_dir}/${deb_file} | wc -l) + if [ "${files}" -lt "50" ]; then + echo "Error: Package ${package} ${codename}-${arch} contains only ${files} files" | write_log + echo "Error: Check that the Debian package has been built correctly" | write_log + exit 1 + else + echo " + Package ${results_dir}/${deb_file} ${codename}-${arch} contains ${files} files" | write_log + fi + + echo "Successfully built Debian package ${package} ${codename}-${arch}" | write_log + + done + done +done +} + +# Synchronizes with the external repository, uploading new packages and ubstituting old ones. +sync_repository() +{ +for package in ${packages[@]} +do + for codename in ${codenames[@]} + do + for arch in ${architectures[@]} + do + + # Reading package version from changelog file + local source_path="$scriptpath/${package}/${package}-${openarmor_version}" + local changelog_file="${source_path}/debian/changelog" + if [ ! -f ${changelog_file} ] ; then + echo "Error: Couldn't find ${changelog_file} for package ${package} ${codename}-${arch}" | write_log + exit 1 + fi + + # Setting up global variable package_version, used for deb_file and changes_file. + read_package_version ${changelog_file} + local deb_file="${package}_${openarmor_version}-${package_version}${codename}_${arch}.deb" + local changes_file="${package}_${openarmor_version}-${package_version}${codename}_${arch}.changes" + local results_dir="/var/cache/pbuilder/${codename}-${arch}/result/${package}" + if [ ! -f ${results_dir}/${deb_file} ] || [ ! -f ${results_dir}/${changes_file} ] ; then + echo "Error: Couldn't find ${deb_file} or ${changes_file}" | write_log + exit 1 + fi + + # Uploading package to repository + cd ${results_dir} + echo "Uploading package ${changes_file} for ${codename} to openarmor repository" | write_log + if sudo /usr/bin/dupload --nomail -f --to openarmor-repository ${changes_file} ; then + echo " + Successfully uploaded package ${changes_file} for ${codename} to openarmor repository" | write_log + else + echo "Error: Could not upload package ${changes_file} for ${codename} to the repository" | write_log + exit 1 + fi + + # Checking if it is an Ubuntu package + if contains_element $codename ${codenames_ubuntu[*]} ; then + local is_ubuntu=1 + else + local is_ubuntu=0 + fi + + # Moving package to the right directory at the openarmor apt repository server + echo " + Adding package /opt/incoming/${deb_file} to server repository for ${codename} distribution" | write_log + if [ $is_ubuntu -eq 1 ]; then + remove_package="cd /var/www/repos/apt/ubuntu; reprepro -A ${arch} remove ${codename} ${package}" + include_package="cd /var/www/repos/apt/ubuntu; reprepro includedeb ${codename} /opt/incoming/${deb_file}" + else + remove_package="cd /var/www/repos/apt/debian; reprepro -A ${arch} remove ${codename} ${package}" + include_package="cd /var/www/repos/apt/debian; reprepro includedeb ${codename} /opt/incoming/${deb_file}" + fi + + echo "Successfully added package ${deb_file} to server repository for ${codename} distribution" | write_log + done + done +done +} + + +# If there are no arguments, display help +if [ $# -eq 0 ]; then + show_help + exit 0 +fi + +# Reading command line arguments +while [[ $# > 0 ]] +do +key="$1" +shift + +case $key in + -h|--help) + show_help + exit 0 + ;; + -u|--update) + update_chroots + shift + exit 0 + ;; + -d|--download) + download_source + shift + exit 0 + ;; + -b|--build) + build_packages + shift + exit 0 + ;; + -s|--sync) + sync_repository + shift + ;; + *) + echo "Unknown command line argument." + show_help + exit 0 + ;; + esac +done + +# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/changelog b/contrib/debian-packages/openarmor-hids-agent/debian/changelog new file mode 100644 index 000000000..9d7d049f8 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/changelog @@ -0,0 +1,18 @@ +openarmor-hids-agent (3.5.0-1) unstable; urgency=medium + + * support arm64 package + + -- Santiago Bassett Wed, 08 Jan 2020 19:45:23 +0000 + +openarmor-hids-agent (2.8.2-2) unstable; urgency=low + + * Set openarmor user home to /var/openarmor/ + * Added linux-libc-dev build dependency to Debian control file + + -- Santiago Bassett Mon, 15 Jun 2015 08:43:10 +0000 + +openarmor-hids-agent (2.8.2-1) unstable; urgency=low + + * 2.8.2 Initial release. Includes several fixes, and patch for CVE-2015-3222 + + -- Santiago Bassett Mon, 15 Jun 2015 08:43:10 +0000 diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/compat b/contrib/debian-packages/openarmor-hids-agent/debian/compat new file mode 100644 index 000000000..7f8f011eb --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/compat @@ -0,0 +1 @@ +7 diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/conffiles b/contrib/debian-packages/openarmor-hids-agent/debian/conffiles new file mode 100644 index 000000000..17a44cc26 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/conffiles @@ -0,0 +1 @@ +/var/openarmor/etc/openarmor.conf diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/control b/contrib/debian-packages/openarmor-hids-agent/debian/control new file mode 100644 index 000000000..244f2b03d --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/control @@ -0,0 +1,15 @@ +Source: openarmor-hids-agent +Section: admin +Priority: extra +Maintainer: Santiago Bassett +Build-Depends: debhelper (>= 7.0.50~), libssl-dev, linux-libc-dev, libpcre2-dev, libevent-dev +Standards-Version: 3.8.4 +Homepage: http://www.theopenarmor.org + +Package: openarmor-hids-agent +Architecture: any +Depends: ${shlibs:Depends}, libc6 (>= 2.7), libssl1.0.0, debconf, libevent-2.0-5, libpcre2-8-0, zlib1g +Conflicts: openarmor-hids +Description: openarmor Agent - Host Based Intrusion Detection System + openarmor HIDS for log analysis, integrity checking, rootkits detection and + active response. This package includes the server and the agent. diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/copyright b/contrib/debian-packages/openarmor-hids-agent/debian/copyright new file mode 100644 index 000000000..555c197dd --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/copyright @@ -0,0 +1,34 @@ +This work was packaged for Debian by: + + Santiago Bassett on Fri, 29 Nov 2013 03:11:44 +0000 + +It was downloaded from: + + http://www.theopenarmor.org + +Upstream Authors: + + dcid@dcid.me + Jia-BingJB_Cheng@trendmicro.com + vichargrave@gmail.com + openarmor@michaelstarks.com + ddpbsd@gmail.com + scott@atomicorp.com + brad.lhotsky@gmail.com + jeremy@jeremyrossi.com + santiago.bassett@gmail.com + +Copyright: + + GNU General Public License version 2. + +License: + + GNU General Public License version 2. + +The Debian packaging is: + + Copyright (C) 2014 Santiago Bassett + +and is licensed under the GPL version 2, +see "/usr/share/common-licenses/GPL-2". diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/openarmor-hids-agent.lintian-overrides b/contrib/debian-packages/openarmor-hids-agent/debian/openarmor-hids-agent.lintian-overrides new file mode 100644 index 000000000..4c30cd52b --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/openarmor-hids-agent.lintian-overrides @@ -0,0 +1,9 @@ +openarmor-hids-agent: embedded-library +openarmor-hids-agent: embedded-zlib +openarmor-hids-agent: possible-gpl-code-linked-with-openssl +openarmor-hids-agent: new-package-should-close-itp-bug +openarmor-hids-agent: possibly-insecure-handling-of-tmp-files-in-maintainer-script +openarmor-hids-agent: non-standard-dir-in-var +openarmor-hids-agent: file-in-unusual-dir +openarmor-hids-agent: hardening-no-fortify-functions +openarmor-hids-agent: hardening-no-relro diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/patches/01_makefile.patch b/contrib/debian-packages/openarmor-hids-agent/debian/patches/01_makefile.patch new file mode 100644 index 000000000..21d3bb5cd --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/patches/01_makefile.patch @@ -0,0 +1,59 @@ +Index: openarmor-hids-agent-2.8.2/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ openarmor-hids-agent-2.8.2/Makefile 2015-06-15 03:15:51.083134760 +0000 +@@ -0,0 +1,54 @@ ++# ++# Santiago Bassett ++# 06/15/2015 ++# ++ ++DESTDIR=/ ++DIR=$(DESTDIR)/var/openarmor/ ++openarmor_INIT=$(DIR)/etc/openarmor-init.conf ++CEXTRA="-DCLIENT" ++all: ++ echo "CEXTRA=$(CEXTRA)" >> src/Config.OS ++ (cd src; make TARGET=agent PCRE2_SYSTEM=yes) ++ ++clean: ++ rm bin/* || /bin/true ++ chmod 750 $(DIR) || /bin/true ++ chmod 750 $(DIR)/* || /bin/true ++ (cd src; make clean) ++ rm -f src/Config.OS ++ rm -f src/analysisd/compiled_rules/compiled_rules.h ++ rm -f src/isbigendian.c ++ rm -f src/analysisd/openarmor-makelists ++ rm -f src/analysisd/openarmor-logtest ++ rm -f src/isbigendian ++ ++install: ++ mkdir -p $(DIR) ++ (cd $(DIR); mkdir -p logs bin queue queue/openarmor queue/alerts queue/syscheck queue/diff queue/rids) ++ (cd $(DIR); mkdir -p var var/run etc etc/init.d etc/shared active-response active-response/bin agentless .ssh) ++ cp -pr src/rootcheck/db/*.txt $(DIR)/etc/shared/ ++ chmod -x $(DIR)/etc/shared/*.txt ++ cp -pr etc/internal_options.conf $(DIR)/etc/ ++ chmod -x $(DIR)/etc/internal_options.conf ++ cp -pr etc/local_internal_options.conf $(DIR)/etc/ > /dev/null 2>&1 || /bin/true ++ cp -pr etc/client.keys $(DIR)/etc/ > /dev/null 2>&1 ||/bin/true ++ cp -pr src/agentlessd/scripts/* $(DIR)/agentless/ ++ cp -pr src/openarmor-agentd ${DIR}/bin/ ++ cp -pr src/agent-auth ${DIR}/bin/ ++ cp -pr src/openarmor-logcollector ${DIR}/bin/ ++ cp -pr src/openarmor-syscheckd ${DIR}/bin/ ++ cp -pr src/openarmor-execd ${DIR}/bin/ ++ cp -pr src/init/openarmor-client.sh ${DIR}/bin/openarmor-control ++ cp -pr src/manage_agents ${DIR}/bin/ ++ cp -pr contrib/util.sh ${DIR}/bin/ ++ sh src/init/fw-check.sh execute > /dev/null ++ cp -pr active-response/*.sh ${DIR}/active-response/bin/ ++ cp -pr active-response/firewalls/*.sh ${DIR}/active-response/bin/ ++ cp -pr etc/openarmor-agent.conf $(DIR)/etc/openarmor.conf ++ chmod -x $(DIR)/etc/openarmor.conf ++ cp -p src/init/openarmor-hids-debian.init $(DIR)/etc/init.d/openarmor ++ echo "DIRECTORY=\"/var/openarmor\"" > $(openarmor_INIT) ++ echo "VERSION=\"v3.5.0\"" >> $(openarmor_INIT) ++ echo "DATE=\"`date`\"" >> $(openarmor_INIT) ++ echo "TYPE=\"agent\"" >> $(openarmor_INIT) diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/patches/02_openarmor-agent.conf.patch b/contrib/debian-packages/openarmor-hids-agent/debian/patches/02_openarmor-agent.conf.patch new file mode 100644 index 000000000..6b675ae23 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/patches/02_openarmor-agent.conf.patch @@ -0,0 +1,58 @@ +--- a/etc/openarmor-agent.conf.orig 2020-01-19 03:45:09.184090231 +0900 ++++ b/etc/openarmor-agent.conf 2020-01-19 03:44:15.844760722 +0900 +@@ -29,16 +29,12 @@ + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt ++ /var/openarmor/etc/shared/system_audit_rcl.txt + + + + syslog +- /var/log/messages +- +- +- +- syslog +- /var/log/authlog ++ /var/log/syslog + + + +@@ -48,26 +44,31 @@ + + + syslog +- /var/log/secure ++ /var/log/dpkg.log + + + + syslog +- /var/log/xferlog ++ /var/log/kern.log + + ++ ++ + diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/patches/series b/contrib/debian-packages/openarmor-hids-agent/debian/patches/series new file mode 100644 index 000000000..1afdc0fd1 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/patches/series @@ -0,0 +1,2 @@ +02_openarmor-agent.conf.patch +01_makefile.patch diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/postinst b/contrib/debian-packages/openarmor-hids-agent/debian/postinst new file mode 100644 index 000000000..ae1ddaa66 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/postinst @@ -0,0 +1,153 @@ +#!/bin/sh +# postinst script for openarmor-hids +# Santiago Bassett +# 03/25/2014 + +set -e + +case "$1" in + configure) + + DIR="/var/openarmor/" + USER="openarmor" + GROUP="openarmor" + openarmor_HIDS_TMP_DIR="/tmp/openarmor-hids" + + OSMYSHELL="/sbin/nologin" + if [ ! -f ${OSMYSHELL} ]; then + if [ -f "/bin/false" ]; then + OSMYSHELL="/bin/false" + fi + fi + + if ! getent group | grep -q "^openarmor" + then + addgroup --system openarmor + fi + if ! getent passwd | grep -q "^openarmor" + then + adduser --system --home ${DIR} --shell ${OSMYSHELL} --ingroup ${GROUP} ${USER} > /dev/null 2>&1 + fi + + # Default for all directories + chmod -R 550 ${DIR} + chown -R root:${GROUP} ${DIR} + + # To the openarmor queue (default for agentd to read) + chown -R ${USER}:${GROUP} ${DIR}/queue/openarmor + chmod -R 770 ${DIR}/queue/openarmor + + # For the logging user + chown -R ${USER}:${GROUP} ${DIR}/logs + chmod -R 750 ${DIR}/logs + chmod -R 775 ${DIR}/queue/rids + touch ${DIR}/logs/openarmor.log + chown ${USER}:${GROUP} ${DIR}/logs/openarmor.log + chmod 664 ${DIR}/logs/openarmor.log + + chown -R ${USER}:${GROUP} ${DIR}/queue/diff + chmod -R 750 ${DIR}/queue/diff + chmod 740 ${DIR}/queue/diff/* > /dev/null 2>&1 || true + + # For the etc dir + chmod 550 ${DIR}/etc + chown -R root:${GROUP} ${DIR}/etc + if [ -f /etc/localtime ]; then + cp -pL /etc/localtime ${DIR}/etc/; + chmod 555 ${DIR}/etc/localtime + chown root:${GROUP} ${DIR}/etc/localtime + fi + + if [ -f /etc/TIMEZONE ]; then + cp -p /etc/TIMEZONE ${DIR}/etc/; + chmod 555 ${DIR}/etc/TIMEZONE + fi + + # More files + chown root:${GROUP} ${DIR}/etc/internal_options.conf + chown root:${GROUP} ${DIR}/etc/local_internal_options.conf >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/etc/client.keys >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/agentless/* + chown ${USER}:${GROUP} ${DIR}/.ssh + chown root:${GROUP} ${DIR}/etc/shared/* + + chmod 550 ${DIR}/etc + chmod 440 ${DIR}/etc/internal_options.conf + chmod 660 ${DIR}/etc/local_internal_options.conf >/dev/null 2>&1 || true + chmod 440 ${DIR}/etc/client.keys >/dev/null 2>&1 || true + chmod 550 ${DIR}/agentless/* + chmod 700 ${DIR}/.ssh + chmod 770 ${DIR}/etc/shared + chmod 660 ${DIR}/etc/shared/* + + # For the /var/run + chmod 770 ${DIR}/var/run + chown root:${GROUP} ${DIR}/var/run + + # For util.sh + chown root:${GROUP} ${DIR}/bin/util.sh + chmod +x ${DIR}/bin/util.sh + + # For binaries and active response + chmod 755 ${DIR}/active-response/bin/* + chown root:${GROUP} ${DIR}/active-response/bin/* + chown root:${GROUP} ${DIR}/bin/* + chmod 550 ${DIR}/bin/* + + # For openarmor.conf + chown root:${GROUP} ${DIR}/etc/openarmor.conf + chmod 660 ${DIR}/etc/openarmor.conf + + # Debconf + . /usr/share/debconf/confmodule + db_input high openarmor-hids-agent/server-ip || true + db_go + + db_get openarmor-hids-agent/server-ip + SERVER_IP=$RET + + sed -i "s/[^<]\+<\/server-ip>/${SERVER_IP}<\/server-ip>/" ${DIR}/etc/openarmor.conf + db_stop + + # openarmor-init.conf + if [ -e ${DIR}/etc/openarmor-init.conf ] && [ -d /etc/ ]; then + if [ -e /etc/openarmor-init.conf ]; then + rm -f /etc/openarmor-init.conf + fi + ln -s ${DIR}/etc/openarmor-init.conf /etc/openarmor-init.conf + fi + + # init.d/openarmor file + if [ -x ${DIR}/etc/init.d/openarmor ] && [ -d /etc/init.d/ ]; then + if [ -e /etc/init.d/openarmor ]; then + rm -f /etc/init.d/openarmor + fi + ln -s ${DIR}/etc/init.d/openarmor /etc/init.d/openarmor + fi + + # Service + if [ -x /etc/init.d/openarmor ]; then + update-rc.d -f openarmor defaults + fi + + # Delete tmp directory + if [ -d ${openarmor_HIDS_TMP_DIR} ]; then + rm -r ${openarmor_HIDS_TMP_DIR} + fi + + ;; + + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + + *) + echo "postinst called with unknown argument \`$1'" >22 + exit 1 + ;; + +esac + +exit 0 diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/postrm b/contrib/debian-packages/openarmor-hids-agent/debian/postrm new file mode 100644 index 000000000..b475dca07 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/postrm @@ -0,0 +1,33 @@ +#!/bin/sh +# postrm script for openarmor-hids +# Santiago Bassett +# 03/25/2014 + + +set -e + +case "$1" in + purge|remove|failed-upgrade|abort-install|abort-upgrade|disappear) + if getent passwd | grep -q "^openarmor" + then + deluser openarmor + fi + if getent group | grep -q "^openarmor" + then + delgroup openarmor + fi + rm -f /etc/init.d/openarmor + rm -f /etc/openarmor-init.conf + update-rc.d -f openarmor remove + + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + + ;; + +esac + +exit 0 diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/preinst b/contrib/debian-packages/openarmor-hids-agent/debian/preinst new file mode 100644 index 000000000..03539abad --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/preinst @@ -0,0 +1,36 @@ +#!/bin/sh +# preinst script for openarmor-hids +# Santiago Bassett +# 03/25/2014 + +set -e + +# configuration variables +openarmor_HIDS_TMP_DIR="/tmp/openarmor-hids" + +# environment configuration +if [ ! -d ${openarmor_HIDS_TMP_DIR} ]; then + mkdir ${openarmor_HIDS_TMP_DIR} +fi + +case "$1" in + install|upgrade) + # back up the current user rules + if [ -f /var/openarmor/rules/local_rules.xml ]; then + cp /var/openarmor/rules/local_rules.xml ${openarmor_HIDS_TMP_DIR}/local_rules.xml + fi + ;; + + abort-upgrade) + + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + + ;; + +esac + +exit 0 diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/rules b/contrib/debian-packages/openarmor-hids-agent/debian/rules new file mode 100644 index 000000000..7e26af8bf --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/rules @@ -0,0 +1,29 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. +# +# Modified to make a template file for a multi-binary package with separated +# build-arch and build-indep targets by Bill Allombert 2001 + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This has to be exported to make some magic below work. +export DH_OPTIONS + + +%: + dh $@ + +override_dh_auto_configure: + +override_dh_auto_build: + $(MAKE) all + +override_dh_auto_clean: + $(MAKE) clean diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/source/format b/contrib/debian-packages/openarmor-hids-agent/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/contrib/debian-packages/openarmor-hids-agent/debian/templates b/contrib/debian-packages/openarmor-hids-agent/debian/templates new file mode 100644 index 000000000..d07270511 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids-agent/debian/templates @@ -0,0 +1,4 @@ +Template: openarmor-hids-agent/server-ip +Type: string +Default: 127.0.0.1 +Description: openarmor server IP address for this agent. This server is also known as Manager and will receive information from the agent. You need to specify the IP address, the hostname is not valid. The agent still needs to be registered and started manually. diff --git a/contrib/debian-packages/openarmor-hids/debian/changelog b/contrib/debian-packages/openarmor-hids/debian/changelog new file mode 100644 index 000000000..9256efe4c --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/changelog @@ -0,0 +1,18 @@ +openarmor-hids (2.8.2-2) unstable; urgency=low + + * Added sticky bit to openarmor tmp directory + * Set maximum number of agents to 16,384 + * Included contrib/openarmor-batch-manager.pl + * Included contrib/openarmor-eps.sh + * Included contrib/compile_alerts.pl + * Included contrib/config2xml + * Set openarmor users home to /var/openarmor/ + * Added linux-libc-dev build dependency to Debian control file + + -- Santiago Bassett Mon, 15 Jun 2015 08:43:10 +0000 + +openarmor-hids (2.8.2-1) unstable; urgency=low + + * 2.8.2 Initial release. Includes several fixes, and patch for CVE-2015-3222 + + -- Santiago Bassett Mon, 15 Jun 2015 08:43:10 +0000 diff --git a/contrib/debian-packages/openarmor-hids/debian/compat b/contrib/debian-packages/openarmor-hids/debian/compat new file mode 100644 index 000000000..7f8f011eb --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/compat @@ -0,0 +1 @@ +7 diff --git a/contrib/debian-packages/openarmor-hids/debian/conffiles b/contrib/debian-packages/openarmor-hids/debian/conffiles new file mode 100644 index 000000000..17a44cc26 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/conffiles @@ -0,0 +1 @@ +/var/openarmor/etc/openarmor.conf diff --git a/contrib/debian-packages/openarmor-hids/debian/control b/contrib/debian-packages/openarmor-hids/debian/control new file mode 100644 index 000000000..80ad8ecdf --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/control @@ -0,0 +1,15 @@ +Source: openarmor-hids +Section: admin +Priority: extra +Maintainer: Santiago Bassett +Build-Depends: debhelper (>= 7.0.50~), libssl-dev, linux-libc-dev +Standards-Version: 3.8.4 +Homepage: http://www.theopenarmor.org + +Package: openarmor-hids +Architecture: any +Depends: ${shlibs:Depends}, libc6 (>= 2.7), libssl1.0.0, expect, debconf +Conflicts: openarmor-hids-agent +Description: openarmor - Host Based Intrusion Detection System + openarmor HIDS for log analysis, integrity checking, rootkits detection and + active response. This package includes the server and the agent. diff --git a/contrib/debian-packages/openarmor-hids/debian/copyright b/contrib/debian-packages/openarmor-hids/debian/copyright new file mode 100644 index 000000000..555c197dd --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/copyright @@ -0,0 +1,34 @@ +This work was packaged for Debian by: + + Santiago Bassett on Fri, 29 Nov 2013 03:11:44 +0000 + +It was downloaded from: + + http://www.theopenarmor.org + +Upstream Authors: + + dcid@dcid.me + Jia-BingJB_Cheng@trendmicro.com + vichargrave@gmail.com + openarmor@michaelstarks.com + ddpbsd@gmail.com + scott@atomicorp.com + brad.lhotsky@gmail.com + jeremy@jeremyrossi.com + santiago.bassett@gmail.com + +Copyright: + + GNU General Public License version 2. + +License: + + GNU General Public License version 2. + +The Debian packaging is: + + Copyright (C) 2014 Santiago Bassett + +and is licensed under the GPL version 2, +see "/usr/share/common-licenses/GPL-2". diff --git a/contrib/debian-packages/openarmor-hids/debian/openarmor-hids.lintian-overrides b/contrib/debian-packages/openarmor-hids/debian/openarmor-hids.lintian-overrides new file mode 100644 index 000000000..f542a498a --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/openarmor-hids.lintian-overrides @@ -0,0 +1,9 @@ +openarmor-hids: embedded-library +openarmor-hids: embedded-zlib +openarmor-hids: possible-gpl-code-linked-with-openssl +openarmor-hids: new-package-should-close-itp-bug +openarmor-hids: possibly-insecure-handling-of-tmp-files-in-maintainer-script +openarmor-hids: non-standard-dir-in-var +openarmor-hids: file-in-unusual-dir +openarmor-hids: hardening-no-fortify-functions +openarmor-hids: hardening-no-relro diff --git a/contrib/debian-packages/openarmor-hids/debian/patches/01_makefile.patch b/contrib/debian-packages/openarmor-hids/debian/patches/01_makefile.patch new file mode 100644 index 000000000..ee234909b --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/patches/01_makefile.patch @@ -0,0 +1,77 @@ +Index: openarmor-hids-2.8.2/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ openarmor-hids-2.8.2/Makefile 2015-08-10 04:36:27.819134760 +0000 +@@ -0,0 +1,72 @@ ++# ++# Santiago Bassett ++# 06/15/2015 ++# ++ ++DESTDIR?=/ ++DIR=$(DESTDIR)/var/openarmor/ ++openarmor_INIT=$(DIR)/etc/openarmor-init.conf ++ ++all: ++ echo "HEXTRA=-DMAX_AGENTS=16384" >> src/Config.OS ++ (cd src; make all; make build) ++ ++clean: ++ rm bin/* || /bin/true ++ mkdir -p $(DIR)/rules/translated/ ++ chmod 750 $(DIR) || /bin/true ++ chmod 750 $(DIR)/* || /bin/true ++ chmod 750 $(DIR)/rules/translated/ || /bin/true ++ chmod 750 $(DIR)/rules/translated/* || /bin/true ++ (cd src; make clean) ++ rm -f src/Config.OS ++ rm -f src/analysisd/compiled_rules/compiled_rules.h ++ rm -f src/isbigendian.c ++ rm -f src/analysisd/openarmor-makelists ++ rm -f src/analysisd/openarmor-logtest ++ rm -f src/isbigendian ++ ++install: ++ mkdir -p $(DIR) ++ (cd $(DIR); mkdir -p logs logs/archives logs/alerts logs/firewall bin stats rules queue queue/alerts queue/openarmor queue/fts queue/syscheck queue/rootcheck queue/diff queue/agent-info queue/agentless queue/rids tmp var var/run etc etc/init.d etc/shared active-response active-response/bin agentless .ssh contrib) ++ cp -pr etc/rules/* $(DIR)/rules/ ++ chmod -x $(DIR)/rules/*.xml ++ chmod -x $(DIR)/rules/log-entries/* ++ chmod -x $(DIR)/rules/translated/pure_ftpd/*.xml ++ cp -pL /etc/localtime $(DIR)/etc/ 2>/dev/null || /bin/true ++ cp -p /etc/TIMEZONE $(DIR)/etc/ 2>/dev/null || /bin/true ++ cp -p contrib/compile_alerts.pl $(DIR)/contrib/ ++ cp -p contrib/compile_alerts.txt $(DIR)/contrib/ ++ cp -p contrib/config2xml $(DIR)/contrib/ ++ cp -p contrib/openarmor-batch-manager.pl $(DIR)/contrib/ ++ cp -p contrib/openarmor-eps.sh $(DIR)/contrib/ ++ cp -pr bin/openarmor* $(DIR)/bin/ ++ cp -pr bin/manage_agents $(DIR)/bin/ ++ cp -pr bin/syscheck_update $(DIR)/bin/ ++ cp -pr bin/verify-agent-conf $(DIR)/bin/ ++ cp -pr bin/clear_stats $(DIR)/bin/ ++ cp -pr bin/list_agents $(DIR)/bin/ ++ cp -pr bin/agent_control $(DIR)/bin/ ++ cp -pr bin/syscheck_control $(DIR)/bin/ ++ cp -pr bin/rootcheck_control $(DIR)/bin/ ++ cp -pr contrib/util.sh $(DIR)/bin/ ++ cp -pr src/init/openarmor-server.sh $(DIR)/bin/openarmor-control ++ cp -pr etc/decoder.xml $(DIR)/etc/ ++ chmod -x $(DIR)/etc/decoder.xml ++ cp -pr etc/local_decoder.xml $(DIR)/etc/ > /dev/null 2>&1 || /bin/true ++ cp -pr etc/local_internal_options.conf $(DIR)/etc/ > /dev/null 2>&1 || /bin/true ++ cp -pr etc/client.keys $(DIR)/etc/ > /dev/null 2>&1 ||/bin/true ++ cp -pr src/agentlessd/scripts/* $(DIR)/agentless/ ++ cp -pr etc/internal_options.conf $(DIR)/etc/ ++ chmod -x $(DIR)/etc/internal_options.conf ++ cp -pr etc/openarmor-server.conf $(DIR)/etc/openarmor.conf ++ chmod -x $(DIR)/etc/openarmor.conf ++ cp -pr src/rootcheck/db/*.txt $(DIR)/etc/shared/ ++ chmod -x $(DIR)/etc/shared/*.txt ++ cp -p active-response/*.sh $(DIR)/active-response/bin/ ++ cp -p active-response/firewalls/*.sh $(DIR)/active-response/bin/ ++ cp -p src/init/openarmor-hids-debian.init $(DIR)/etc/init.d/openarmor ++ echo "DIRECTORY=\"/var/openarmor\"" > $(openarmor_INIT) ++ echo "VERSION=\"$(cat src/VERSION)" >> $(openarmor_INIT) ++ echo "DATE=\"`date`\"" >> $(openarmor_INIT) ++ echo "TYPE=\"server\"" >> $(openarmor_INIT) diff --git a/contrib/debian-packages/openarmor-hids/debian/patches/02_openarmor-server.conf.patch b/contrib/debian-packages/openarmor-hids/debian/patches/02_openarmor-server.conf.patch new file mode 100644 index 000000000..977d4c531 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/patches/02_openarmor-server.conf.patch @@ -0,0 +1,100 @@ +Index: openarmor-hids-2.8.2/etc/openarmor-server.conf +=================================================================== +--- openarmor-hids-2.8.2.orig/etc/openarmor-server.conf 2015-06-10 15:38:32.000000000 +0000 ++++ openarmor-hids-2.8.2/etc/openarmor-server.conf 2015-07-12 18:46:24.995134760 +0000 +@@ -2,10 +2,10 @@ + + + +- yes +- daniel.cid@example.com +- smtp.example.com. +- openarmorm@openarmor.example.com. ++ no ++ your_email_address@example.com ++ smtp.your_domain.com. ++ openarmorm@openarmor.your_domain.com. + + + +@@ -90,14 +90,11 @@ + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt ++ /var/openarmor/etc/shared/system_audit_rcl.txt + + + + 127.0.0.1 +- 192.168.2.1 +- 192.168.2.190 +- 192.168.2.32 +- 192.168.2.10 + + + +@@ -138,6 +135,7 @@ + - level (severity) >= 6. + - The IP is going to be blocked for 600 seconds. + --> ++ yes + host-deny + local + 6 +@@ -149,6 +147,7 @@ + - 600 seconds on the firewall (iptables, + - ipfilter, etc). + --> ++ yes + firewall-drop + local + 6 +@@ -159,36 +158,41 @@ + + + syslog +- /var/log/messages ++ /var/log/syslog + + + + syslog +- /var/log/authlog ++ /var/log/auth.log + + + + syslog +- /var/log/secure ++ /var/log/dpkg.log + + + + syslog +- /var/log/xferlog ++ /var/log/kern.log + + ++ ++ + diff --git a/contrib/debian-packages/openarmor-hids/debian/patches/series b/contrib/debian-packages/openarmor-hids/debian/patches/series new file mode 100644 index 000000000..393a60283 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/patches/series @@ -0,0 +1,2 @@ +02_openarmor-server.conf.patch +01_makefile.patch diff --git a/contrib/debian-packages/openarmor-hids/debian/postinst b/contrib/debian-packages/openarmor-hids/debian/postinst new file mode 100644 index 000000000..75729391c --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/postinst @@ -0,0 +1,232 @@ +#!/bin/sh +# postinst script for openarmor-hids + +set -e + +case "$1" in + configure) + + DIR="/var/openarmor/" + USER="openarmor" + USER_MAIL="openarmorm" + USER_REM="openarmorr" + GROUP="openarmor" + openarmor_HIDS_TMP_DIR="/tmp/openarmor-hids" + + OSMYSHELL="/sbin/nologin" + if [ ! -f ${OSMYSHELL} ]; then + if [ -f "/bin/false" ]; then + OSMYSHELL="/bin/false" + fi + fi + + if ! getent group | grep -q "^openarmor" + then + addgroup --system openarmor + fi + if ! getent passwd | grep -q "^openarmor" + then + adduser --system --home ${DIR} --shell ${OSMYSHELL} --ingroup ${GROUP} ${USER} > /dev/null 2>&1 + fi + if ! getent passwd | grep -q "^openarmorm" + then + adduser --system --home ${DIR} --shell ${OSMYSHELL} --ingroup ${GROUP} ${USER_MAIL} > /dev/null 2>&1 + fi + if ! getent passwd | grep -q "^openarmorr" + then + adduser --system --home ${DIR} --shell ${OSMYSHELL} --ingroup ${GROUP} ${USER_REM} > /dev/null 2>&1 + fi + + # Default for all directories + chmod -R 550 ${DIR} + chown -R root:${GROUP} ${DIR} + + # AnalysisD needs to write to alerts: log, mail and cmds + chown -R ${USER}:${GROUP} ${DIR}/queue/alerts + chmod -R 770 ${DIR}/queue/alerts + + # To the openarmor queue (default for analysisd to read) + chown -R ${USER}:${GROUP} ${DIR}/queue/openarmor + chmod -R 770 ${DIR}/queue/openarmor + + # To the openarmor fts queue + chown -R ${USER}:${GROUP} ${DIR}/queue/fts + chmod -R 750 ${DIR}/queue/fts + chmod 740 ${DIR}/queue/fts/* > /dev/null 2>&1 || true + + # To the openarmor syscheck/rootcheck queue + chown -R ${USER}:${GROUP} ${DIR}/queue/syscheck + chmod -R 750 ${DIR}/queue/syscheck + chmod 740 ${DIR}/queue/syscheck/* > /dev/null 2>&1 || true + + chown -R ${USER}:${GROUP} ${DIR}/queue/rootcheck + chmod -R 750 ${DIR}/queue/rootcheck + chmod 740 ${DIR}/queue/rootcheck/* > /dev/null 2>&1 || true + + chown -R ${USER}:${GROUP} ${DIR}/queue/diff + chmod -R 750 ${DIR}/queue/diff + chmod 740 ${DIR}/queue/diff/* > /dev/null 2>&1 || true + + chown -R ${USER_REM}:${GROUP} ${DIR}/queue/agent-info + chmod -R 755 ${DIR}/queue/agent-info + chmod 744 ${DIR}/queue/agent-info/* > /dev/null 2>&1 || true + chown -R ${USER_REM}:${GROUP} ${DIR}/queue/rids + chmod -R 755 ${DIR}/queue/rids + chmod 744 ${DIR}/queue/rids/* > /dev/null 2>&1 || true + + chown -R ${USER}:${GROUP} ${DIR}/queue/agentless + chmod -R 755 ${DIR}/queue/agentless + chmod 744 ${DIR}/queue/agentless/* > /dev/null 2>&1 || true + + # For the stats directory + chown -R ${USER}:${GROUP} ${DIR}/stats + chmod -R 750 ${DIR}/stats + + # For the logging user + chown -R ${USER}:${GROUP} ${DIR}/logs + chmod -R 750 ${DIR}/logs + touch ${DIR}/logs/openarmor.log + chown ${USER}:${GROUP} ${DIR}/logs/openarmor.log + chmod 664 ${DIR}/logs/openarmor.log + + # Backup previous rules + if [ -d ${DIR}/rules/ ]; then + mkdir ${DIR}/rules/backup-rules.$$ + cp -pr ${DIR}/rules/*.xml ${DIR}/rules/backup-rules.$$/ + fi + + # Restore the local rules + if [ -f ${openarmor_HIDS_TMP_DIR}/local_rules.xml ]; then + mv ${openarmor_HIDS_TMP_DIR}/local_rules.xml ${DIR}/rules/local_rules.xml + fi + + chown -R root:${GROUP} ${DIR}/rules + chmod -R 550 ${DIR}/rules + + + # For the etc dir + chmod 550 ${DIR}/etc + chown -R root:${GROUP} ${DIR}/etc + if [ -f /etc/localtime ]; then + cp -pL /etc/localtime ${DIR}/etc/; + chmod 555 ${DIR}/etc/localtime + chown root:${GROUP} ${DIR}/etc/localtime + fi + + if [ -f /etc/TIMEZONE ]; then + cp -p /etc/TIMEZONE ${DIR}/etc/; + chmod 555 ${DIR}/etc/TIMEZONE + fi + + # For the /var/run + chmod 770 ${DIR}/var/run + chown root:${GROUP} ${DIR}/var/run + + # More files + chown root:${GROUP} ${DIR}/etc/decoder.xml + chown root:${GROUP} ${DIR}/etc/local_decoder.xml >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/etc/internal_options.conf + chown root:${GROUP} ${DIR}/etc/local_internal_options.conf >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/etc/client.keys >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/etc/shared/* + chown root:${GROUP} ${DIR}/agentless/* + chown ${USER}:${GROUP} ${DIR}/.ssh + chmod 440 ${DIR}/etc/decoder.xml + chmod 660 ${DIR}/etc/local_decoder.xml >/dev/null 2>&1 || true + chmod 440 ${DIR}/etc/internal_options.conf + chmod 660 ${DIR}/etc/local_internal_options.conf >/dev/null 2>&1 || true + chmod 440 ${DIR}/etc/client.keys >/dev/null 2>&1 || true + chmod 550 ${DIR}/etc + chmod 770 ${DIR}/etc/shared + chmod 660 ${DIR}/etc/shared/* + chmod 550 ${DIR}/agentless/* + chmod 700 ${DIR}/.ssh + + rm ${DIR}/etc/shared/merged.mg >/dev/null 2>&1 || true + chmod 755 ${DIR}/active-response/bin/* + chown root:${GROUP} ${DIR}/active-response/bin/* + chown root:${GROUP} ${DIR}/bin/* + chmod 550 ${DIR}/bin/* + chown root:${GROUP} ${DIR}/etc/openarmor.conf + chmod 660 ${DIR}/etc/openarmor.conf + + # Sticky bit for /var/openarmor/tmp + chmod +t ${DIR}/tmp + + # Debconf + . /usr/share/debconf/confmodule + db_input high openarmor-hids/email_notification || true + db_go + + db_get openarmor-hids/email_notification + EMAIL_NOTIFICATION=$RET + + if [ ${EMAIL_NOTIFICATION} = "yes" ]; then + sed -i 's/[^<]\+<\/email_notification>/yes<\/email_notification>/' ${DIR}/etc/openarmor.conf + db_input high openarmor-hids/email_to || true + db_go + db_input high openarmor-hids/email_from || true + db_go + db_input high openarmor-hids/smtp_server || true + db_go + + db_get openarmor-hids/email_to + EMAIL_TO=$RET + db_get openarmor-hids/email_from + EMAIL_FROM=$RET + db_get openarmor-hids/smtp_server + SMTP_SERVER=$RET + + sed -i "s/[^<]\+<\/email_to>/${EMAIL_TO}<\/email_to>/" ${DIR}/etc/openarmor.conf + sed -i "s/[^<]\+<\/email_from>/${EMAIL_FROM}<\/email_from>/" ${DIR}/etc/openarmor.conf + sed -i "s/[^<]\+<\/smtp_server>/${SMTP_SERVER}<\/smtp_server>/" ${DIR}/etc/openarmor.conf + + else + sed -i 's/[^<]\+<\/email_notification>/no<\/email_notification>/' ${DIR}/etc/openarmor.conf + fi + + db_stop + + # openarmor-init.conf + if [ -e ${DIR}/etc/openarmor-init.conf ] && [ -d /etc/ ]; then + if [ -e /etc/openarmor-init.conf ]; then + rm -f /etc/openarmor-init.conf + fi + ln -s ${DIR}/etc/openarmor-init.conf /etc/openarmor-init.conf + fi + + # init.d/openarmor file + if [ -x ${DIR}/etc/init.d/openarmor ] && [ -d /etc/init.d/ ]; then + if [ -e /etc/init.d/openarmor ]; then + rm -f /etc/init.d/openarmor + fi + ln -s ${DIR}/etc/init.d/openarmor /etc/init.d/openarmor + fi + + # Service + if [ -x /etc/init.d/openarmor ]; then + update-rc.d -f openarmor defaults + service openarmor restart + fi + + # Delete tmp directory + if [ -d ${openarmor_HIDS_TMP_DIR} ]; then + rm -r ${openarmor_HIDS_TMP_DIR} + fi + + ;; + + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + + *) + echo "postinst called with unknown argument \`$1'" >22 + exit 1 + ;; + +esac + +exit 0 diff --git a/contrib/debian-packages/openarmor-hids/debian/postrm b/contrib/debian-packages/openarmor-hids/debian/postrm new file mode 100644 index 000000000..a177fd339 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/postrm @@ -0,0 +1,38 @@ +#!/bin/sh +# postrm script for openarmor-hids + +set -e + +case "$1" in + purge|remove|failed-upgrade|abort-install|abort-upgrade|disappear) + if getent passwd | grep -q "^openarmorr" + then + deluser openarmorr + fi + if getent passwd | grep -q "^openarmorm" + then + deluser openarmorm + fi + if getent passwd | grep -q "^openarmor" + then + deluser openarmor + fi + if getent group | grep -q "^openarmor" + then + delgroup openarmor + fi + rm -f /etc/init.d/openarmor + rm -f /etc/openarmor-init.conf + update-rc.d -f openarmor remove + + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + + ;; + +esac + +exit 0 diff --git a/contrib/debian-packages/openarmor-hids/debian/preinst b/contrib/debian-packages/openarmor-hids/debian/preinst new file mode 100644 index 000000000..6d4e692b4 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/preinst @@ -0,0 +1,34 @@ +#!/bin/sh +# preinst script for openarmor-hids + +set -e + +# configuration variables +openarmor_HIDS_TMP_DIR="/tmp/openarmor-hids" + +# environment configuration +if [ ! -d ${openarmor_HIDS_TMP_DIR} ]; then + mkdir ${openarmor_HIDS_TMP_DIR} +fi + +case "$1" in + install|upgrade) + # back up the current user rules + if [ -f /var/openarmor/rules/local_rules.xml ]; then + cp /var/openarmor/rules/local_rules.xml ${openarmor_HIDS_TMP_DIR}/local_rules.xml + fi + ;; + + abort-upgrade) + + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + + ;; + +esac + +exit 0 diff --git a/contrib/debian-packages/openarmor-hids/debian/rules b/contrib/debian-packages/openarmor-hids/debian/rules new file mode 100644 index 000000000..7e26af8bf --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/rules @@ -0,0 +1,29 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. +# +# Modified to make a template file for a multi-binary package with separated +# build-arch and build-indep targets by Bill Allombert 2001 + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This has to be exported to make some magic below work. +export DH_OPTIONS + + +%: + dh $@ + +override_dh_auto_configure: + +override_dh_auto_build: + $(MAKE) all + +override_dh_auto_clean: + $(MAKE) clean diff --git a/contrib/debian-packages/openarmor-hids/debian/source/format b/contrib/debian-packages/openarmor-hids/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/contrib/debian-packages/openarmor-hids/debian/templates b/contrib/debian-packages/openarmor-hids/debian/templates new file mode 100644 index 000000000..063337723 --- /dev/null +++ b/contrib/debian-packages/openarmor-hids/debian/templates @@ -0,0 +1,20 @@ +Template: openarmor-hids/email_notification +Type: select +Choices: yes, no +Default: no +Description: Enable email notification when an alert is triggered. + +Template: openarmor-hids/email_to +Type: string +Default: root@localhost +Description: This is the email address where alerts will be sent to. + +Template: openarmor-hids/email_from +Type: string +Default: openarmorm@localhost +Description: This is the from email address used to send alerts. + +Template: openarmor-hids/smtp_server +Type: string +Default: localhost +Description: SMTP server IP address or hostname. diff --git a/contrib/debian-packages/openarmor_packages.log b/contrib/debian-packages/openarmor_packages.log new file mode 100644 index 000000000..b71151921 --- /dev/null +++ b/contrib/debian-packages/openarmor_packages.log @@ -0,0 +1 @@ +2024-07-15 20:27:50: Error: Couldn't find debian files directory for openarmor-hids-agent, version 3.6.0 diff --git a/contrib/debian-packages/pbuilderrc b/contrib/debian-packages/pbuilderrc new file mode 100644 index 000000000..43197613d --- /dev/null +++ b/contrib/debian-packages/pbuilderrc @@ -0,0 +1,90 @@ +#!/bin/bash +# Codenames for Debian suites according to their alias. Update these when +# needed. +UNSTABLE_CODENAME="sid" +TESTING_CODENAME="bullseye" +STABLE_CODENAME="buster" +STABLE_BACKPORTS_SUITE="$STABLE_CODENAME-backports" + +# List of Debian suites. +DEBIAN_SUITES=($UNSTABLE_CODENAME $TESTING_CODENAME $STABLE_CODENAME + "unstable" "testing" "stable") + +# List of Ubuntu suites. Update these when needed. +UBUNTU_SUITES=("eoan" "bionic" "xenial") + +# Mirrors to use. Update these to your preferred mirror. +DEBIAN_MIRROR="ftp.us.debian.org" +UBUNTU_MIRROR="ftp.ubuntu.com" +UBUNTU_PORTS_MIRROR="ports.ubuntu.com" + +# Optionally use the changelog of a package to determine the suite to use if +# none set. +if [ -z "${DIST}" ] && [ -r "debian/changelog" ]; then + DIST=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}') + DIST="${DIST%%-*}" + # Use the unstable suite for certain suite values. + if $(echo "experimental UNRELEASED" | grep -q $DIST); then + DIST="$UNSTABLE_CODENAME" + fi +fi + +# Optionally set a default distribution if none is used. Note that you can set +# your own default (i.e. ${DIST:="unstable"}). +: ${DIST:="$(lsb_release --short --codename)"} + +# Optionally change Debian release states in $DIST to their names. +case "$DIST" in + unstable) + DIST="$UNSTABLE_CODENAME" + ;; + testing) + DIST="$TESTING_CODENAME" + ;; + stable) + DIST="$STABLE_CODENAME" + ;; +esac + +# Optionally set the architecture to the host architecture if none set. Note +# that you can set your own default (i.e. ${ARCH:="i386"}). +: ${ARCH:="$(dpkg --print-architecture)"} + +NAME="$DIST" +if [ -n "${ARCH}" ]; then + NAME="$NAME-$ARCH" + DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}") +fi +BASETGZ="/var/cache/pbuilder/$NAME-base.tgz" +# Optionally, set BASEPATH (and not BASETGZ) if using cowbuilder +# BASEPATH="/var/cache/pbuilder/$NAME/base.cow/" +DISTRIBUTION="$DIST" +BUILDRESULT="/var/cache/pbuilder/$NAME/result/" +APTCACHE="/var/cache/pbuilder/$NAME/aptcache/" +BUILDPLACE="/var/cache/pbuilder/build/" + +if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then + # Debian configuration + MIRRORSITE="http://$DEBIAN_MIRROR/debian/" + COMPONENTS="main contrib non-free" + DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg") + +elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then + # Ubuntu configuration + case "$ARCH" in + i386|amd64) + MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/" + ;; + arm64) + MIRRORSITE="http://$UBUNTU_PORTS_MIRROR/ubuntu-ports/" + DEBOOTSTRAP="qemu-debootstrap" + # pbuilder-satisfydepends-aptitude SEGVs on arm64 qemu env. + PBUILDERSATISFYDEPENDSCMD=/usr/lib/pbuilder/pbuilder-satisfydepends-experimental + ;; + esac + COMPONENTS="main restricted universe multiverse" + DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg") +else + echo "Unknown distribution: $DIST" + exit 1 +fi diff --git a/contrib/iis-logs.bat b/contrib/iis-logs.bat new file mode 100644 index 000000000..b54e55ba6 --- /dev/null +++ b/contrib/iis-logs.bat @@ -0,0 +1,57 @@ +@echo off + +rem Searching for IIS logs. +rem If we find any log in the NCSA or W3C extended format, +rem change the config to support that. If not, let the user know. +rem Example of log to look: nc060215.log or ex060723.log + +echo. +echo Looking for IIS log files to monitor. +echo For more information visit: +echo http://www.theopenarmor.org/en/manual.html#iis +echo. +echo. + +IF EXIST %WinDir%\System32\LogFiles\W3SVC1\nc??????.log ( + echo * IIS NCSA log found. Changing config to read it. + echo. >> openarmor.conf + echo ^ >> openarmor.conf + echo ^ >> openarmor.conf + echo ^%WinDir%\System32\LogFiles\W3SVC1\nc%%y%%m%%d.log^ >> openarmor.conf + echo ^iis^ >> openarmor.conf + echo ^ >> openarmor.conf + echo ^ >> openarmor.conf + pause + ) + +IF EXIST %WinDir%\System32\LogFiles\W3SVC1\ex??????.log ( + echo * IIS W3C extended log found. Changing config to read it. + echo. >> openarmor.conf + echo ^ >> openarmor.conf + echo ^ >> openarmor.conf + echo ^%WinDir%\System32\LogFiles\W3SVC1\ex%%y%%m%%d.log^ >> openarmor.conf + echo ^iis^ >> openarmor.conf + echo ^ >> openarmor.conf + echo ^ >> openarmor.conf + pause + ) + +IF EXIST %WinDir%\System32\LogFiles\W3SVC3\ex??????.log ( + echo * IIS W3C extended log found. Changing config to read it. + echo. >> openarmor.conf + echo ^ >> openarmor.conf + echo ^ >> openarmor.conf + echo ^%WinDir%\System32\LogFiles\W3SVC3\nc%%y%%m%%d.log^ >> openarmor.conf + echo ^iis^ >> openarmor.conf + echo ^ >> openarmor.conf + echo ^ >> openarmor.conf + pause + ) + +IF EXIST %WinDir%\System32\LogFiles\W3SVC1 ( + echo * IIS Log found. Look at the link above if you want to monitor it. + pause + exit ) + +rem EOF + diff --git a/contrib/logtesting/1/log b/contrib/logtesting/1/log new file mode 100644 index 000000000..eb7e201b5 --- /dev/null +++ b/contrib/logtesting/1/log @@ -0,0 +1 @@ +Nov 2 13:24:34 melancia pam: gdm-password[1600]: pam_unix(gdm-password:session): session closed for user dcid11 diff --git a/contrib/logtesting/1/res b/contrib/logtesting/1/res new file mode 100644 index 000000000..a62202e04 --- /dev/null +++ b/contrib/logtesting/1/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Nov 2 13:24:34 melancia pam: gdm-password[1600]: pam_unix(gdm-password:session): session closed for user dcid11' + hostname: 'melancia' + program_name: 'pam' + log: 'gdm-password[1600]: pam_unix(gdm-password:session): session closed for user dcid11' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/10/log b/contrib/logtesting/10/log new file mode 100644 index 000000000..74ad82145 --- /dev/null +++ b/contrib/logtesting/10/log @@ -0,0 +1 @@ +Feb 15 16:08:14 triumph PAM-securetty[741]: Couldn't open /etc/securetty diff --git a/contrib/logtesting/10/res b/contrib/logtesting/10/res new file mode 100644 index 000000000..d8aa869a7 --- /dev/null +++ b/contrib/logtesting/10/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Feb 15 16:08:14 triumph PAM-securetty[741]: Couldn't open /etc/securetty' + hostname: 'triumph' + program_name: 'PAM-securetty' + log: 'Couldn't open /etc/securetty' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '1001' + Level: '2' + Description: 'File missing. Root access unrestricted.' +**Alert to be generated. + + diff --git a/contrib/logtesting/11/log b/contrib/logtesting/11/log new file mode 100644 index 000000000..34594c716 --- /dev/null +++ b/contrib/logtesting/11/log @@ -0,0 +1 @@ +Sep 11 01:40:59 bogus.com su: ericx to root on /dev/ttyu0 diff --git a/contrib/logtesting/11/res b/contrib/logtesting/11/res new file mode 100644 index 000000000..f6cb8675f --- /dev/null +++ b/contrib/logtesting/11/res @@ -0,0 +1,18 @@ +**Phase 1: Completed pre-decoding. + full event: 'Sep 11 01:40:59 bogus.com su: ericx to root on /dev/ttyu0' + hostname: 'bogus.com' + program_name: 'su' + log: 'ericx to root on /dev/ttyu0' + +**Phase 2: Completed decoding. + decoder: 'su' + srcuser: 'ericx' + dstuser: 'root' + +**Phase 3: Completed filtering (rules). + Rule id: '5305' + Level: '4' + Description: 'First time (su) is executed by user.' +**Alert to be generated. + + diff --git a/contrib/logtesting/12/log b/contrib/logtesting/12/log new file mode 100644 index 000000000..e1baedb22 --- /dev/null +++ b/contrib/logtesting/12/log @@ -0,0 +1 @@ +May 4 11:17:42 niban su(pam_unix)[2298]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=root diff --git a/contrib/logtesting/12/res b/contrib/logtesting/12/res new file mode 100644 index 000000000..81143bfc5 --- /dev/null +++ b/contrib/logtesting/12/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 4 11:17:42 niban su(pam_unix)[2298]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=root' + hostname: 'melancia' + program_name: '(null)' + log: 'May 4 11:17:42 niban su(pam_unix)[2298]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=root' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '2501' + Level: '5' + Description: 'User authentication failure.' +**Alert to be generated. + + diff --git a/contrib/logtesting/13/log b/contrib/logtesting/13/log new file mode 100644 index 000000000..a9bffd12b --- /dev/null +++ b/contrib/logtesting/13/log @@ -0,0 +1 @@ +May 4 11:18:52 niban su(pam_unix)[2307]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=test diff --git a/contrib/logtesting/13/res b/contrib/logtesting/13/res new file mode 100644 index 000000000..83f79a026 --- /dev/null +++ b/contrib/logtesting/13/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 4 11:18:52 niban su(pam_unix)[2307]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=test' + hostname: 'melancia' + program_name: '(null)' + log: 'May 4 11:18:52 niban su(pam_unix)[2307]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=test' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '2501' + Level: '5' + Description: 'User authentication failure.' +**Alert to be generated. + + diff --git a/contrib/logtesting/14/log b/contrib/logtesting/14/log new file mode 100644 index 000000000..86d4c5689 --- /dev/null +++ b/contrib/logtesting/14/log @@ -0,0 +1 @@ +Jun 8 09:01:01 niban su(pam_unix)[1313]: session opened for user root by (uid=1342) diff --git a/contrib/logtesting/14/res b/contrib/logtesting/14/res new file mode 100644 index 000000000..d6fcaae3a --- /dev/null +++ b/contrib/logtesting/14/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jun 8 09:01:01 niban su(pam_unix)[1313]: session opened for user root by (uid=1342)' + hostname: 'melancia' + program_name: '(null)' + log: 'Jun 8 09:01:01 niban su(pam_unix)[1313]: session opened for user root by (uid=1342)' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/15/log b/contrib/logtesting/15/log new file mode 100644 index 000000000..60cc1e1b3 --- /dev/null +++ b/contrib/logtesting/15/log @@ -0,0 +1 @@ +Jun 9 13:32:14 niban su(pam_unix)[1338]: session opened for user root by (uid=1342) diff --git a/contrib/logtesting/15/res b/contrib/logtesting/15/res new file mode 100644 index 000000000..5dcfd9f18 --- /dev/null +++ b/contrib/logtesting/15/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jun 9 13:32:14 niban su(pam_unix)[1338]: session opened for user root by (uid=1342)' + hostname: 'melancia' + program_name: '(null)' + log: 'Jun 9 13:32:14 niban su(pam_unix)[1338]: session opened for user root by (uid=1342)' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/16/log b/contrib/logtesting/16/log new file mode 100644 index 000000000..305dc61d1 --- /dev/null +++ b/contrib/logtesting/16/log @@ -0,0 +1 @@ +Jul 5 00:30:21 lili su[2190]: + pts/4 dcid-root diff --git a/contrib/logtesting/16/res b/contrib/logtesting/16/res new file mode 100644 index 000000000..6388ef2ca --- /dev/null +++ b/contrib/logtesting/16/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jul 5 00:30:21 lili su[2190]: + pts/4 dcid-root' + hostname: 'melancia' + program_name: '(null)' + log: 'Jul 5 00:30:21 lili su[2190]: + pts/4 dcid-root' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/17/log b/contrib/logtesting/17/log new file mode 100644 index 000000000..b9f0336da --- /dev/null +++ b/contrib/logtesting/17/log @@ -0,0 +1 @@ +Jul 5 12:13:15 lili su[2614]: Authentication failed for root diff --git a/contrib/logtesting/17/res b/contrib/logtesting/17/res new file mode 100644 index 000000000..5d2368eb3 --- /dev/null +++ b/contrib/logtesting/17/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jul 5 12:13:15 lili su[2614]: Authentication failed for root' + hostname: 'melancia' + program_name: '(null)' + log: 'Jul 5 12:13:15 lili su[2614]: Authentication failed for root' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '2501' + Level: '5' + Description: 'User authentication failure.' +**Alert to be generated. + + diff --git a/contrib/logtesting/18/log b/contrib/logtesting/18/log new file mode 100644 index 000000000..721b97b1e --- /dev/null +++ b/contrib/logtesting/18/log @@ -0,0 +1 @@ +Jul 5 12:13:15 lili su[2614]: - pts/6 dcid-root diff --git a/contrib/logtesting/18/res b/contrib/logtesting/18/res new file mode 100644 index 000000000..1dd1cf83a --- /dev/null +++ b/contrib/logtesting/18/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jul 5 12:13:15 lili su[2614]: - pts/6 dcid-root' + hostname: 'melancia' + program_name: '(null)' + log: 'Jul 5 12:13:15 lili su[2614]: - pts/6 dcid-root' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/19/log b/contrib/logtesting/19/log new file mode 100644 index 000000000..a0843f8b0 --- /dev/null +++ b/contrib/logtesting/19/log @@ -0,0 +1 @@ +May 21 10:24:54 niban useradd[6070]: new group: name=test, gid=5006 diff --git a/contrib/logtesting/19/res b/contrib/logtesting/19/res new file mode 100644 index 000000000..64a4ab6f7 --- /dev/null +++ b/contrib/logtesting/19/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 21 10:24:54 niban useradd[6070]: new group: name=test, gid=5006' + hostname: 'niban' + program_name: 'useradd' + log: 'new group: name=test, gid=5006' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '5901' + Level: '8' + Description: 'New group added to the system' +**Alert to be generated. + + diff --git a/contrib/logtesting/2/log b/contrib/logtesting/2/log new file mode 100644 index 000000000..6059c8f31 --- /dev/null +++ b/contrib/logtesting/2/log @@ -0,0 +1 @@ +Nov 1 14:54:03 melancia runuser: pam_unix(runuser:session): session opened for user root by (uid=0) diff --git a/contrib/logtesting/2/res b/contrib/logtesting/2/res new file mode 100644 index 000000000..ed00e95e2 --- /dev/null +++ b/contrib/logtesting/2/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Nov 1 14:54:03 melancia runuser: pam_unix(runuser:session): session opened for user root by (uid=0)' + hostname: 'melancia' + program_name: 'runuser' + log: 'pam_unix(runuser:session): session opened for user root by (uid=0)' + +**Phase 2: Completed decoding. + decoder: 'pam' + +**Phase 3: Completed filtering (rules). + Rule id: '5501' + Level: '3' + Description: 'Login session opened.' +**Alert to be generated. + + diff --git a/contrib/logtesting/20/log b/contrib/logtesting/20/log new file mode 100644 index 000000000..7cb06f558 --- /dev/null +++ b/contrib/logtesting/20/log @@ -0,0 +1 @@ +May 28 10:48:29 niban useradd[32421]: new group: name=logr, gid=12000 diff --git a/contrib/logtesting/20/res b/contrib/logtesting/20/res new file mode 100644 index 000000000..b0b445844 --- /dev/null +++ b/contrib/logtesting/20/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 28 10:48:29 niban useradd[32421]: new group: name=logr, gid=12000' + hostname: 'niban' + program_name: 'useradd' + log: 'new group: name=logr, gid=12000' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '5901' + Level: '8' + Description: 'New group added to the system' +**Alert to be generated. + + diff --git a/contrib/logtesting/21/log b/contrib/logtesting/21/log new file mode 100644 index 000000000..584236425 --- /dev/null +++ b/contrib/logtesting/21/log @@ -0,0 +1 @@ +Jun 16 09:53:44 niban useradd[5721]: new group: name=test2, gid=12001 diff --git a/contrib/logtesting/21/res b/contrib/logtesting/21/res new file mode 100644 index 000000000..74dd5bb12 --- /dev/null +++ b/contrib/logtesting/21/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jun 16 09:53:44 niban useradd[5721]: new group: name=test2, gid=12001' + hostname: 'niban' + program_name: 'useradd' + log: 'new group: name=test2, gid=12001' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '5901' + Level: '8' + Description: 'New group added to the system' +**Alert to be generated. + + diff --git a/contrib/logtesting/22/log b/contrib/logtesting/22/log new file mode 100644 index 000000000..d769abb1c --- /dev/null +++ b/contrib/logtesting/22/log @@ -0,0 +1 @@ +Aug 4 15:11:23 niban groupadd[26459]: new group: name=osaudit, gid=12002 diff --git a/contrib/logtesting/22/res b/contrib/logtesting/22/res new file mode 100644 index 000000000..1f3de2282 --- /dev/null +++ b/contrib/logtesting/22/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Aug 4 15:11:23 niban groupadd[26459]: new group: name=osaudit, gid=12002' + hostname: 'melancia' + program_name: '(null)' + log: 'Aug 4 15:11:23 niban groupadd[26459]: new group: name=osaudit, gid=12002' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/23/log b/contrib/logtesting/23/log new file mode 100644 index 000000000..bab36558a --- /dev/null +++ b/contrib/logtesting/23/log @@ -0,0 +1 @@ +Aug 4 15:14:14 niban groupadd[26477]: new group: name=osaudit, gid=12002 diff --git a/contrib/logtesting/23/res b/contrib/logtesting/23/res new file mode 100644 index 000000000..2829a5fb0 --- /dev/null +++ b/contrib/logtesting/23/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Aug 4 15:14:14 niban groupadd[26477]: new group: name=osaudit, gid=12002' + hostname: 'melancia' + program_name: '(null)' + log: 'Aug 4 15:14:14 niban groupadd[26477]: new group: name=osaudit, gid=12002' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/24/log b/contrib/logtesting/24/log new file mode 100644 index 000000000..d52ac7aa3 --- /dev/null +++ b/contrib/logtesting/24/log @@ -0,0 +1 @@ +Apr 5 16:19:49 niban adduser[16188]: new user: name=port4, uid=12006, gid=0, home=/home/port4, shell=/bin/bash diff --git a/contrib/logtesting/24/res b/contrib/logtesting/24/res new file mode 100644 index 000000000..0e452759c --- /dev/null +++ b/contrib/logtesting/24/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Apr 5 16:19:49 niban adduser[16188]: new user: name=port4, uid=12006, gid=0, home=/home/port4, shell=/bin/bash' + hostname: 'melancia' + program_name: '(null)' + log: 'Apr 5 16:19:49 niban adduser[16188]: new user: name=port4, uid=12006, gid=0, home=/home/port4, shell=/bin/bash' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/25/log b/contrib/logtesting/25/log new file mode 100644 index 000000000..6871b31aa --- /dev/null +++ b/contrib/logtesting/25/log @@ -0,0 +1 @@ +Feb 1 14:39:16 nogan sudo: test2 : 3 incorrect password attempts ; TTY=pts/4 ; PWD=/home/test2 ; USER=root ; COMMAND=/bin/ls diff --git a/contrib/logtesting/25/res b/contrib/logtesting/25/res new file mode 100644 index 000000000..6c61ac8a9 --- /dev/null +++ b/contrib/logtesting/25/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Feb 1 14:39:16 nogan sudo: test2 : 3 incorrect password attempts ; TTY=pts/4 ; PWD=/home/test2 ; USER=root ; COMMAND=/bin/ls' + hostname: 'melancia' + program_name: '(null)' + log: 'Feb 1 14:39:16 nogan sudo: test2 : 3 incorrect password attempts ; TTY=pts/4 ; PWD=/home/test2 ; USER=root ; COMMAND=/bin/ls' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/26/log b/contrib/logtesting/26/log new file mode 100644 index 000000000..328e46f87 --- /dev/null +++ b/contrib/logtesting/26/log @@ -0,0 +1 @@ +Jan 28 20:36:33 enigma sudo: dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls diff --git a/contrib/logtesting/26/res b/contrib/logtesting/26/res new file mode 100644 index 000000000..c8fe17a07 --- /dev/null +++ b/contrib/logtesting/26/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jan 28 20:36:33 enigma sudo: dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls' + hostname: 'enigma' + program_name: 'sudo' + log: 'dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls' + +**Phase 2: Completed decoding. + decoder: 'sudo' + +**Phase 3: Completed filtering (rules). + Rule id: '5404' + Level: '10' + Description: 'Three failed attempts to run sudo' +**Alert to be generated. + + diff --git a/contrib/logtesting/27/log b/contrib/logtesting/27/log new file mode 100644 index 000000000..b156e56dc --- /dev/null +++ b/contrib/logtesting/27/log @@ -0,0 +1 @@ +May 26 19:40:25 enigma sudo: dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/bin/ls diff --git a/contrib/logtesting/27/res b/contrib/logtesting/27/res new file mode 100644 index 000000000..a23d94347 --- /dev/null +++ b/contrib/logtesting/27/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 26 19:40:25 enigma sudo: dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/bin/ls' + hostname: 'enigma' + program_name: 'sudo' + log: 'dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/bin/ls' + +**Phase 2: Completed decoding. + decoder: 'sudo' + +**Phase 3: Completed filtering (rules). + Rule id: '5404' + Level: '10' + Description: 'Three failed attempts to run sudo' +**Alert to be generated. + + diff --git a/contrib/logtesting/28/log b/contrib/logtesting/28/log new file mode 100644 index 000000000..b0dea841f --- /dev/null +++ b/contrib/logtesting/28/log @@ -0,0 +1 @@ +Feb 4 10:43:02 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls diff --git a/contrib/logtesting/28/res b/contrib/logtesting/28/res new file mode 100644 index 000000000..a5a97d8ab --- /dev/null +++ b/contrib/logtesting/28/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Feb 4 10:43:02 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls' + hostname: 'melancia' + program_name: '(null)' + log: 'Feb 4 10:43:02 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/29/log b/contrib/logtesting/29/log new file mode 100644 index 000000000..03a69c9c2 --- /dev/null +++ b/contrib/logtesting/29/log @@ -0,0 +1 @@ +Feb 4 10:44:00 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/chmod 777 /home/dcid/test1 diff --git a/contrib/logtesting/29/res b/contrib/logtesting/29/res new file mode 100644 index 000000000..8d55df218 --- /dev/null +++ b/contrib/logtesting/29/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Feb 4 10:44:00 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/chmod 777 /home/dcid/test1' + hostname: 'melancia' + program_name: '(null)' + log: 'Feb 4 10:44:00 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/chmod 777 /home/dcid/test1' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/3/log b/contrib/logtesting/3/log new file mode 100644 index 000000000..60a16a2c5 --- /dev/null +++ b/contrib/logtesting/3/log @@ -0,0 +1 @@ +Nov 11 22:46:29 localhost vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=1.2.3.4 diff --git a/contrib/logtesting/3/res b/contrib/logtesting/3/res new file mode 100644 index 000000000..5586f896b --- /dev/null +++ b/contrib/logtesting/3/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'Nov 11 22:46:29 localhost vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=1.2.3.4' + hostname: 'localhost' + program_name: 'vsftpd' + log: 'pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=1.2.3.4' + +**Phase 2: Completed decoding. + decoder: 'pam' + srcip: '1.2.3.4' + +**Phase 3: Completed filtering (rules). + Rule id: '5503' + Level: '5' + Description: 'User login failed.' +**Alert to be generated. + + diff --git a/contrib/logtesting/30/log b/contrib/logtesting/30/log new file mode 100644 index 000000000..eeb35efe2 --- /dev/null +++ b/contrib/logtesting/30/log @@ -0,0 +1 @@ +Feb 4 10:46:37 niban sudo: dcid : TTY=pts/26 ; PWD=/home/dcid/dev/pr/osaudit/osaudit-0.1/src ; USER=root ; COMMAND=/bin/cp -pr ../bin/logreader ../bin/logremote ../bin/logremote-client /var/osaudit/bin diff --git a/contrib/logtesting/30/res b/contrib/logtesting/30/res new file mode 100644 index 000000000..87eec28b9 --- /dev/null +++ b/contrib/logtesting/30/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Feb 4 10:46:37 niban sudo: dcid : TTY=pts/26 ; PWD=/home/dcid/dev/pr/osaudit/osaudit-0.1/src ; USER=root ; COMMAND=/bin/cp -pr ../bin/logreader ../bin/logremote ../bin/logremote-client /var/osaudit/bin' + hostname: 'melancia' + program_name: '(null)' + log: 'Feb 4 10:46:37 niban sudo: dcid : TTY=pts/26 ; PWD=/home/dcid/dev/pr/osaudit/osaudit-0.1/src ; USER=root ; COMMAND=/bin/cp -pr ../bin/logreader ../bin/logremote ../bin/logremote-client /var/osaudit/bin' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/31/log b/contrib/logtesting/31/log new file mode 100644 index 000000000..e5eb9d183 --- /dev/null +++ b/contrib/logtesting/31/log @@ -0,0 +1 @@ +May 26 19:40:41 enigma sudo: dcid : TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/usr/bin/tail /var/log/secure diff --git a/contrib/logtesting/31/res b/contrib/logtesting/31/res new file mode 100644 index 000000000..9ad2d73ab --- /dev/null +++ b/contrib/logtesting/31/res @@ -0,0 +1,20 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 26 19:40:41 enigma sudo: dcid : TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/usr/bin/tail /var/log/secure' + hostname: 'enigma' + program_name: 'sudo' + log: 'dcid : TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/usr/bin/tail /var/log/secure' + +**Phase 2: Completed decoding. + decoder: 'sudo' + dstuser: 'dcid' + url: '/var/www/htdocs' + srcuser: 'root' + status: '/usr/bin/tail /var/log/secure' + +**Phase 3: Completed filtering (rules). + Rule id: '5403' + Level: '4' + Description: 'First time user executed sudo.' +**Alert to be generated. + + diff --git a/contrib/logtesting/32/log b/contrib/logtesting/32/log new file mode 100644 index 000000000..83041fbc2 --- /dev/null +++ b/contrib/logtesting/32/log @@ -0,0 +1 @@ +May 26 20:16:17 lili sudo: dcid : TTY=pts/1 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/vi /etc/sudoers diff --git a/contrib/logtesting/32/res b/contrib/logtesting/32/res new file mode 100644 index 000000000..986a2fd46 --- /dev/null +++ b/contrib/logtesting/32/res @@ -0,0 +1,20 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 26 20:16:17 lili sudo: dcid : TTY=pts/1 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/vi /etc/sudoers' + hostname: 'lili' + program_name: 'sudo' + log: 'dcid : TTY=pts/1 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/vi /etc/sudoers' + +**Phase 2: Completed decoding. + decoder: 'sudo' + dstuser: 'dcid' + url: '/home/dcid' + srcuser: 'root' + status: '/usr/bin/vi /etc/sudoers' + +**Phase 3: Completed filtering (rules). + Rule id: '5403' + Level: '4' + Description: 'First time user executed sudo.' +**Alert to be generated. + + diff --git a/contrib/logtesting/33/log b/contrib/logtesting/33/log new file mode 100644 index 000000000..ee9b225b7 --- /dev/null +++ b/contrib/logtesting/33/log @@ -0,0 +1 @@ +Oct 26 18:07:45 ccs rpc.statd[189]: gethostbyname error for ^X^X^Z^Z%8x%8x%8x%8x%8x%8x%8x%8x%8x%62716x%hn%51859x%hn220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220 diff --git a/contrib/logtesting/33/res b/contrib/logtesting/33/res new file mode 100644 index 000000000..69d8c5a6e --- /dev/null +++ b/contrib/logtesting/33/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Oct 26 18:07:45 ccs rpc.statd[189]: gethostbyname error for ^X^X^Z^Z%8x%8x%8x%8x%8x%8x%8x%8x%8x%62716x%hn%51859x%hn220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220' + hostname: 'ccs' + program_name: 'rpc.statd' + log: 'gethostbyname error for ^X^X^Z^Z%8x%8x%8x%8x%8x%8x%8x%8x%8x%62716x%hn%51859x%hn220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220220' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '1002' + Level: '2' + Description: 'Unknown problem somewhere in the system.' +**Alert to be generated. + + diff --git a/contrib/logtesting/34/log b/contrib/logtesting/34/log new file mode 100644 index 000000000..691ce2a60 --- /dev/null +++ b/contrib/logtesting/34/log @@ -0,0 +1 @@ +May 17 01:01:19 server ftpd[746]: ANONYMOUS FTP LOGIN FROM emaca.here.com diff --git a/contrib/logtesting/34/res b/contrib/logtesting/34/res new file mode 100644 index 000000000..a249697c8 --- /dev/null +++ b/contrib/logtesting/34/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 17 01:01:19 server ftpd[746]: ANONYMOUS FTP LOGIN FROM emaca.here.com' + hostname: 'server' + program_name: 'ftpd' + log: 'ANONYMOUS FTP LOGIN FROM emaca.here.com' + +**Phase 2: Completed decoding. + decoder: 'ftpd' + srcip: 'emaca.here.com' + +**Phase 3: Completed filtering (rules). + Rule id: '11106' + Level: '3' + Description: 'Remote host connected to FTP server.' +**Alert to be generated. + + diff --git a/contrib/logtesting/35/log b/contrib/logtesting/35/log new file mode 100644 index 000000000..6e81c7ec4 --- /dev/null +++ b/contrib/logtesting/35/log @@ -0,0 +1 @@ +May 16 22:46:08 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped diff --git a/contrib/logtesting/35/res b/contrib/logtesting/35/res new file mode 100644 index 000000000..290e8e14c --- /dev/null +++ b/contrib/logtesting/35/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 16 22:46:08 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped' + hostname: 'victim-host' + program_name: 'inetd' + log: '/usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '40107' + Level: '14' + Description: 'Heap overflow in the Solaris cachefsd service.' + Info - CVE: '2002-0033' +**Alert to be generated. + + diff --git a/contrib/logtesting/36/log b/contrib/logtesting/36/log new file mode 100644 index 000000000..a08d83551 --- /dev/null +++ b/contrib/logtesting/36/log @@ -0,0 +1 @@ +May 16 22:46:24 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped diff --git a/contrib/logtesting/36/res b/contrib/logtesting/36/res new file mode 100644 index 000000000..2899796fe --- /dev/null +++ b/contrib/logtesting/36/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'May 16 22:46:24 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped' + hostname: 'victim-host' + program_name: 'inetd' + log: '/usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '40107' + Level: '14' + Description: 'Heap overflow in the Solaris cachefsd service.' + Info - CVE: '2002-0033' +**Alert to be generated. + + diff --git a/contrib/logtesting/37/log b/contrib/logtesting/37/log new file mode 100644 index 000000000..3c30aae44 --- /dev/null +++ b/contrib/logtesting/37/log @@ -0,0 +1 @@ +Apr 17 22:20:29 hostj named[312]: [ID 295310 daemon.notice] security: notice: dropping source port zero packet from [64.211.251.254].0 diff --git a/contrib/logtesting/37/res b/contrib/logtesting/37/res new file mode 100644 index 000000000..61c466e5e --- /dev/null +++ b/contrib/logtesting/37/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'Apr 17 22:20:29 hostj named[312]: [ID 295310 daemon.notice] security: notice: dropping source port zero packet from [64.211.251.254].0' + hostname: 'hostj' + program_name: 'named' + log: 'security: notice: dropping source port zero packet from [64.211.251.254].0' + +**Phase 2: Completed decoding. + decoder: 'named' + srcip: '64.211.251.254' + +**Phase 3: Completed filtering (rules). + Rule id: '12101' + Level: '12' + Description: 'Invalid DNS packet. Possibility of attack.' +**Alert to be generated. + + diff --git a/contrib/logtesting/38/log b/contrib/logtesting/38/log new file mode 100644 index 000000000..9c1608c1b --- /dev/null +++ b/contrib/logtesting/38/log @@ -0,0 +1 @@ +sshd[7386]: error: Bad prime description in line 73 diff --git a/contrib/logtesting/38/res b/contrib/logtesting/38/res new file mode 100644 index 000000000..ddd59dd22 --- /dev/null +++ b/contrib/logtesting/38/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'sshd[7386]: error: Bad prime description in line 73' + hostname: 'melancia' + program_name: '(null)' + log: 'sshd[7386]: error: Bad prime description in line 73' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '1002' + Level: '2' + Description: 'Unknown problem somewhere in the system.' +**Alert to be generated. + + diff --git a/contrib/logtesting/39/log b/contrib/logtesting/39/log new file mode 100644 index 000000000..3685e94d1 --- /dev/null +++ b/contrib/logtesting/39/log @@ -0,0 +1 @@ +Jan 12 20:48:29 elrond sshd[19734]: refused connect from accsys.elink.net.au (203.31.101.11) diff --git a/contrib/logtesting/39/res b/contrib/logtesting/39/res new file mode 100644 index 000000000..2f740ccf0 --- /dev/null +++ b/contrib/logtesting/39/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'Jan 12 20:48:29 elrond sshd[19734]: refused connect from accsys.elink.net.au (203.31.101.11)' + hostname: 'elrond' + program_name: 'sshd' + log: 'refused connect from accsys.elink.net.au (203.31.101.11)' + +**Phase 2: Completed decoding. + decoder: 'sshd' + srcip: '203.31.101.11' + +**Phase 3: Completed filtering (rules). + Rule id: '2503' + Level: '5' + Description: 'Connection blocked by Tcp Wrappers.' +**Alert to be generated. + + diff --git a/contrib/logtesting/4/log b/contrib/logtesting/4/log new file mode 100644 index 000000000..5571201d3 --- /dev/null +++ b/contrib/logtesting/4/log @@ -0,0 +1 @@ +Dec 18 18:06:28 hostname cimserver[18575]: PGS17200: Authentication failed for user jones_b. diff --git a/contrib/logtesting/4/res b/contrib/logtesting/4/res new file mode 100644 index 000000000..cf3a8d680 --- /dev/null +++ b/contrib/logtesting/4/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'Dec 18 18:06:28 hostname cimserver[18575]: PGS17200: Authentication failed for user jones_b.' + hostname: 'hostname' + program_name: 'cimserver' + log: 'PGS17200: Authentication failed for user jones_b.' + +**Phase 2: Completed decoding. + decoder: 'cimserver' + dstuser: 'jones_b' + +**Phase 3: Completed filtering (rules). + Rule id: '9610' + Level: '5' + Description: 'Compaq Insight Manager authentication failure.' +**Alert to be generated. + + diff --git a/contrib/logtesting/40/log b/contrib/logtesting/40/log new file mode 100644 index 000000000..4da5f03e2 --- /dev/null +++ b/contrib/logtesting/40/log @@ -0,0 +1 @@ +Aug 1 15:44:10 enigma sshd[13752]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2 diff --git a/contrib/logtesting/40/res b/contrib/logtesting/40/res new file mode 100644 index 000000000..cde3af4d1 --- /dev/null +++ b/contrib/logtesting/40/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Aug 1 15:44:10 enigma sshd[13752]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2' + hostname: 'melancia' + program_name: '(null)' + log: 'Aug 1 15:44:10 enigma sshd[13752]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '1002' + Level: '2' + Description: 'Unknown problem somewhere in the system.' +**Alert to be generated. + + diff --git a/contrib/logtesting/41/log b/contrib/logtesting/41/log new file mode 100644 index 000000000..ec267f97f --- /dev/null +++ b/contrib/logtesting/41/log @@ -0,0 +1 @@ +Aug 1 15:44:10 enigma sshd[6682]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2 diff --git a/contrib/logtesting/41/res b/contrib/logtesting/41/res new file mode 100644 index 000000000..145936e54 --- /dev/null +++ b/contrib/logtesting/41/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'Aug 1 15:44:10 enigma sshd[6682]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2' + hostname: 'melancia' + program_name: '(null)' + log: 'Aug 1 15:44:10 enigma sshd[6682]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2' + +**Phase 2: Completed decoding. + No decoder matched. + +**Phase 3: Completed filtering (rules). + Rule id: '1002' + Level: '2' + Description: 'Unknown problem somewhere in the system.' +**Alert to be generated. + + diff --git a/contrib/logtesting/42/log b/contrib/logtesting/42/log new file mode 100644 index 000000000..47f2fd48f --- /dev/null +++ b/contrib/logtesting/42/log @@ -0,0 +1 @@ +[Tue Sep 12 10:38:15 2006] [error] [client 127.0.0.1] request failed: URI too long (longer than 8190) diff --git a/contrib/logtesting/42/res b/contrib/logtesting/42/res new file mode 100644 index 000000000..c228b7b72 --- /dev/null +++ b/contrib/logtesting/42/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: '[Tue Sep 12 10:38:15 2006] [error] [client 127.0.0.1] request failed: URI too long (longer than 8190)' + hostname: 'melancia' + program_name: '(null)' + log: '[error] [client 127.0.0.1] request failed: URI too long (longer than 8190)' + +**Phase 2: Completed decoding. + decoder: 'apache-errorlog' + srcip: '127.0.0.1' + +**Phase 3: Completed filtering (rules). + Rule id: '30117' + Level: '10' + Description: 'Invalid URI, file name too long.' +**Alert to be generated. + + diff --git a/contrib/logtesting/43/log b/contrib/logtesting/43/log new file mode 100644 index 000000000..7a1ba345e --- /dev/null +++ b/contrib/logtesting/43/log @@ -0,0 +1 @@ +[Mon Sep 11 16:55:08 2006] [error] [client 127.0.0.1] (36)File name too long: access to /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm failed diff --git a/contrib/logtesting/43/res b/contrib/logtesting/43/res new file mode 100644 index 000000000..392f224d4 --- /dev/null +++ b/contrib/logtesting/43/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: '[Mon Sep 11 16:55:08 2006] [error] [client 127.0.0.1] (36)File name too long: access to /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm failed' + hostname: 'melancia' + program_name: '(null)' + log: '[error] [client 127.0.0.1] (36)File name too long: access to /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm failed' + +**Phase 2: Completed decoding. + decoder: 'apache-errorlog' + srcip: '127.0.0.1' + +**Phase 3: Completed filtering (rules). + Rule id: '30117' + Level: '10' + Description: 'Invalid URI, file name too long.' +**Alert to be generated. + + diff --git a/contrib/logtesting/44/log b/contrib/logtesting/44/log new file mode 100644 index 000000000..2d503b906 --- /dev/null +++ b/contrib/logtesting/44/log @@ -0,0 +1 @@ +Sep 1 10:29:33 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1234 -> 192.168.100.1:443] diff --git a/contrib/logtesting/44/res b/contrib/logtesting/44/res new file mode 100644 index 000000000..fcd8b85e3 --- /dev/null +++ b/contrib/logtesting/44/res @@ -0,0 +1,8 @@ +**Phase 1: Completed pre-decoding. + full event: 'Sep 1 10:29:33 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1234 -> 192.168.100.1:443]' + hostname: 'melancia' + program_name: '(null)' + log: 'Sep 1 10:29:33 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1234 -> 192.168.100.1:443]' + +**Phase 2: Completed decoding. + No decoder matched. diff --git a/contrib/logtesting/5/log b/contrib/logtesting/5/log new file mode 100644 index 000000000..c545162d4 --- /dev/null +++ b/contrib/logtesting/5/log @@ -0,0 +1 @@ +Apr 27 15:22:23 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/tail /var/log/snort/alert.fast diff --git a/contrib/logtesting/5/res b/contrib/logtesting/5/res new file mode 100644 index 000000000..ae59790d8 --- /dev/null +++ b/contrib/logtesting/5/res @@ -0,0 +1,20 @@ +**Phase 1: Completed pre-decoding. + full event: 'Apr 27 15:22:23 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/tail /var/log/snort/alert.fast' + hostname: 'niban' + program_name: 'sudo' + log: ' dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/tail /var/log/snort/alert.fast' + +**Phase 2: Completed decoding. + decoder: 'sudo' + dstuser: 'dcid' + url: '/home/dcid' + srcuser: 'root' + status: '/usr/bin/tail /var/log/snort/alert.fast' + +**Phase 3: Completed filtering (rules). + Rule id: '5403' + Level: '4' + Description: 'First time user executed sudo.' +**Alert to be generated. + + diff --git a/contrib/logtesting/6/log b/contrib/logtesting/6/log new file mode 100644 index 000000000..821e304b3 --- /dev/null +++ b/contrib/logtesting/6/log @@ -0,0 +1 @@ +Sun Aug 27 16:28:20 2006 [pid 13962] [xx] OK UPLOAD: Client "1.2.3.4", "/a.php", 8338 bytes, 18.77Kbyte/sec diff --git a/contrib/logtesting/6/res b/contrib/logtesting/6/res new file mode 100644 index 000000000..45c6a43f2 --- /dev/null +++ b/contrib/logtesting/6/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'Sun Aug 27 16:28:20 2006 [pid 13962] [xx] OK UPLOAD: Client "1.2.3.4", "/a.php", 8338 bytes, 18.77Kbyte/sec' + hostname: 'melancia' + program_name: '(null)' + log: 'Sun Aug 27 16:28:20 2006 [pid 13962] [xx] OK UPLOAD: Client "1.2.3.4", "/a.php", 8338 bytes, 18.77Kbyte/sec' + +**Phase 2: Completed decoding. + decoder: 'vsftpd' + dstuser: 'xx' + status: 'OK UPLOAD' + srcip: '1.2.3.4' + url: '/a.php' + +**Phase 3: Completed filtering (rules). + Rule id: '11404' + Level: '0' + Description: 'FTP server file upload.' diff --git a/contrib/logtesting/7/log b/contrib/logtesting/7/log new file mode 100644 index 000000000..37f5735a3 --- /dev/null +++ b/contrib/logtesting/7/log @@ -0,0 +1 @@ +MySQL log: 060516 22:38:46 mysqld ended diff --git a/contrib/logtesting/7/res b/contrib/logtesting/7/res new file mode 100644 index 000000000..5ad144321 --- /dev/null +++ b/contrib/logtesting/7/res @@ -0,0 +1,16 @@ +**Phase 1: Completed pre-decoding. + full event: 'MySQL log: 060516 22:38:46 mysqld ended' + hostname: 'melancia' + program_name: '(null)' + log: 'MySQL log: 060516 22:38:46 mysqld ended' + +**Phase 2: Completed decoding. + decoder: 'mysql_log' + +**Phase 3: Completed filtering (rules). + Rule id: '50120' + Level: '12' + Description: 'Database shutdown message.' +**Alert to be generated. + + diff --git a/contrib/logtesting/8/log b/contrib/logtesting/8/log new file mode 100644 index 000000000..1779e50f2 --- /dev/null +++ b/contrib/logtesting/8/log @@ -0,0 +1 @@ +Nov 24 18:18:28 gandalf pop3d: LOGIN FAILED, ip=[::ffff:1.2.3.4] diff --git a/contrib/logtesting/8/res b/contrib/logtesting/8/res new file mode 100644 index 000000000..8d62b8dfd --- /dev/null +++ b/contrib/logtesting/8/res @@ -0,0 +1,17 @@ +**Phase 1: Completed pre-decoding. + full event: 'Nov 24 18:18:28 gandalf pop3d: LOGIN FAILED, ip=[::ffff:1.2.3.4]' + hostname: 'gandalf' + program_name: 'pop3d' + log: 'LOGIN FAILED, ip=[::ffff:1.2.3.4]' + +**Phase 2: Completed decoding. + decoder: 'courier' + srcip: '::ffff:1.2.3.4' + +**Phase 3: Completed filtering (rules). + Rule id: '3902' + Level: '5' + Description: 'Courier (imap/pop3) authentication failed.' +**Alert to be generated. + + diff --git a/contrib/logtesting/9/log b/contrib/logtesting/9/log new file mode 100644 index 000000000..250fedb6a --- /dev/null +++ b/contrib/logtesting/9/log @@ -0,0 +1 @@ +type=SYSCALL msg=audit(1307045440.943:148): arch=c000003e syscall=59 success=yes exit=0 a0=de1fa8 a1=de23a8 a2=dc3008 a3=7fff1db3cc60 items=2 ppid=11719 pid=12140 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="wget" exe="/tmp/wget" key="webserver-watch-tmp" diff --git a/contrib/logtesting/9/res b/contrib/logtesting/9/res new file mode 100644 index 000000000..2f97bf033 --- /dev/null +++ b/contrib/logtesting/9/res @@ -0,0 +1,12 @@ +**Phase 1: Completed pre-decoding. + full event: 'type=SYSCALL msg=audit(1307045440.943:148): arch=c000003e syscall=59 success=yes exit=0 a0=de1fa8 a1=de23a8 a2=dc3008 a3=7fff1db3cc60 items=2 ppid=11719 pid=12140 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="wget" exe="/tmp/wget" key="webserver-watch-tmp"' + hostname: 'melancia' + program_name: '(null)' + log: 'type=SYSCALL msg=audit(1307045440.943:148): arch=c000003e syscall=59 success=yes exit=0 a0=de1fa8 a1=de23a8 a2=dc3008 a3=7fff1db3cc60 items=2 ppid=11719 pid=12140 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="wget" exe="/tmp/wget" key="webserver-watch-tmp"' + +**Phase 2: Completed decoding. + decoder: 'auditd' + action: 'SYSCALL' + id: '148' + status: 'yes' + extra_data: '/tmp/wget' diff --git a/contrib/logtesting/dotests.sh b/contrib/logtesting/dotests.sh new file mode 100644 index 000000000..a818eead5 --- /dev/null +++ b/contrib/logtesting/dotests.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +hostname=`hostname` +hostname melancia + +cleanup() { + hostname $hostname + rm -f ./tmpres +} + +trap "cleanup" INT TERM EXIT +exitcode=0 + +if diff --help 2>&1 | grep -q -- --color; then + diff_cmd='diff --color' +else + diff_cmd='diff' +fi + +echo "Starting log unit tests (must be run as root and on a system with openarmor installed)." +echo "(it will make sure the current rules are working as they should)." +rm -f ./tmpres +for i in ./*/log; do + idir=`dirname $i` + + rm -f ./tmpres || exit "Unable to remove tmpres."; + cat $i | /var/openarmor/bin/openarmor-logtest 2>&1|grep -av openarmor-testrule |grep -aA 500 "Phase 1:" > ./tmpres + + if [ ! -f $idir/res ]; then + echo "** Creating entry for $i - Not set yet." + cat ./tmpres > $idir/res + rm -f tmpres + continue; + fi + MD1=`md5sum ./tmpres | cut -d " " -f 1` + MD2=`md5sum $idir/res | cut -d " " -f 1` + + if [ ! $MD1 = $MD2 ]; then + exitcode=1 + echo + echo + echo + echo "**ERROR: Unit testing failed. Output for the test $i failed." + echo "== DIFF OUTPUT: ==" + $diff_cmd -Na -U `wc -l $idir/res` tmpres + rm -f tmpres + fi + +done + +echo "" +if [ $exitcode -eq 0 ]; then + echo "Log unit tests completed. Everything seems ok (nothing changed since last test regarding the outputs)." +else + echo "Log unit tests completed. Some tests failed." +fi +exit $exitcode diff --git a/contrib/openarmor-batch-manager.pl b/contrib/openarmor-batch-manager.pl new file mode 100644 index 000000000..8549a33e0 --- /dev/null +++ b/contrib/openarmor-batch-manager.pl @@ -0,0 +1,376 @@ +#!/usr/bin/perl +# vim:shiftwidth=2:tabstop=2:expandtab:textwidth=80:softtabstop=2:ai: + + ######################################################### + # Written Aug 4, 2007 and released under the GNU/GPLv2 ## + # by Jeff Schroeder (jeffschroeder@computer.org) # # +######################################################### # +# # # +# openarmor-batch-manager.pl - Add and extract agents from # # +# the openarmor client.keys file non-interactively. This # # +# started as a hack to properly script manage_agents. # # +# # # +########################################################## +# Modified by Tim Meader (Timothy.A.Meader@nasa.gov) +# on 2013/07/01 +# +# - corrected a MAJOR logic error in the remove +# function. The comparison was being done across the +# entire line of the agent keys file, so both IPs +# and the SSH keys at the end could be matched against +# the 'agent ID' wanting to be removed. Changed the +# match to only compare the first column of the file +# - added an error output message to the remove +# function if it's fed an 'agent ID' that doesn't +# exist +# - the script now also removes the corresponding +# associated agent rid files after a successful remove +# operation, or gives an error on failure +# +########################################################## +# Modified by Tim Meader (Timothy.A.Meader@nasa.gov) +# on 2010/12/08 +# +# - fixed two errors that were popping up during add or +# remove operations due to the code not taking into +# account the old key entries that have the "#*#*#*" +# pattern after the ID number. Simple fix was to do +# a "if (defined(xxx))" on the vars +# - fixed the "list" operation to only show valid key +# entries +# - changed the extract operation to store options +# in an array, and subsequently rewrote the +# "extract_key" (now called "extract_keys") func +# to accept this new behavior +# - modified "extract_keys" func to accept either ID, +# name, or IP address as the argument after the +# "-e" operator. Output of key extraction now +# include the name and IP address by default in the +# format: "name,IP extracted_key" +# +######################################################### + + +#$Id$ +# TODO: +# - Add check for openarmor 1.4 and support longer agent names +# - Add in eval so that older version of perl without +# Time::HiRes still can use this script. + +use strict; +use warnings; +require 5.8.2; # Time::HiRes is standard from this version forth +#use diagnostics; +use MIME::Base64; +use Digest::MD5 qw(md5_hex); +use Getopt::Long; +use Regexp::Common qw(net); + +use constant AUTH_KEY_FILE => "/var/openarmor/etc/client.keys"; +use constant RIDS_PATH => "/var/openarmor/queue/rids/"; + +my ($key, $add, $remove, @extracts, $import, $listagents); +my ($agentid, $agentname, $ipaddress); + +GetOptions( + 'k|key=s' => \$key, # Unencoded ssh key + 'a|add' => \$add, # Add a new agent + 'r|remove=s' => \$remove, # Remove an agent + 'e|extract=s' => \@extracts, # Extract a key + 'm|import' => \$import, # Import a key + 'l|list' => \$listagents, # List all agents + 'i|id=s' => \$agentid, # Unique agent id + 'n|name=s' => \$agentname, # Agent name. 32 char max + 'p|ip=s' => \$ipaddress # IP Address in "dotted quad" notation +); + +# Spit out a list of available agents, their names, and ip information +if ($listagents) { + list_agents(); +} +# Decode and extract the key for $agentid +elsif (@extracts) { + if (@extracts) { + extract_keys(@extracts); + } + else { + usage(); + } +} +# Adding a new agent +elsif ($add) { + if ($agentname && $ipaddress && + ( + $ipaddress =~ m/$RE{net}{IPv4}/ + || + $ipaddress =~ m/$RE{net}{IPv6}/ + || + $ipaddress eq 'any' + ) && + # openarmor doesn't like agent names > 32 characters. + length($agentname) <= 32) { + + # Autogenerate an id incremented 1 from the last in a sorted list of + # all current ones if it isn't specified from the command line. + if (!$agentid) { + + # Make a list of all of the used agentids and then sort it. + if (-r AUTH_KEY_FILE) { + my @used_agent_ids = (); + open (FH, "<", AUTH_KEY_FILE); + while () { + my ($id, $name, $ip, $key) = split; + push(@used_agent_ids, $id); + } + close(FH); + + if (@used_agent_ids) { + @used_agent_ids = sort {$a <=> $b} @used_agent_ids; + $agentid = sprintf("%03d", $used_agent_ids[-1] + 1); + } + } + # If the client.keys is empty or doesn't exist set the id to 001 + $agentid = sprintf("%03d", 001) if (!$agentid); + } + + # Autogenerate a key unless one was specified on the command line + if (!$key) { + use Time::HiRes; # Standard with perl >= 5.8.2 + + my $rand_str1 = time() . $agentname . rand(10000); + my $rand_str2 = Time::HiRes::time . $ipaddress . $agentid . rand(10000); + $key = md5_hex($rand_str1) . md5_hex($rand_str2); + } + + add_agent($agentid, $agentname, $ipaddress, $key); + } + else { + warn "Error: adding agents requires: --name and --ip options.\n"; + usage(); + } +} +elsif ($remove) { + if ($agentid) { + remove_agent($agentid); + } + else { + remove_agent($remove) + } +} +elsif ($import) { + # Every option needs to be specified and NOT autogenerated because what + # is autogenerated on the server and the agent will likely be different + if (!$agentid || !$agentname || !$ipaddress || !$key) { + warn "Error: importing requires: --id, --name, --ip, and --key\n"; + usage(); + } + else { + # The key extracted from the server needs to be decoded before being put + # into the client.keys + $key = MIME::Base64::decode($key); + + add_agent($agentid, $agentname, $ipaddress, $key); + } +} +else { + warn "Error: no options specified!\n"; + usage(); +} + +sub usage { + warn "Usage: $0 [OPERATION] [OPTIONS]\n"; + warn " [operations]\n"; + warn " -a or --add = Add a new agent\n"; + warn " -r or --remove [id] = Remove agent\n"; + warn " -e or --extract [id|name|ip] = Extract key\n"; + warn " -m or --import [keydata] = Import key\n"; + warn " -l or --list = List available agents\n"; + warn " [options]\n"; + warn " -k or --key [keydata] = Key data\n"; + warn " -n or --name [name] = Agent name (32 character max)\n"; + warn " -i or --id [id] = Agent identification (integer)\n"; + warn " -p or --ip [ip] = IP address\n\n"; + exit 1; +} + +sub list_agents { + if (-r AUTH_KEY_FILE) { + open (FH, "<", AUTH_KEY_FILE); + } + else { + die "Error reading ".AUTH_KEY_FILE.": $!\n"; + } + print "Available Agents:\n"; + print "ID", " " x (25 - length('ID')), + "NAME", " " x (25 - length('NAME')), + "IP", " " x (25 - length('IP')); + print "\n"; + while () { + chomp; + my ($id, $name, $ip, $key) = split; + if (defined($key)) { + print "$id", " " x (25 - length($id)), + "$name", " " x (25 - length($name)), + "$ip", " " x (25 - length($ip)) . "\n"; + } + } + close(FH); + exit 0; +} + +sub extract_keys { + if (-r AUTH_KEY_FILE) { + open (FH, "<", AUTH_KEY_FILE); + } + else { + die "No ".AUTH_KEY_FILE."!\n"; + } + + foreach my $extract (@_) { + my ($encoded, $decoded); + my $found = 0; + + while () { + chomp; + my ($id, $name, $ip, $key) = split; + # Check to make sure it's a valid entry + if (defined($key)) { + if (($extract =~ /^\d+$/) && ($id == $extract)) { + $found = 1; + } + elsif ($name eq $extract) { + $found = 1; + } + elsif ($ip eq $extract) { + $found = 1; + } + else { + next; + } + # Newlines are valid base64 characters so use '' instead for \n + $decoded = MIME::Base64::encode($_, ''); + print "$name,$ip $decoded\n"; + next; + } + } + if (!$found) { + warn "Error: Agent $extract doesn't exist!\n"; + } + seek FH,0,0; + } +} + +sub add_agent { + my $id = shift; + my $name = shift; + my $ip = shift; + my $agentkey = shift; + + if ($name && $ip && $agentkey) { + # Valid example key: + # 5a832efb8f93660857ce2acf8eec66a19fd9d4fa58e3221bbd2927ca8a0b40c3 + if ($agentkey !~ m/[a-z0-9]{64}/) { + warn "Error: invalid keydata! Let this script autogenerate it.\n"; + usage(); + } + + my @newagent = ($id, $name, $ip, $agentkey); + my $exists = check_if_exists(\@newagent); + + if ($exists == 0) { + # Append if client.keys exists and create it if it doesn't + if (-e AUTH_KEY_FILE) { + open(FH, ">>", AUTH_KEY_FILE) or die AUTH_KEY_FILE." error: $!\n"; + } + else { + open(FH, ">", AUTH_KEY_FILE) or die AUTH_KEY_FILE." error: $!\n"; + } + print FH join(' ', @newagent), "\n"; + close(FH); + } + elsif ($exists == 1) { + warn "ID: $id already in ".AUTH_KEY_FILE."!\n"; + } + elsif ($exists == 2) { + warn "Agent: $name already in ".AUTH_KEY_FILE."!\n"; + } + elsif ($exists == 3) { + warn "IP: $ip already in ".AUTH_KEY_FILE."!\n"; + } + } + else { + warn "Missing options to --add or problem with ".AUTH_KEY_FILE.": $!\n"; + usage(); + } +} + +sub remove_agent { + my $removeid = shift; + my @agent_array; + + if (-r AUTH_KEY_FILE) { + open (FH, "<", AUTH_KEY_FILE); + } + else { + die "Error: with ".AUTH_KEY_FILE.": $!\n"; + } + while () { + push(@agent_array, $_); + } + close(FH); + + if (-w AUTH_KEY_FILE) { + open (FHRW, ">", AUTH_KEY_FILE); + } + else { + die "Error writing ".AUTH_KEY_FILE.": $!\n"; + } + + my $key_found = 0; + + foreach my $line (@agent_array) { + my @split_line = split(/\s/,$line); + + if ($split_line[0] ne $removeid) { + print FHRW "$line"; + } + else { + my $rids_file = RIDS_PATH.$removeid; + $key_found = 1; + unlink $rids_file or warn "Could not remove rids file for Agent ID \'".$removeid."\'!\n"; + } + } + close(FHRW); + + if (!$key_found) { + die "Agent ID \'".$removeid."\' not found! Nothing removed.\n"; + } + exit(0); +} + +sub check_if_exists { + my $agentlist_ref = shift; + my ($newid, $newname, $newip); + my $rval = 0; + + $newid = $agentlist_ref->[0]; + $newname = $agentlist_ref->[1]; + $newip = $agentlist_ref->[2]; + + # If the file isn't readable, the id probably isn't already in it + if (-r AUTH_KEY_FILE) { + open (FH, "<", AUTH_KEY_FILE); + while () { + chomp; + my ($id, $name, $ip, $key) = split; + if(defined($key)) { + $rval = 1 if ($id == $newid && $rval == 0); + $rval = 2 if ($name eq $newname && $rval == 0); + $rval = 3 if ($ip ne 'any' && $ip eq $newip && $rval == 0); + } + } + close(FH); + } + return $rval; +} + diff --git a/contrib/openarmor-configure b/contrib/openarmor-configure new file mode 100644 index 000000000..14b398b79 --- /dev/null +++ b/contrib/openarmor-configure @@ -0,0 +1,307 @@ +#!/bin/sh + +# Global Variables +openarmor_HOME="/var/openarmor/" +openarmor_CONF_FILE="$openarmor_HOME/etc/openarmor.conf" +RULES_TEMPLATE="$openarmor_HOME/etc/templates/rules.template" +SYSCHECK_TEMPLATE="$openarmor_HOME/etc/templates/syscheck.template" +HOST_DENY_TEMPLATE="$openarmor_HOME/etc/templates/ar-host-deny.template" +FIREWALL_DROP_TEMPLATE="$openarmor_HOME/etc/templates/ar-firewall-drop.template" +DISABLE_ACCOUNT_TEMPLATE="$openarmor_HOME/etc/templates/ar-disable-account.template" +ROUTENULL_TEMPLATE="$openarmor_HOME/etc/templates/ar-routenull.template" +SYSLOG_TEMPLATE="$openarmor_HOME//etc/templates/syslog-logs.template" +SNORT_TEMPLATE="$openarmor_HOME/etc/templates/snort-logs.template" +APACHE_TEMPLATE="$openarmor_HOME/etc/templates/apache-logs.template" +PGSQL_TEMPLATE="$openarmor_HOME/etc/templates/pgsql-logs.template" +ACTIVE_RESPONSE_TEMPLATE="$openarmor_HOME/etc/templates/active-response.template" + +HOSTNAME=$(hostname) + +# Module specific functions + +# Input validation function +# check_input +# if is passed on as null, then there is no default +# Example: check_input "Some question (yes/no) " "yes|no" "yes" +function check_input { + message=$1 + validate=$2 + default=$3 + + while [ $? -ne 1 ]; do + echo -n "$message " + read INPUTTEXT < /dev/tty + if [ "$INPUTTEXT" == "" -a "$default" != "" ]; then + INPUTTEXT=$default + return 1 + fi + echo $INPUTTEXT | egrep -q "$validate" && return 1 + echo "Invalid input" + done +} + + +# Main +echo +echo "openarmor Configuration utility v0.1" +echo + +echo "" > ${openarmor_CONF_FILE}.new + +# Back up config file +cp ${openarmor_CONF_FILE} ${openarmor_CONF_FILE}.bak + +# Set language + +# grabs System/User/Host + +# openarmor installed? + +# server/agent/local or help +check_input "1- What kind of installation do you want? (server, agent, local) [Default: server]:" "server|agent|local" "server" +openarmor_TYPE=$INPUTTEXT +echo + +echo "2- Setting up the configuration environment." +echo + +# email notification +echo "3- Configuring the openarmor HIDS." +echo +check_input " 3.1- Do you want e-mail notification? (y/n) [Default: y]:" "y|n" "y" +EMAIL_NOTIFICATION=$INPUTTEXT + +echo " " >> ${openarmor_CONF_FILE}.new +if [ "$EMAIL_NOTIFICATION" == "y" ]; then + # Get default email address + echo -n " - What's your e-mail address? " + read EMAIL_ADDRESS < /dev/tty + echo " yes" >> ${openarmor_CONF_FILE}.new + echo " $EMAIL_ADDRESS" >> ${openarmor_CONF_FILE}.new + + # find local smtp server, use it? + + # else enter it manually + echo -n " - What's your SMTP server ip/host? " + read SMTP_SERVER < /dev/tty + echo " $SMTP_SERVER" >> ${openarmor_CONF_FILE}.new + echo " openarmorm@$HOSTNAME" >> ${openarmor_CONF_FILE}.new +else + echo " no" >> ${openarmor_CONF_FILE}.new +fi +echo " " >> ${openarmor_CONF_FILE}.new +echo "" >> ${openarmor_CONF_FILE}.new + + + +# update the rules? +cat $RULES_TEMPLATE >> ${openarmor_CONF_FILE}.new +echo "" >> ${openarmor_CONF_FILE}.new +echo + + + +# where is openarmor + +# run integrity check daemon? +check_input " 3.2- Do you want to run the integrity check daemon? (y/n) [y]:" "y|n" "y" +INTEGRITY_CHECK=$INPUTTEXT +if [ "$INTEGRITY_CHECK" == "y" ]; then + echo "" >> ${openarmor_CONF_FILE}.new + cat $SYSCHECK_TEMPLATE >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new +fi +echo + +# run rootkit detection engine? +check_input " 3.3- Do you want to run the rootkit detection engine? (y/n) [y]:" "y|n" "y" +ROOTCHECK=$INPUTTEXT +if [ "$ROOTCHECK" == "y" ]; then + echo "" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + echo " $openarmor_HOME/etc/shared/rootkit_files.txt" >> ${openarmor_CONF_FILE}.new + echo " $openarmor_HOME/etc/shared/rootkit_trojans.txt" >> ${openarmor_CONF_FILE}.new + echo " $openarmor_HOME/etc/shared/system_audit_rcl.txt" >> ${openarmor_CONF_FILE}.new + echo " $openarmor_HOME/etc/shared/cis_rhel_linux_rcl.txt" >> ${openarmor_CONF_FILE}.new + echo " $openarmor_HOME/etc/shared/cis_rhel5_linux_rcl.txt" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new +else + echo "" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + echo " yes" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new +fi +echo + + +# enable active response +echo " 3.4- Active response allows you to execute a specific + command based on the events received. For example, + you can block an IP address or disable access for + a specific user. + More information at: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + +" +check_input " - Do you want to enable active response? (y/n) [y]:" "y|n" "y" +ACTIVE_RESPONSE=$INPUTTEXT +if [ "$ACTIVE_RESPONSE" == "y" ]; then + echo " - Active response enabled. + + - By default, we can enable the host-deny and the + firewall-drop responses. The first one will add + a host to the /etc/hosts.deny and the second one + will block the host on iptables (if linux) or on + ipfilter (if Solaris, FreeBSD or NetBSD). + - They can be used to stop SSHD brute force scans, + portscans and some other forms of attacks. You can + also add them to block on snort events, for example. + + " + check_input " - Do you want to enable the firewall-drop response? (y/n) [y]:" "y|n" "y" + FIREWALL_DROP=$INPUTTEXT + + if [ "$FIREWALL_DROP" == "y" ]; then + echo " " >> ${openarmor_CONF_FILE}.new + echo " 127.0.0.1" >> ${openarmor_CONF_FILE}.new + echo " ^localhost.localdomain$" >> ${openarmor_CONF_FILE}.new + # Add stuff to whitelist, default w/ local IP + for ip in `awk '/nameserver/ {print $2}' /etc/resolv.conf`; do + echo " $ip" >> ${openarmor_CONF_FILE}.new + done + + check_input " - Do you want to add more IPs to the white list? (y/n)? [n]:" "y|n" "n" + if [ "$INPUTTEXT" == "y" ]; then + echo -n " - IPs (space separated): " + read WHITELIST_IPS < /dev/tty + + for ip in $WHITELIST_IPS; do + echo "$ip" >> ${openarmor_CONF_FILE}.new + done + fi + + echo " " >> ${openarmor_CONF_FILE}.new + + fi + + +fi +echo + +# enable remote syslog? +check_input " 3.5- Do you want to enable remote syslog (port 514 udp)? (y/n) [y]:" "y|n" "y" +if [ "$INPUTTEXT" == "y" ]; then + echo " " >> ${openarmor_CONF_FILE}.new + echo " syslog" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + + echo " " >> ${openarmor_CONF_FILE}.new + echo " secure" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new +fi + +# Email/log alerts +echo " " >> ${openarmor_CONF_FILE}.new +echo " 1" >>${openarmor_CONF_FILE}.new +if [ "$EMAIL_NOTIFICATION" == "y" ]; then + echo " 7" >> ${openarmor_CONF_FILE}.new +fi +echo " " >> ${openarmor_CONF_FILE}.new + +if [ "$ACTIVE_RESPONSE" == "y" ]; then + # Add commands in here + echo "" >> ${openarmor_CONF_FILE}.new + cat ${HOST_DENY_TEMPLATE} >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new + cat ${FIREWALL_DROP_TEMPLATE} >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new + cat ${DISABLE_ACCOUNT_TEMPLATE} >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new + cat ${ROUTENULL_TEMPLATE} >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new + + if [ "$FIREWALL_DROP" = "y" ]; then + echo "" >> ${openarmor_CONF_FILE}.new + cat ${ACTIVE_RESPONSE_TEMPLATE} >> ${openarmor_CONF_FILE}.new + echo "" >> ${openarmor_CONF_FILE}.new + fi + +fi + +# detect log files +echo "" >> ${openarmor_CONF_FILE}.new +echo + +# Syslog +for i in `cat $SYSLOG_TEMPLATE`; do + if [ -f $i ] ; then + echo " -- $i (syslog)" + echo "" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + echo " syslog" >> ${openarmor_CONF_FILE}.new + echo " $i" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + + fi +done + +# Snort +SNORT_FILES=`cat ${SNORT_TEMPLATE}` +for i in ${SNORT_FILES}; do + ls $i > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + + head -n 1 $i|grep "\[**\] "|grep -v "Classification:" > /dev/null + if [ $? = 0 ]; then + echo " snort-full" >> ${openarmor_CONF_FILE}.new + echo " -- $i (snort-full file)" + else + echo " snort-fast" >> ${openarmor_CONF_FILE}.new + echo " -- $i (snort-fast file)" + fi + echo " $i" >>${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + fi +done + +# Apache +APACHE_FILES=`cat ${APACHE_TEMPLATE}` +for i in ${APACHE_FILES}; do + ls $i > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + echo " apache" >> ${openarmor_CONF_FILE}.new + echo " $i" >>${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + + echo " -- $i (apache log)" + fi +done + +# Postgres +PGSQL_FILES=`cat ${PGSQL_TEMPLATE}` +for i in ${PGSQL_FILES}; do + ls $i > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "" >> ${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + echo " postgresql_log" >> ${openarmor_CONF_FILE}.new + echo " $i" >>${openarmor_CONF_FILE}.new + echo " " >> ${openarmor_CONF_FILE}.new + + echo " -- $i (postgresql log)" + fi +done + +# + +echo "" >> ${openarmor_CONF_FILE}.new +mv ${openarmor_CONF_FILE} ${openarmor_CONF_FILE}.bak +mv ${openarmor_CONF_FILE}.new ${openarmor_CONF_FILE} +echo "Configuration complete." +echo + diff --git a/contrib/openarmor-eps.sh b/contrib/openarmor-eps.sh new file mode 100644 index 000000000..b80f4743c --- /dev/null +++ b/contrib/openarmor-eps.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Calculate openarmor events per second +# Author Michael Starks openarmor [at] michaelstarks [dot] com +# License: GPLv3 + +if [ ! -e /etc/openarmor-init.conf ]; then + echo openarmor does not appear to be installed on this system. Goodbye. + exit 1 +else + grep -q agent /etc/openarmor-init.conf && echo This script can only be run on the manager. Goodbye. && exit 1 +fi + +#Reset counters +COUNT=0 +EPSSUM=0 +EPSAVG=0 +#Source openarmor Dir +. /etc/openarmor-init.conf + +for i in $(grep 'Total events for day' ${DIRECTORY}/stats/totals/*/*/openarmor-totals-*.log | cut -d: -f3); do + COUNT=$((COUNT+1)) + DAILYEVENTS=$i + EPSSUM=$(($DAILYEVENTS+$EPSSUM)) +done + +EPSAVG=$(($EPSSUM/$COUNT/(86400))) + +echo Your total lifetime number of events collected is: $EPSSUM +echo Your total daily number of events average is: $(($EPSSUM/$COUNT)) +echo Your daily events per second average is: $EPSAVG diff --git a/contrib/openarmor-pcre2-config.pl b/contrib/openarmor-pcre2-config.pl new file mode 100644 index 000000000..d2b48f721 --- /dev/null +++ b/contrib/openarmor-pcre2-config.pl @@ -0,0 +1,78 @@ +#! /usr/bin/perl -w + +use strict; +use warnings; + +use Cwd qw/getcwd realpath/; +use File::Basename; +use File::Find; +use File::Temp qw/tempfile/; + +my $openarmor_regex_convert = realpath(dirname($0) . '/../src/openarmor-regex-convert'); + +sub get_install_dir () { + open(FILE, '<', 'src/LOCATION') || die("Cannot find INSTALL DIR"); + my $dir = '/var/openarmor'; + + while () { + if (m{^DIR\s*=\s*(["']?)(.*)\g1$}p) { + $dir = $2; + last; + } + } + + return $dir; +} + +my $old_tags = join('|', split(/\n/m, `$openarmor_regex_convert -t`)); + +sub convert_file ($) { + my $filename = shift(); + print("Converting ${filename}...\n"); + + unless (open(SRC, '<', $filename)) { + print(STDERR "Cannot read '${filename}'\n"); + return; + } + my ($tmp_fh, $tmp_filename) = tempfile('tmp-openarmor-config-convert.XXXXX', DIR => '/tmp', SUFFIX => '.xml'); + + while () { + if (m{^(\s*)<\s*($old_tags)([^>]*)>(.*?)<\s*/\s*\g2\s*>}pg) { + my ($indent, $old_type, $options, $old_regex) = ($1, $2, $3, $4); + $old_regex =~ s/'/'\\''/g; + my $out = qx/$openarmor_regex_convert -b -- $old_type '$old_regex'/; + chomp($out); + my ($type, $regex) = split(/ /, $out, 2); + if ($old_regex) { + print($tmp_fh "$indent<$type$options>$regex\n"); + } else { + print($tmp_fh "$indent<$type$options>\n"); + } + } else { + print($tmp_fh $_); + } + } + + close(SRC); + close($tmp_fh); + + rename($tmp_filename, $filename); +} + +sub wanted() { + my $filename = $File::Find::name; + + if ($filename =~ m/[.]xml$/) { + convert_file($filename); + } +} + +my $INSTALL_DIR = get_install_dir(); +if (! -d ${INSTALL_DIR}) { + print(STDERR "Please install openarmor first\n"); + exit(1); +} + +find({wanted => \&wanted, no_chdir => 1}, $INSTALL_DIR); + +exit(0); diff --git a/contrib/openarmor-testing/runtests.py b/contrib/openarmor-testing/runtests.py new file mode 100644 index 000000000..0d46da61a --- /dev/null +++ b/contrib/openarmor-testing/runtests.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +import ConfigParser +import subprocess +import os +import sys +import os.path + + +class openarmorTester(object): + def __init__(self): + self._error = False + self._debug = False + self._quiet = False + self._openarmor_conf = "/var/openarmor/etc/openarmor.conf" + self._base_dir = "/var/openarmor/" + self._openarmor_path = "/var/openarmor/bin/" + self._test_path = "./tests" + + def buildCmd(self, rule, alert, decoder): + cmd = ['%s/openarmor-logtest' % (self._openarmor_path), ] + cmd += ['-q'] + if self._openarmor_conf: + cmd += ["-c", self._openarmor_conf] + if self._base_dir: + cmd += ["-D", self._base_dir] + cmd += ['-U', "%s:%s:%s" % (rule, alert, decoder)] + return cmd + + def runTest(self, log, rule, alert, decoder, section, name, negate=False): + #print self.buildCmd(rule, alert, decoder) + p = subprocess.Popen( + self.buildCmd(rule, alert, decoder), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, + shell=False) + std_out = p.communicate(log)[0] + if (p.returncode != 0 and not negate) or (p.returncode == 0 and negate): + self._error = True + print "" + print "-" * 60 + print "Failed: Exit code = %s" % (p.returncode) + print " Alert = %s" % (alert) + print " Rule = %s" % (rule) + print " Decoder = %s" % (decoder) + print " Section = %s" % (section) + print " line name = %s" % (name) + print " " + print std_out + elif self._debug: + print "Exit code= %s" % (p.returncode) + print std_out + else: + sys.stdout.write(".") + + def run(self, selective_test=False): + for aFile in os.listdir(self._test_path): + aFile = os.path.join(self._test_path, aFile) + if aFile.endswith(".ini"): + if selective_test and not aFile.endswith(selective_test): + continue + print "- [ File = %s ] ---------" % (aFile) + tGroup = ConfigParser.ConfigParser() + tGroup.read([aFile]) + tSections = tGroup.sections() + for t in tSections: + rule = tGroup.get(t, "rule") + alert = tGroup.get(t, "alert") + decoder = tGroup.get(t, "decoder") + for (name, value) in tGroup.items(t): + if name.startswith("log "): + if self._debug: + print "-" * 60 + if name.endswith("pass"): + neg = False + elif name.endswith("fail"): + neg = True + else: + neg = False + self.runTest(value, rule, alert, decoder, + t, name, negate=neg) + print "" + if self._error: + sys.exit(1) + +if __name__ == "__main__": + if len(sys.argv) == 2: + selective_test = sys.argv[1] + if not selective_test.endswith('.ini'): + selective_test += '.ini' + else: + selective_test = False + OT = openarmorTester() + OT.run(selective_test) diff --git a/contrib/openarmor-testing/tests/apache.ini b/contrib/openarmor-testing/tests/apache.ini new file mode 100644 index 000000000..1fd79a6cd --- /dev/null +++ b/contrib/openarmor-testing/tests/apache.ini @@ -0,0 +1,81 @@ +[Attempt to access forbidden directory index.] +log 1 pass = [error] [client 80.230.208.105] Directory index forbidden by rule: /home/ +rule = 30106 +alert = 5 +decoder = apache-errorlog + +[Code Red attack] +log 1 pass = [error] [client 64.94.163.159] Client sent malformed Host header +rule = 30107 +alert = 6 +decoder = apache-errorlog + +[Attempt to access an non-existent file] +log 1 pass = [error] [client 66.31.142.16] File does not exist: /var/www/html/default.ida +rule = 30112 +alert = 0 +decoder = apache-errorlog + +[Apache notice messages grouped] +log 1 pass = [notice] Apache configured +rule = 30103 +alert = 0 +decoder = apache-errorlog + +[Apache 2.2 error messages grouped] +log 1 pass = [Fri Dec 13 06:59:54 2013] [error] [client 12.34.65.78] PHP Notice: +rule = 30101 +alert = 0 +decoder = apache-errorlog + +[Apache 2.4 error messages grouped] +log 1 pass = [Tue Sep 30 11:30:13.262255 2014] [core:error] [pid 20101] [client 99.47.227.95:34567] AH00037: Symbolic link not allowed or link target not accessible: /usr/share/awstats/icon/mime/document.png +log 2 pass = [Tue Sep 30 12:11:21.258612 2014] [ssl:error] [pid 30473] AH02032: Hostname www.example.com provided via SNI and hostname ssl://www.example.com provided via HTTP are different +rule = 30301 +alert = 0 +decoder = apache-errorlog + +[Apache 2.4 warn messages grouped] +log 1 pass = [Tue Sep 30 12:24:22.891366 2014] [proxy:warn] [pid 2331] [client 77.127.180.111:54082] AH01136: Unescaped URL path matched ProxyPass; ignoring unsafe nocanon, referer: http://www.easylinker.co.il/he/links.aspx?user=bguyb +rule = 30302 +alert = 0 +decoder = apache-errorlog + +[Attempt to access forbidden file or directory] +log 1 pass = [Tue Sep 30 14:25:44.895897 2014] [authz_core:error] [pid 31858] [client 99.47.227.95:38870] AH01630: client denied by server configuration: /var/www/example.com/docroot/ +rule = 30305 +alert = 5 +decoder = apache-errorlog + +[Apache messages grouped] +log 1 pass = [Thu Oct 23 15:17:55.926067 2014] [ssl:info] [pid 18838] [client 36.226.119.49:2359] AH02008: SSL library error 1 in handshake (server www.example.com:443) +log 2 pass = [Thu Oct 23 15:17:55.926123 2014] [ssl:info] [pid 18838] SSL Library Error: error:1407609B:SSL routines:SSL23_GET_CLIENT_HELLO:https proxy request -- speaking HTTP to HTTPS port!? +rule = 30100 +alert = 0 +decoder = apache-errorlog + +[PHP Notices in Apache 2.4 errorlog] +log 1 pass = [Sun Nov 23 18:49:01.713508 2014] [:error] [pid 15816] [client 141.8.147.9:51507] PHP Notice: A non well formed numeric value encountered in /path/to/file.php on line 123 +rule = 30318 +alert = 5 +decoder = apache-errorlog + +[auth fail] +log 1 pass = [Tue Feb 07 08:50:22.679122 2017] [auth_basic:error] [pid 14446] [client 10.101.1.50:33168] AH01617: user pupkin: authentication failure for "/secret/": Password Mismatch +rule = 30308 +alert = 5 +decoder = apache-errorlog + +[script 404] +log 1 pass = [Tue Feb 07 02:43:19.799723 2017] [cgi:error] [pid 9721] [client 10.101.1.50:44324] AH02811: script not found or unable to stat: /var/www/html/showmail.pl +rule = 30321 +alert = 2 +decoder = apache-errorlog + +[permission denied] +log 1 pass = [Thu Feb 02 01:44:27.699327 2017] [access_compat:error] [pid 7934] [client ::1:50058] AH01797: client denied by server configuration: /var/www/html/' +log 2 pass = [Thu Feb 02 00:59:02.285651 2017] [core:error] [pid 20009] (13)Permission denied: [client ::1:49934] AH00132: file permissions deny server access: /var/www/html/1 +rule = 30320 +alert = 2 +decoder = apache-errorlog + diff --git a/contrib/openarmor-testing/tests/apparmor.ini b/contrib/openarmor-testing/tests/apparmor.ini new file mode 100644 index 000000000..bcada3d86 --- /dev/null +++ b/contrib/openarmor-testing/tests/apparmor.ini @@ -0,0 +1,35 @@ +[Ignore ALLOWED or STATUS] +log 1 pass = Jun 24 10:35:29 hostname kernel: [49787.970285] audit: type=1400 audit(1403598929.839:88986): apparmor="ALLOWED" operation="getattr" profile="/usr/sbin/dovecot//null-1//null-2//null-4a6" name="/home/admin/mails/new/" pid=19973 comm="imap" requested_mask="r" denied_mask="r" fsuid=1003 ouid=1003 + +rule = 52001 +alert = 0 +decoder = iptables + +[Apparmor ALLOWED or STATUS] +log 1 pass = Jun 23 20:46:15 hostname kernel: [ 11.103248] audit: type=1400 audit(1403549175.177:2): apparmor="STATUS" operation="profile_load" name="/sbin/klogd" pid=2185 comm="apparmor_parser" + +rule = 52001 +alert = 0 +decoder = iptables + +[Apparmor DENIED] +log 1 pass = Jul 14 11:03:47 hostname kernel: [ 8665.951930] type=1400 audit(1405328627.702:54): apparmor="DENIED" operation="open" profile="/usr/bin/evince" name="/etc/xfce4/defaults.list" pid=16418 comm="evince" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 + +rule = 52002 +alert = 3 +decoder = iptables + +[Apparmor DENIED mknod operation.] +log 1 pass = Jun 16 17:37:39 hostname kernel: [891880.587989] audit: type=1400 audit(1314853822.672:33649): apparmor="DENIED" operation="mknod" parent=27250 profile="/usr/lib/apache2/mpm-prefork/apache2//example.com" name="/usr/share/wordpress/1114140474e5f13bea68a4.tmp" pid=27289 comm="apache2" requested_mask="c" denied_mask="c" fsuid=33 ouid=33 + +rule = 52004 +alert = 4 +decoder = iptables + +[Apparmor DENIED exec operation.] +log 1 pass = Jun 16 17:37:39 hostname kernel: [891880.587989] audit: type =1400 audit(1315353795.331:33657): apparmor="DENIED" operation="exec" parent=14952 profile="/usr/lib/apache2/mpm-prefork/apache2//example.com" name="/usr/lib/sm.bin/sendmail" pid=14953 comm="sh" requested_mask="x" denied_mask="x" fsuid=33 ouid=0 + +rule = 52003 +alert = 5 +decoder = iptables + diff --git a/contrib/openarmor-testing/tests/asterisk.ini b/contrib/openarmor-testing/tests/asterisk.ini new file mode 100644 index 000000000..fffff0827 --- /dev/null +++ b/contrib/openarmor-testing/tests/asterisk.ini @@ -0,0 +1,15 @@ +[login failed] +log 1 pass = Aug 29 07:21:05 hostname asterisk[3284]: NOTICE[3734]: chan_sip.c:28088 in handle_request_register: Registration from '"3810" ' failed for '37.8.26.31:5065' - Wrong password +log 2 pass = Dec 16 18:02:04 asterisk1 asterisk[31774]: NOTICE[31787]: chan_sip.c:11242 in handle_request_register: Registration from '"503"' failed for '192.168.1.137' - Wrong password + +rule = 6210 +alert = 5 +decoder = asterisk + +[invalid extension] +log 1 pass = Aug 30 16:02:29 hostname asterisk[3284]: NOTICE[3734][C-00001c7a]: chan_sip.c:25650 in handle_request_invite: Call from '' (89.163.146.112:5071) to extension '70046313115067' rejected because extension not found in context 'default'. + +rule = 6258 +alert = 5 +decoder = asterisk + diff --git a/contrib/openarmor-testing/tests/cimserver.ini b/contrib/openarmor-testing/tests/cimserver.ini new file mode 100644 index 000000000..80717c6ba --- /dev/null +++ b/contrib/openarmor-testing/tests/cimserver.ini @@ -0,0 +1,9 @@ +[rshd: illegal] +log 1 pass = Dec 18 18:06:28 hostname cimserver[18575]: PGS17200: Authentication failed for user jones_b. +log 2 fail = Dec 18 18:06:29 hostname vimserver[18575]: PGS17200: Authentication failed for user domain\jones_b. + + +rule = 9610 +alert = 5 +decoder = cimserver + diff --git a/contrib/openarmor-testing/tests/cisco_ios.ini b/contrib/openarmor-testing/tests/cisco_ios.ini new file mode 100644 index 000000000..e4a7a1e04 --- /dev/null +++ b/contrib/openarmor-testing/tests/cisco_ios.ini @@ -0,0 +1,21 @@ +[cisco ios ids: sig] +log 1 pass = Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:51654 -> 10.10.10.10:4444] +log 2 pass = Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:60797 -> 10.10.10.10:80] +log 3 pass = Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:5123 Subsig:2 Sev:5 WWW IIS Internet Printing Overflow [192.168.100.11:60797 -> 10.10.10.10:80] + + +rule = 20100 +alert = 8 +decoder = cisco-ios + + +[cisco ios: acl ] +log 1 pass = Sep 1 10:25:29 10.10.10.1 %SEC-6-IPACCESSLOGP: list 102 denied tcp 10.0.6.56(3067) -> 172.36.4.7(139), 1 packet +log 2 pass = Sep 1 10:25:29 10.10.10.1 %SEC-6-IPACCESSLOGP: list 199 denied tcp 10.0.61.108(1477) -> 10.0.127.20(445), 1 packet + + +rule = 4100 +alert = 0 +decoder = cisco-ios + + diff --git a/contrib/openarmor-testing/tests/cpanel.ini b/contrib/openarmor-testing/tests/cpanel.ini new file mode 100644 index 000000000..ae036efda --- /dev/null +++ b/contrib/openarmor-testing/tests/cpanel.ini @@ -0,0 +1,38 @@ +[successful login] +log 1 fail = [2016-04-18 13:07:02 -0400] info [cpsrvd] 10.1.5.19 - root - SUCCESS LOGIN whostmgrd +log 2 fail = [2016-04-18 13:07:15 -0400] info [cpsrvd] 10.1.5.19 - reseller (possessor: root) - SUCCESS LOGIN cpaneld +log 3 fail = [2016-04-18 13:08:27 -0400] info [cpsrvd] 10.1.5.19 - emailaccount@reseller.com (possessor: reseller) - SUCCESS LOGIN webmaild + +rule = 11007 +alert = 3 +decoder = postgresql_log + + +[cpanel attacks] +log 1 fail = [2017-01-25 06:01:10 -0500] info [cpsrvd] 10.1.5.19 - test "POST /login/?login_only=1 HTTP/1.1" FAILED LOGIN cpaneld: invalid cpanel user test (loadcpdata failed) + +rule = 11001 +alert = 5 +decoder = postgresql_log + +[cpanel attacks 2] +log 1 fail = [2016-11-18 09:32:19 +0000] info [cpsrvd] 10.1.5.19 - admin "POST /login/?login_only=1 HTTP/1.1" FAILED LOGIN whostmgrd: user password hash is missing from system (user probably does not exist) + +rule = 11000 +alert = 5 +decoder = cpanel-login + +[successful login 2] +log 1 fail = [2016-04-18 13:07:02 +0400] info [cpsrvd] 10.1.5.19 - root - SUCCESS LOGIN whostmgrd + +rule = 11006 +alert = 3 +decoder = cpanel-login + +[session purge] +log 1 fail = [2017-01-25 06:15:38 -0500] info [cpsrvd] 10.1.5.19 PURGE root:Nmm4xzhSpA2Sddv3 logout + +rule = 11009 +alert = 3 +decoder = postgresql_log + diff --git a/contrib/openarmor-testing/tests/dnsmasq.ini b/contrib/openarmor-testing/tests/dnsmasq.ini new file mode 100644 index 000000000..96f2236ef --- /dev/null +++ b/contrib/openarmor-testing/tests/dnsmasq.ini @@ -0,0 +1,9 @@ +[dnsmasq group] +log 1 pass = Jul 17 14:49:57 dnsmasq[15210]: 21745 10.10.10.33/59490 query[A] server.example.com from 10.10.10.33 +log 2 pass = Jul 17 14:49:57 dnsmasq[15210]: 21745 10.10.10.33/59490 forwarded server.example.com to 10.20.20.10 +log 3 pass = Jul 17 14:49:57 dnsmasq[15210]: 21745 10.10.10.33/59490 reply server.example.com is + +rule = 53551 +alert = 0 +decoder = dnsmasq + diff --git a/contrib/openarmor-testing/tests/doas.ini b/contrib/openarmor-testing/tests/doas.ini new file mode 100644 index 000000000..f5535435c --- /dev/null +++ b/contrib/openarmor-testing/tests/doas.ini @@ -0,0 +1,28 @@ +[failed command] +log 1 fail = Apr 13 08:49:20 ix doas: failed command for ddp2: ls + +rule = 51554 +alert = 5 +decoder = doas + +[command run as root] +log 1 fail = Mar 22 07:21:58 ix doas: ddp ran command /bin/ksh as root from /data/ddp/projects/git/sysconf/openarmor/rules + +rule = 51556 +alert = 2 +decoder = doas + +[failed auth] +log 1 fail = Feb 29 14:58:39 ix doas: failed auth for ddp + +rule = 51557 +alert = 5 +decoder = doas + +[doas command run] +log 1 fail = Aug 13 15:16:40 ix doas: ddp ran command as ddpnfs: ls + +rule = 51555 +alert = 1 +decoder = doas + diff --git a/contrib/openarmor-testing/tests/dovecot.ini b/contrib/openarmor-testing/tests/dovecot.ini new file mode 100644 index 000000000..691bc82b1 --- /dev/null +++ b/contrib/openarmor-testing/tests/dovecot.ini @@ -0,0 +1,81 @@ +[auth failed] +log 1 pass = Dec 19 06:21:06 ny dovecot: imap-login: Disconnected (auth failed, 7 attempts in 111 secs): user=, method=PLAIN, rip=109.201.200.201, lip=67.205.141.203, session=<+hgd5vxDBMZtycjJ> +log 2 pass = Jan 11 03:45:09 hostname dovecot: auth-worker(default): sql(username,1.2.3.4): unknown user +log 3 pass = Jan 11 03:42:09 hostname dovecot: auth(default): pam(user@example.com,1.2.3.4): pam_authenticate() failed: User not known to the underlying authentication module + +rule = 9705 +alert = 5 +decoder = dovecot + +[dovecot is starting] +log 1 pass = Jun 17 10:15:24 hostname dovecot: Dovecot v1.2.rc3 starting up (core dumps disabled) + +rule = 9703 +alert = 3 +decoder = dovecot + +[fatal error] +log 1 pass = Jun 17 10:15:24 hostname dovecot: Fatal: auth(default): Support not compiled in for passdb driver 'ldap' +log 2 pass = Jun 17 10:15:24 hostname dovecot: Fatal: Auth process died too early - shutting down + +rule = 9704 +alert = 2 +decoder = dovecot + +[user authentication failure] +log 1 pass = Jun 23 15:04:05 Info: imap-login: Login: user=, method=PLAIN, rip=1.2.3.4, lip=1.2.3.5 Authentication Failure: + +rule = 9770 +alert = 0 +decoder = dovecot-info + +[dovecot auth failed] +log 1 pass = Jan 11 03:42:09 hostname dovecot: auth-worker(default): sql(user@example.com,1.2.3.4): Password mismatch + +rule = 9702 +alert = 5 +decoder = dovecot + +[XXX nothing] +log 1 fail = Jan 07 14:46:28 Warn: auth(default): userdb(username,::ffff:127.0.0.1): user not found from userdb +log 3 fail = May 31 09:43:57 Info: pop3-login: Aborted login (1 authentication attempts): user=, method=PLAIN, rip=::ffff:1.2.3.4, lip=::ffff:1.2.3.5, secured + +rule = 1002 +alert = 2 +decoder = + +[XXX unknown 1002] +log 1 pass = Mar 13 15:25:07 Info: auth(default): pam(user@example.com,::ffff:1.2.3.4): pam_authenticate() failed: User not known to the underlying authentication module + +rule = 9771 +alert = 5 +decoder = dovecot-info + +[session disconnected] +log 1 pass = Jul 4 17:30:51 hostname dovecot[2992]: pop3-login: Disconnected: rip=1.2.3.4, lip=1.2.3.5 + +rule = 9706 +alert = 3 +decoder = dovecot + +[aborted login] +log 1 pass = Jan 30 09:37:55 hostname dovecot: pop3-login: Aborted login: user=, method=PLAIN, rip=::ffff:1.2.3.4, lip=::ffff:1.2.3.5 + +rule = 9707 +alert = 5 +decoder = dovecot + +[XXX logged out] +log 1 fail = Jun 23 15:04:06 Info: IMAP(username): Disconnected: Logged out bytes=59/566 + +rule = 1002 +alert = 2 +decoder = dovecot-info + +[unknown user] +log 1 pass = Mar 13 15:25:07 Info: auth(default): passwd-file(user@example.com,::ffff:1.2.3.4): unknown user + +rule = 9771 +alert = 5 +decoder = dovecot-info + diff --git a/contrib/openarmor-testing/tests/dpkg.ini b/contrib/openarmor-testing/tests/dpkg.ini new file mode 100644 index 000000000..61890b66f --- /dev/null +++ b/contrib/openarmor-testing/tests/dpkg.ini @@ -0,0 +1,8 @@ +[dpkg log] +log 1 pass = 2018-05-31 12:09:56 upgrade vlc-plugin-visualization:amd64 3.0.2-1+b1 3.0.3-1 +log 2 pass = 2018-05-11 09:41:49 conffile /etc/redis/redis.conf keep + +rule = 2900 +alert = 0 +decoder = windows-date-format + diff --git a/contrib/openarmor-testing/tests/dropbear.ini b/contrib/openarmor-testing/tests/dropbear.ini new file mode 100644 index 000000000..b48008ff3 --- /dev/null +++ b/contrib/openarmor-testing/tests/dropbear.ini @@ -0,0 +1,7 @@ +[already listening] +log 1 pass = Jun 25 14:04:30 10.0.0.1 dropbear[30746]: Failed listening on '7001': Error listening: Address already in use + +rule = 51011 +alert = 1 +decoder = dropbear + diff --git a/contrib/openarmor-testing/tests/exim.ini b/contrib/openarmor-testing/tests/exim.ini new file mode 100644 index 000000000..f6853658a --- /dev/null +++ b/contrib/openarmor-testing/tests/exim.ini @@ -0,0 +1,29 @@ +[auth failure] +log 1 pass = 2017-01-23 03:44:14 dovecot_login authenticator failed for (hydra) [10.101.1.18]:35686: 535 Incorrect authentication data (set_id=user) +log 2 pass = 2017-01-24 05:22:29 dovecot_plain authenticator failed for (test) [::1]:39454: 535 Incorrect authentication data (set_id=test) + +rule = 13006 +alert = 5 +decoder = windows-date-format + +[exim connection] +log 1 pass = 2017-01-24 03:09:46 SMTP connection from [10.101.1.10]:55010 (TCP/IP connection count = 1) + +rule = 13008 +alert = 0 +decoder = windows-date-format + +[exim connection lost] +log 1 pass = 2017-01-24 02:53:13 SMTP connection from (hydra) [10.101.1.10]:53682 lost + +rule = 13009 +alert = 1 +decoder = windows-date-format + +[exim syntax/protocol error] +log 1 pass = 2017-01-24 05:36:23 SMTP call from (000000) [::1]:39480 dropped: too many syntax or protocol errors (last command was "123") + +rule = 13010 +alert = 5 +decoder = windows-date-format + diff --git a/contrib/openarmor-testing/tests/firewalld.ini b/contrib/openarmor-testing/tests/firewalld.ini new file mode 100644 index 000000000..ceb925cd2 --- /dev/null +++ b/contrib/openarmor-testing/tests/firewalld.ini @@ -0,0 +1,21 @@ +[Incorrect chain/target/match.] +log 3 fail = Jul 18 10:51:43 localhost firewalld: 2014-07-18 10:51:43 ERROR: '/sbin/iptables -D INPUT_ZONES -t filter -i enp1s0 -g IN_public' failed: iptables: No chain/target/match by that name. + +rule = 40902 +alert = 3 +decoder = + +[Incorrect chain/target/match.] +log 3 fail = Jul 18 10:51:43 localhost firewalld: 2014-07-18 10:51:43 ERROR: COMMAND_FAILED: '/sbin/iptables -D INPUT_ZONES -t filter -i enp1s0 -g IN_public' failed: iptables: No chain/target/match by that name. + +rule = 40902 +alert = 3 +decoder = + +[firewalld: zone already set] +log 3 fail = Jul 18 11:04:51 localhost firewalld: 2014-07-18 11:04:51 ERROR: ZONE_ALREADY_SET + +rule = 40903 +alert = 2 +decoder = + diff --git a/contrib/openarmor-testing/tests/mailscanner.ini b/contrib/openarmor-testing/tests/mailscanner.ini new file mode 100644 index 000000000..725bbbe02 --- /dev/null +++ b/contrib/openarmor-testing/tests/mailscanner.ini @@ -0,0 +1,6 @@ +[update phishing] +log 1 fail = Feb 14 06:29:39 hostname update.bad.phishing.sites: Phishing bad sites list updated +rule = 3752 +alert = 0 +decoder = + diff --git a/contrib/openarmor-testing/tests/modsecurity.ini b/contrib/openarmor-testing/tests/modsecurity.ini new file mode 100644 index 000000000..7331dd217 --- /dev/null +++ b/contrib/openarmor-testing/tests/modsecurity.ini @@ -0,0 +1,20 @@ +[ModSecurity Warning messages grouped] +log 1 pass = [Mon Feb 09 16:47:55.974089 2015] [:error] [pid 17675] [client 172.16.10.87] ModSecurity: Warning. Operator GE matched 4 at TX:outbound_anomaly_score. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_60_correlation.conf"] [line "40"] [id "981205"] [msg "Outbound Anomaly Score Exceeded (score 4): The application is not available"] [hostname "172.16.10.91"] [uri "/wordpress/wp-includes/rss-functions.php"] [unique_id "VNkA238AAQEAAEULYMwAAAAA"] +log 2 pass = [Thu Jan 22 14:33:30.959520 2015] [:error] [pid 2406] [client 172.16.10.87] ModSecurity: Warning. Pattern match "^(?i)(?:ft|htt)ps?(.*?)\\\\?+$" at ARGS:path_prefix. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_40_generic_attacks.conf"] [line "160"] [id "950119"] [rev "2"] [msg "Remote File Inclusion Attack"] [data "Matched Data: http://cirt.net/rfiinc.txt? found within ARGS:path_prefix: http://cirt.net/rfiinc.txt?"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/WEB_ATTACK/RFI"] [hostname "172.16.10.91"] [uri "/wordpress/web/BetaBlockModules//Module/Module.php"] [unique_id "VMEmWn8AAQEAAAlmdHgAAAAI"] +rule = 30401 +alert = 0 +decoder = apache-errorlog + +[ModSecurity Audit log messages grouped] +log 1 pass = [Mon Feb 09 21:17:06.798110 2015] [:error] [pid 8608] [client 172.16.10.57] ModSecurity: Audit log: Failed writing (requested 83 bytes, written 24): No space left on device [hostname "172.16.10.91"] [uri "/403.php"] [unique_id "VNk-8n8AAQEAACGg7LEAAAAE"] +log 2 pass = [Wed Feb 11 19:46:12.759594 2015] [:error] [pid 1130] [client 172.16.10.91] ModSecurity: Audit log: Failed to lock global mutex: Identifier removed [hostname "172.16.10.91"] [uri "/wordpress/wp-cron.php"] [unique_id "VNvLw38AAQEAAARqTXsAAAAD"] +rule = 30403 +alert = 0 +decoder = apache-errorlog + +[ModSecurity rejected a query] +log 1 pass = [Mon Feb 09 16:47:55.908176 2015] [:error] [pid 17679] [client 172.16.10.91] ModSecurity: Access denied with code 403 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "47"] [id "960015"] [rev "1"] [msg "Request Missing an Accept Header"] [severity "NOTICE"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "172.16.10.91"] [uri "/wordpress/wp-cron.php"] [unique_id "VNkA238AAQEAAEUP9hIAAAAI"] +log 2 pass = [Mon Feb 09 16:47:55.973954 2015] [:error] [pid 17675] [client 172.16.10.87] ModSecurity: Access denied with code 403 (phase 4). Pattern match "^5\\\\d{2}$" at RESPONSE_STATUS. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_50_outbound.conf"] [line "53"] [id "970901"] [rev "2"] [msg "The application is not available"] [data "Matched Data: 500 found within RESPONSE_STATUS: 500"] [severity "ERROR"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "WASCTC/WASC-13"] [tag "OWASP_TOP_10/A6"] [tag "PCI/6.5.6"] [hostname "172.16.10.91"] [uri "/wordpress/wp-includes/rss-functions.php"] [unique_id "VNkA238AAQEAAEULYMwAAAAA"] +rule = 30411 +alert = 7 +decoder = apache-errorlog diff --git a/contrib/openarmor-testing/tests/named.ini b/contrib/openarmor-testing/tests/named.ini new file mode 100644 index 000000000..98e3dd654 --- /dev/null +++ b/contrib/openarmor-testing/tests/named.ini @@ -0,0 +1,11 @@ +[Query cache denied] +log 1 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.3#1036: query (cache) denied +log 2 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.4#32769: query (cache) denied +log 3 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.3#1036: query (cache) denied +log 4 fail = Aug 29 15:33:13 ns3 name[464]: client 217.148.39.4#32769: query (cache) denied +log 5 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.3#1036: query (cache) +log 6 pass = Mar 13 01:42:45 net19 named[6147]: client 31.150.218.239#6173 (odcdavcxkvin.games.yuanyou8.com): query (cache) 'odcdavcxkvin.games.yuanyou8.com/A/IN' denied + +rule = 12108 +alert = 5 +decoder = named diff --git a/contrib/openarmor-testing/tests/netscreen.ini b/contrib/openarmor-testing/tests/netscreen.ini new file mode 100644 index 000000000..92de03d80 --- /dev/null +++ b/contrib/openarmor-testing/tests/netscreen.ini @@ -0,0 +1,28 @@ +[Firewall configuration changed.] +log 1 pass = 2014-05-23T10:25:58.681222-04:00 10.10.10.1 ssg5-serial: NetScreen device_id=0275112227993284 [Root]system-information-00767: System configuration saved by netscreen via web from host 10.10.10.101 to 10.10.10.1:443 by netscreen. (2014-05-23 10:58:17) + +rule = 4509 +alert = 8 +decoder = netscreenfw + +[Firewall policy changed.] +log 1 pass = 2014-05-23T10:29:55.704201-04:00 10.10.10.1 ssg5-serial: NetScreen device_id=0275112227993284 [Root]system-notification-00018: Policy (5, Trust->Untrust, 10.10.10.0/24->172.16.19.0/24,ANY, Permit) was modified by netscreen via web from host 10.10.10.101 to 10.10.10.1:443. (2014-05-23 11:02:13) + +rule = 4508 +alert = 8 +decoder = netscreenfw + +[Successfull admin login to the Netscreen firewall] +log 1 pass = 2014-05-23T10:39:20.681154-04:00 10.10.10.1 ssg5-serial: NetScreen device_id=0275112227993284 [Root]system-warning-00515: Management session via SSH from 10.10.10.100:0 for admin netscreen has timed out (2014-05-23 11:11:39) + +rule = 4507 +alert = 8 +decoder = netscreenfw + +[syn flood] +log 1 pass = Jul 7 05:02:34 ssg5.17.168.192.in-addr.arpa ssg5: NetScreen device_id=ssg5 [Root]system-emergency-00005: SYN flood! From 192.168.18.53:41437 to 192.168.17.251:9612, proto TCP (zone Untrust int ethernet0/0). Occurred 1 times. (2016-07-07 05:02:32) + +rule = 4560 +alert = 3 +decoder = netscreenfw + diff --git a/contrib/openarmor-testing/tests/nginx.ini b/contrib/openarmor-testing/tests/nginx.ini new file mode 100644 index 000000000..91aa78035 --- /dev/null +++ b/contrib/openarmor-testing/tests/nginx.ini @@ -0,0 +1,79 @@ +; YYYY/MM/DD HH:MM:SS [LEVEL] PID:TID yadda yadda +[Nginx messages grouped.] +log 1 pass = 2014/12/30 06:07:37 [yadda] 80:2 yadda yadda + +rule = 31300 +alert = 0 +decoder = nginx-errorlog + +[Nginx error message.] +log 1 pass = 2014/12/30 06:07:37 [error] 80:2 yadda yadda + +rule = 31301 +alert = 3 +decoder = nginx-errorlog + +[Nginx warning message.] +log 1 pass = 2014/12/30 06:07:37 [warn] 80:2 yadda yadda + +rule = 31302 +alert = 3 +decoder = nginx-errorlog + +[Nginx critical message.] +log 1 pass = 2014/12/30 06:07:37 [crit] 80:2 + +rule = 31303 +alert = 5 +decoder = nginx-errorlog + +[Server returned 404 (reported in the access.log).] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 blah blah failed (2: No such file or directory) +log 2 pass = 2015/01/08 11:31:23 [error] 80:2 blah blah is not found (2: No such file or directory) + +rule = 31310 +alert = 0 +decoder = nginx-errorlog + +[Incomplete client request.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 blah blah accept() failed (53: Software caused connection abort) + +rule = 31311 +alert = 0 +decoder = nginx-errorlog + +[Initial 401 authentication request.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 no user/password was provided for basic authentication + +rule = 31312 +alert = 0 +decoder = nginx-errorlog + +[Web authentication failed.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 yadda password mismatch, client yadda +log 2 pass = 2015/01/08 11:31:23 [error] 80:2 yadda was not found in yadda + +rule = 31315 +alert = 5 +decoder = nginx-errorlog + +# Can't yet test frequency +;[Multiple web authentication failures.] +; +;rule = 31316 +;alert = 10 +;decoder = nginx-errorlog + +[Common cache error when files were removed.] +log 1 pass = 2015/01/08 11:31:23 [crit] 80:2 yadda yadda failed (2: No such file or directory + +rule = 31317 +alert = 0 +decoder = nginx-errorlog + +[Invalid URI, file name too long.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 yadda yadda failed (36: File name too long) + +rule = 31320 +alert = 10 +decoder = nginx-errorlog diff --git a/contrib/openarmor-testing/tests/openarmor.ini b/contrib/openarmor-testing/tests/openarmor.ini new file mode 100644 index 000000000..55ecefb64 --- /dev/null +++ b/contrib/openarmor-testing/tests/openarmor.ini @@ -0,0 +1,41 @@ +[openarmor: active response: add host] +log 1 pass = Sat May 7 03:17:27 CDT 2011 /var/openarmor/active-response/bin/host-deny.sh add - 172.16.0.1 1304756247.60385 31151 +rule = 603 +alert = 3 +decoder = ar_log + +[openarmor: active response: add firewall] +log 2 pass = Sat May 7 03:17:27 CDT 2011 /var/openarmor/active-response/bin/firewall-drop.sh add - 172.16.0.1 1304756247.60385 31151 +rule = 601 +alert = 3 +decoder = ar_log + + +[openarmor: active response: delete host] +log 3 pass = Sat May 7 03:27:57 CDT 2011 /var/openarmor/active-response/bin/host-deny.sh delete - 172.16.0.1 1304756247.60385 31151 +rule = 604 +alert = 3 +decoder = ar_log + + +[openarmor: active response: delete firewall] +log 4 pass = Sat May 7 03:27:57 CDT 2011 /var/openarmor/active-response/bin/firewall-drop.sh delete - 172.16.0.1 1304756247.60385 31151 + +rule = 602 +alert = 3 +decoder = ar_log + +[openarmor-logcollector: ignore informational messages at startup] +log 1 pass = 2015/01/29 21:09:49 openarmor-logcollector(1950): INFO: Analyzing file: '/var/log/httpd/error_log'. + +rule = 701 +alert = 0 +decoder = openarmor-logcollector + +[agent started] +log 1 pass = openarmor: Agent started: 'any' + +rule = 501 +alert = 3 +decoder = openarmor + diff --git a/contrib/openarmor-testing/tests/openbsd-dhcpd.ini b/contrib/openarmor-testing/tests/openbsd-dhcpd.ini new file mode 100644 index 000000000..799bab627 --- /dev/null +++ b/contrib/openarmor-testing/tests/openbsd-dhcpd.ini @@ -0,0 +1,25 @@ +[lease release] +log 1 pass = Jan 26 18:12:55 junction dhcpd[4842]: IP address 192.168.1.16 answers a ping after sending a release +log 2 pass = Jan 26 18:12:40 junction dhcpd[4842]: Possible release spoof - Not releasing address 192.168.17.160 + +rule = 53003 +alert = 5 +decoder = dhcpd + +[no free leases] +log 1 pass = Jan 26 17:42:32 junction dhcpd[4842]: no free leases on subnet 192.168.17.0 + +rule = 53011 +alert = 7 +decoder = dhcpd + +[normal dhcp stuff] +log 1 pass = Jan 27 09:25:36 junction dhcpd[71391]: DHCPREQUEST for 192.168.17.164 from f4:8c:50:9d:eb:35 via em1 +log 2 pass = Jan 27 09:25:36 junction dhcpd[71391]: DHCPDISCOVER from f4:8c:50:9d:eb:35 via em1 +log 3 pass = Jan 27 09:25:31 junction dhcpd[71391]: DHCPOFFER on 192.168.17.164 to f4:8c:50:9d:eb:35 via em1 + +rule = 53001 +alert = 1 +decoder = dhcpd + + diff --git a/contrib/openarmor-testing/tests/openbsd-httpd.ini b/contrib/openarmor-testing/tests/openbsd-httpd.ini new file mode 100644 index 000000000..5bbdd19ae --- /dev/null +++ b/contrib/openarmor-testing/tests/openbsd-httpd.ini @@ -0,0 +1,14 @@ +[access] +log 1 pass = wafflelab.online 192.168.18.8 - - [08/Jul/2018:00:29:48 -0400] "GET / HTTP/1.0" 302 0 +log 2 pass = wafflelab.online 192.168.18.8 - - [08/Jul/2018:00:32:57 -0400] "GET /nmaplowercheck1531024375 HTTP/1.1" 302 0 +rule = 31100 +alert = 0 +decoder = openbsd-httpd + +[POST] +log 1 pass = www.wafflelab.online 192.168.18.8 - - [08/Jul/2018:00:33:13 -0400] "POST /sdk HTTP/1.1" 404 0 + +rule = 31530 +alert = 3 +decoder = openbsd-httpd + diff --git a/contrib/openarmor-testing/tests/openbsd.ini b/contrib/openarmor-testing/tests/openbsd.ini new file mode 100644 index 000000000..77ae6610d --- /dev/null +++ b/contrib/openarmor-testing/tests/openbsd.ini @@ -0,0 +1,7 @@ +[sendsyslog drop] +log 1 fail = Oct 16 08:15:07 ix sendsyslog: dropped 2 messages, error 55 + +rule = 51558 +alert = 4 +decoder = + diff --git a/contrib/openarmor-testing/tests/opensmtpd.ini b/contrib/openarmor-testing/tests/opensmtpd.ini new file mode 100644 index 000000000..6bb28d562 --- /dev/null +++ b/contrib/openarmor-testing/tests/opensmtpd.ini @@ -0,0 +1,49 @@ +[message failed] +log 1 pass = Aug 14 10:15:25 junction.example.com smtpd[28882]: smtp-in: Failed command on session 1f55bdcdf16e28a3: "MAIL FROM: " => 421 4.3.0: Temporary Error + +rule = 53501 +alert = 3 +decoder = smtpd + +[new session] +log 1 pass = Aug 17 01:26:02 ix smtpd[22704]: smtp-in: New session 08d856b172f69c5c from host ix.example.com [local] + +rule = 53502 +alert = 0 +decoder = smtpd + +[message accepted] +log 1 pass = Aug 17 01:26:02 ix smtpd[22704]: smtp-in: Accepted message 4296f490 on session 08d856b172f69c5c: from=, to=, size=1746, ndest=1, proto=ESMTP + +rule = 53504 +alert = 0 +decoder = smtpd + +[session closed] +log 1 pass = Aug 17 01:26:02 ix smtpd[22704]: smtp-in: Closing session 08d856b172f69c5c + +rule = 53503 +alert = 0 +decoder = smtpd + +[disconnect] +log 1 pass = Mar 4 00:11:00 ix smtpd[22421]: smtp-in: Received disconnect from session 427e7493ebe154ae + +rule = 53500 +alert = 0 +decoder = smtpd + +[no ssl] +log 1 pass = Mar 4 00:13:55 ix smtpd[22421]: smtp-in: Disconnecting session 427e7497e03518ef: IO error: No SSL error + +rule = 53507 +alert = 2 +decoder = smtpd + +[started tls] +log 1 pass = Mar 4 00:13:55 ix smtpd[22421]: smtp-in: Started TLS on session 427e749c2e46f809: version=TLSv1.2, cipher=EDH-RSA-DES-CBC3-SHA, bits=112 + +rule = 53500 +alert = 0 +decoder = smtpd + diff --git a/contrib/openarmor-testing/tests/pam.ini b/contrib/openarmor-testing/tests/pam.ini new file mode 100644 index 000000000..a6e1eaed0 --- /dev/null +++ b/contrib/openarmor-testing/tests/pam.ini @@ -0,0 +1,36 @@ +[User login failed.] +log 1 pass = Nov 11 22:46:29 localhost su(pam_unix)[23164]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=osaudit +log 2 pass = Jun 28 23:01:27 xxxx auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=lipjigaglgihgoeadcdaa.p.salmon@xxx.xxx.xxx.xxx rhost=91.195.103.44 + +rule = 5503 +alert = 5 +decoder = pam + +[Attempt to login with an invalid user.] +log 1 pass = Nov 11 22:46:29 localhost vsftpd(pam_unix)[25073]: check pass; user unknown + +rule = 5504 +alert = 5 +decoder = pam + +[Login session opened.] +log 1 pass = Nov 11 22:46:29 localhost su(pam_unix)[14592]: session opened for user news by (uid=0) + +rule = 5501 +alert = 3 +decoder = pam + +[Login session closed.] +log 1 pass = Nov 11 22:46:29 localhost su(pam_unix)[14592]: session closed for user news + +rule = 5502 +alert = 3 +decoder = pam + +[User missed the password more than one time] +log 1 pass = Nov 11 22:46:29 localhost sshd(pam_unix)[15794]: 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.0.3.1 user=root + +rule = 2502 +alert = 10 +decoder = pam + diff --git a/contrib/openarmor-testing/tests/postfix.ini b/contrib/openarmor-testing/tests/postfix.ini new file mode 100644 index 000000000..f8e45ce12 --- /dev/null +++ b/contrib/openarmor-testing/tests/postfix.ini @@ -0,0 +1,14 @@ +[reject rcpt] +log 1 pass = May 8 08:26:55 mail postfix/postscreen[22055]: NOQUEUE: reject: RCPT from [157.122.148.242]:47407: 550 5.7.1 Service unavailable; client [157.122.148.242] blocked using bl.spamcop.net; from=, to=, proto=ESMTP, helo= + +rule = 3306 +alert = 6 +decoder = postfix-reject + +[domain not found] +log 1 pass = Jun 18 20:59:29 mybox postfix/postscreen[12181]: NOQUEUE: reject: RCPT from [213.158.187.41]:45263: 450 4.3.2 Service currently unavailable; from=, to=, proto=ESMTP, helo= + +rule = 3303 +alert = 5 +decoder = postfix-reject + diff --git a/contrib/openarmor-testing/tests/proftpd.ini b/contrib/openarmor-testing/tests/proftpd.ini new file mode 100644 index 000000000..84a26a281 --- /dev/null +++ b/contrib/openarmor-testing/tests/proftpd.ini @@ -0,0 +1,32 @@ +[unable to open incoming connection (reason may vary)] +log 1 pass = Jan 04 22:51:57 server proftpd[26169] server.example.net: Fatal: unable to open incoming connection: Der Socket ist nicht verbunden +rule = 11222 +alert = 4 +decoder = proftpd + +[FTP Authentication success] +log 1 pass = Jan 04 22:51:57 hayaletgemi proftpd[26916]: hayaletgemi (85.101.218.135[85.101.218.135]) - ANON anonymous: Login successful. +log 2 pass = Jan 04 22:51:57 juf01 proftpd[12564]: juf01 (pD9EE35B1.dip.t-dialin.net[217.238.53.177]) - USER jufu: Login successful +log 3 pass = Jan 04 22:51:57 xx.yy.zz proftpd[30362] xx.yy.zz (aa.bb.cc[aa.bb.vv.dd]): USER backup: Login successful. +rule = 11205 +alert = 3 +decoder = proftpd + +[Connection refused by TCP Wrappers] +log 1 pass = Jan 04 22:51:57 server proftpd[2344]: refused connect from 192.168.1.2 (192.168.1.2) +rule = 11207 +alert = 5 +decoder = proftpd + +[Connection denied by ProFTPD configuration] +log 1 pass = Jan 04 22:51:57 valhalla proftpd[15181]: valhalla (crawl-66-249-66-80.googlebot.com[66.249.66.80]) - Connection from crawl-66-249-66-80.googlebot.com [66.249.66.80] denied. +rule = 11206 +alert = 5 +decoder = proftpd + +[Login failed accessing the FTP server] +log 1 pass = 2015-04-16 21:51:02,805 zuse proftpd[26189] zuse.domain.com (182.100.67.115[182.100.67.115]): USER root (Login failed): Incorrect password +rule = 11204 +alert = 5 +decoder = proftpd + diff --git a/contrib/openarmor-testing/tests/rsh.ini b/contrib/openarmor-testing/tests/rsh.ini new file mode 100644 index 000000000..9804df0c1 --- /dev/null +++ b/contrib/openarmor-testing/tests/rsh.ini @@ -0,0 +1,8 @@ +[rshd: illegal] +log 1 pass = Dec 17 10:49:23 hostname rshd[347339]: Connection from 10.217.223.31 on illegal port +log 2 fail = Dec 17 10:49:23 hostname rhsd[347339]: Connection from 10.217.223.31 on illegal port + +rule = 2551 +alert = 10 +decoder = rshd + diff --git a/contrib/openarmor-testing/tests/samba.ini b/contrib/openarmor-testing/tests/samba.ini new file mode 100644 index 000000000..23a337216 --- /dev/null +++ b/contrib/openarmor-testing/tests/samba.ini @@ -0,0 +1,23 @@ +[samba: denied connect] +log 1 pass = Dec 18 18:06:28 hostname smbd[832]: Denied connection from (192.168.3.23) + + +rule = 13102 +alert = 5 +decoder = smbd + +[samba: connect denied] +log 1 pass = Dec 18 18:06:28 hostname smbd[832]: Denied connection from (192.168.3.23) + + +rule = 13102 +alert = 5 +decoder = smbd + +[samba: permission denied] +log 1 fail = Dec 18 18:06:28 hostname smbd[17535]: Permission denied user not allowed to delete, pause, or resume print job. User name: ahmet. Printer name: prnq1. +log 2 fail = Dec 18 18:06:28 hostname smbd[17535]: Permission denied\-\- user not allowed to delete, pause, or resume print job. User name: ahmet. Printer name: prnq1. + +rule = 13102 +alert = 5 +decoder = smbd diff --git a/contrib/openarmor-testing/tests/sshd.ini b/contrib/openarmor-testing/tests/sshd.ini new file mode 100644 index 000000000..bde0b7d63 --- /dev/null +++ b/contrib/openarmor-testing/tests/sshd.ini @@ -0,0 +1,163 @@ +[SSHD configuration error (AuthorizedKeysCommand)] +log 1 pass = Feb 9 11:44:56 someserver sshd[1234]: error: Could not stat AuthorizedKeysCommand "/usr/local/sbin/ssh-ldap-authorized_keys": No such file or directory + +rule = 5739 +alert = 4 +decoder = sshd + +[ssh connection reset by peer] +log 1 pass = Feb 10 23:21:05 someserver sshd[1234]: Read error from remote host 192.168.1.1: Connection reset by peer + +rule = 5740 +alert = 4 +decoder = sshd + +[ssh connection refused] +log 1 pass = Feb 11 06:41:50 someserver sshd[1234]: debug1: channel 5: connection failed: Connection refused + +rule = 5741 +alert = 4 +decoder = sshd + +[ssh connection timed out] +log 1 pass = Feb 12 17:45:09 someserver sshd[1234]: debug1: channel 3: connection failed: Connection timed out + +rule = 5742 +alert = 4 +decoder = sshd + +[ssh no route to host] +log 1 pass = Jan 30 18:55:24 someserver sshd[1234]: debug1: channel 1: connection failed: No route to host + +rule = 5743 +alert = 4 +decoder = sshd + +[ssh port forwarding issue] +log 1 pass = Feb 13 22:54:51 someserver sshd[1234]: debug1: server_input_channel_open: failure direct-tcpip + +rule = 5744 +alert = 4 +decoder = sshd + +[ssh transport endpoint is not connected] +log 1 pass = Feb 6 12:28:17 someserver sshd[1234]: debug1: getpeername failed: Transport endpoint is not connected + +rule = 5745 +alert = 4 +decoder = sshd + +[ssh get_remote_port failed] +log 1 pass = Feb 6 12:28:17 someserver sshd[1234]: debug1: get_remote_port failed + +rule = 5746 +alert = 4 +decoder = sshd + +[ssh bad client public DH value] +log 1 pass = Feb 4 23:05:57 someserver sshd[1234]: Disconnecting: bad client public DH value [preauth] +log 1 pass = Feb 4 23:05:57 someserver sshd[1234]: Disconnecting: bad client public DH value + +rule = 5747 +alert = 6 +decoder = sshd + +[ssh corrupted MAC on input] +log 1 pass = Feb 14 14:34:15 someserver sshd[1234]: Corrupted MAC on input. [preauth] +log 2 pass = Nov 22 19:24:55 server sshd[4046]: Corrupted MAC on input. + +rule = 5748 +alert = 6 +decoder = sshd + +[ssh bad packet length] +log 1 pass = Mar 4 13:34:59 someserver sshd[5396]: Bad packet length 4081586742. [preauth] +log 2 pass = Mar 4 13:34:59 someserver sshd[5396]: Bad packet length 4081586742. + +rule = 5749 +alert = 4 +decoder = sshd + +[ssh unable to negotiate] +log 1 pass = Mar 3 10:56:18 junction sshd[32065]: fatal: Unable to negotiate with 202.191.177.33 port 3579: no matching cipher found. Their offer: 3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc [preauth] + +rule = 5753 +alert = 2 +decoder = sshd + +[ssh no matching key exchange] +log 1 pass = Sep 16 05:46:56 junction sshd[1961]: fatal: Unable to negotiate with 108.229.36.174: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1 [preauth] +log 2 pass = Apr 18 21:27:08 web2 sshd[23484]: fatal: Unable to negotiate a key exchange method [preauth] + +rule = 5752 +alert = 2 +decoder = sshd + +[invalid user] +log 1 pass = 2013-10-30T14:51:21.901728+01:00 srv sshd[12664]: Postponed keyboard-interactive for invalid user warez from 192.241.237.101 port 54197 ssh2 [preauth] +log 2 pass = 2013-10-30T14:51:24.140565+01:00 srv sshd[12664]: Failed keyboard-interactive/pam for invalid user warez from 192.241.237.101 port 54197 ssh2 +log 3 fail = 2013-10-30T14:51:24.139258+01:00 srv sshd[12664]: error: PAM: User not known to the underlying authentication module for illegal user warez from 192.241.237.101 +log 4 pass = 2013-10-30T14:51:30.267401+01:00 srv sshd[12671]: Invalid user opcione from 192.241.237.101 +log 5 fail = 2013-10-30T14:51:30.267906+01:00 srv sshd[12671]: input_userauth_request: invalid user opcione [preauth] + +rule = 5710 +alert = 5 +decoder = sshd + +[failed to create session] +log 1 pass = May 4 17:48:43 collectd sshd[15044]: pam_systemd(sshd:session): Failed to create session: Access denied + +rule = 5754 +alert = 1 +decoder = sshd + +[bad authorized_keys] +log 1 pass = May 4 18:30:04 collectd sshd[15191]: Authentication refused: bad ownership or modes for file /home/ansible/.ssh/authorized_keys + +rule = 5755 +alert = 2 +decoder = sshd + +[subsystem failed] +log 1 pass = May 5 05:00:38 junction sshd[28395]: subsystem request for netconf by user checker failed, subsystem not found + +rule = 5756 +alert = 0 +decoder = sshd + +[login failed] +log 1 pass = Aug 18 07:30:25 192.168.1.5 sshd[20247]: [ID 800047 auth.notice] Failed none for root from 192.168.1.1 port 36942 ssh2 + +rule = 5716 +alert = 5 +decoder = sshd + +[bad dns] +log 1 pass = Oct 20 12:33:07 ar-agent sshd[3433]: Address 192.168.18.54 maps to nmap.18.168.192.in-addr.arpa, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! + +rule = 5757 +alert = 0 +decoder = sshd + +[max auth attempts] +log 1 pass = Dec 27 03:23:51 r1 sshd[21183]: error: maximum authentication attempts exceeded for root from 183.106.179.x port 34100 ssh2 [preauth] +log 2 fail = Aug 31 10:19:36 hostname sshd[12079]: error: maximum authentication attempts exceeded for invalid user service from 202.188.45.36 port 37313 ssh2 [preauth] + +rule = 5758 +alert = 8 +decoder = sshd + +[bad protocol] +log 1 pass = Jun 28 19:35:39 xxx sshd[30255]: Bad protocol version identification '' from 188.18.81.21 port 60787 + +rule = 5701 +alert = 8 +decoder = sshd + +[blocked by tcpwrapper] +log 1 pass = Aug 30 18:12:54 hostname sshd[25350]: refused connect from 103.79.143.159 (103.79.143.159) + +rule = 2503 +alert = 5 +decoder = sshd + diff --git a/contrib/openarmor-testing/tests/su.ini b/contrib/openarmor-testing/tests/su.ini new file mode 100644 index 000000000..023106b2d --- /dev/null +++ b/contrib/openarmor-testing/tests/su.ini @@ -0,0 +1,27 @@ +[su: failed ] +log 1 pass = Apr 27 15:22:23 niban su[2921936]: failed: ttyq4 changing from ldap to root +log 2 pass = Jun 20 17:19:59 dactyl su: FAILED SU (to root) mmoorcro on pts/0 +rule = 5302 +alert = 9 +decoder = su + +[su: bad pass] +log 1 pass = Apr 27 15:22:23 niban su[234]: BAD SU ger to fwmaster on /dev/ttyp0 +rule = 5301 +alert = 5 +decoder = su + +[su: pam - auth fail] +log 1 fail = Apr 27 15:22:23 niban su(pam_unix)[23164]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=osaudit +log 2 fail = Apr 27 15:22:23 niban su(pam_unix)[2298]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=root +rule = 5503 +alert = 5 +decoder = su + + +[su: work fts] +log 1 pass = Apr 22 17:51:51 enigma su: dcid to root on /dev/ttyp1 +rule = 5305 +alert = 4 +decoder = su + diff --git a/contrib/openarmor-testing/tests/sudo.ini b/contrib/openarmor-testing/tests/sudo.ini new file mode 100644 index 000000000..cea4a17fa --- /dev/null +++ b/contrib/openarmor-testing/tests/sudo.ini @@ -0,0 +1,38 @@ +[sudo: all] +log 1 pass = Apr 27 15:22:23 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/tail /var/log/snort/alert.fast +log 2 pass = Apr 14 10:59:01 enigma sudo: dcid : TTY=ttyp3 ; PWD=/home/dcid/openarmor-hids.0.1a/src/analysisd ; USER=root ; COMMAND=/bin/cp -pr ../../bin/addagent ../../bin/osaudit-logaudit ../../bin/openarmor-execd ../../bin/openarmor-logcollector ../../bin/openarmor-maild ../../bin/openarmor-remoted /var/openarmor/bin +log 3 pass = Apr 19 14:52:02 enigma sudo: dcid : TTY=ttyp3 ; PWD=/var/www/alex ; USER=root ; COMMAND=/sbin/chown dcid.dcid . +log 4 pass = Dec 30 19:36:11 rheltest sudo: cplummer : TTY=pts/2 ; PWD=/home/cplummer1 ; USER=root ; TSID=0000UM ; COMMAND=/bin/bash + +rule = 5403 +alert = 4 +decoder = sudo + +[Failed attempt to run sudo] +log 1 pass = Jun 25 15:51:13 precise32 sudo: mike : 1 incorrect password attempt ; TTY=pts/0 ; PWD=/root ; USER=root ; COMMAND=/bin/ls + +rule = 5401 +alert = 5 +decoder = sudo + +[First time user executed sudo] +log 1 pass = Jun 25 15:48:21 precise32 sudo: mike : TTY=pts/0 ; PWD=/home/vagrant ; USER=root ; COMMAND=/bin/su - + +rule = 5403 +alert = 4 +decoder = sudo + +[3 incorrect password attempts] +log 1 pass = Jun 25 16:15:45 precise32 sudo: mike : 3 incorrect password attempts ; TTY=pts/0 ; PWD=/root ; USER=root ; COMMAND=/bin/ls + +rule = 5404 +alert = 10 +decoder = sudo + +[unauthorized user] +log 1 pass = Apr 13 08:36:31 ix sudo: ddp2 : user NOT in sudoers ; TTY=ttypZ ; PWD=/home/ddp2 ; USER=root ; COMMAND=/bin/ls + +rule = 5405 +alert = 5 +decoder = sudo + diff --git a/contrib/openarmor-testing/tests/syslog.ini b/contrib/openarmor-testing/tests/syslog.ini new file mode 100644 index 000000000..44c202994 --- /dev/null +++ b/contrib/openarmor-testing/tests/syslog.ini @@ -0,0 +1,43 @@ +[Uninteresting nouveau error.] +log 1 fail = Jul 18 09:21:57 localhost kernel: nouveau E[ PGRAPH][0000:0f:00.0] DATA_ERROR BEGIN_END_ACTIVE + +rule = 2944 +alert = 1 +decoder = + +[Uninteresting nouveau error.] +log 1 fail = Jul 18 09:21:57 localhost kernel: nouveau E[ PGRAPH][0000:0f:00.0] DATA_ERROR + +rule = 2944 +alert = 1 +decoder = + +[Incorrect chain/target/match.] +log 3 fail = Jul 18 10:51:43 localhost NetworkManager[1366]: (enp1s0) firewall zone remove failed: (32) COMMAND_FAILED: '/sbin/iptables -D INPUT_ZONES -t filter -i enp1s0 -g IN_public' failed: ipta +bles: No chain/target/match by that name. + +rule = 2941 +alert = 3 +decoder = NetworkManager + +[rsyslog may be dropping messages due to rate-limiting.] +log 1 fail = Feb 5 13:07:52 plugh rsyslogd-2177: imuxsock begins to drop messages from pid 12105 due to rate-limiting + +rule = 2945 +alert = 4 +decoder = + +[Non-standard syslog-ng format with year.] +log 1 fail = 2015 2015 Nov 13 13:40:01 ether rsyslogd-2177: imuxsock begins to drop messages from pid 17840 due to rate-limiting + +rule = 2945 +alert = 4 +decoder = + +[useradd failed] +log 1 fail = May 4 18:21:10 collectd useradd[15178]: failed adding user 'ansible', data deleted + +rule = 5905 +alert = 0 +decoder = + diff --git a/contrib/openarmor-testing/tests/sysmon.ini b/contrib/openarmor-testing/tests/sysmon.ini new file mode 100644 index 000000000..2208b4af1 --- /dev/null +++ b/contrib/openarmor-testing/tests/sysmon.ini @@ -0,0 +1,18 @@ +[Sysmon EventID#1 - Suspicious svchost process] +log 1 pass = 2014 Dec 20 14:29:48 (HME-TEST-01) 10.0.15.14->WinEvtLog 2014 Dec 20 09:29:47 WinEvtLog: Microsoft-Windows-Sysmon/Operational: INFORMATION(1): Microsoft-Windows-Sysmon: SYSTEM: NT AUTHORITY: WIN-U93G48C7BOP: Process Create: UtcTime: 12/20/2014 2:29 PM ProcessGuid: {00000000-87DB-5495-0000-001045F25A00} ProcessId: 3048 Image: C:\Windows\system32\svchost.exe CommandLine: "C:\Windows\system32\NOTEPAD.EXE" C:\Users\Administrator\Desktop\openarmor.log User: WIN-U93G48C7BOP\Administrator LogonGuid: {00000000-84B8-5494-0000-0020CB330200} LogonId: 0x233CB TerminalSessionId: 1 IntegrityLevel: High HashType: SHA1 Hash: 9FEF303BEDF8430403915951564E0D9888F6F365 ParentProcessGuid: {00000000-84B9-5494-0000-0010BE4A0200} ParentProcessId: 848 ParentImage: C:\Windows\Explorer.EXE ParentCommandLine: C:\Windows\Explorer.EXE +rule = 18501 +alert = 12 +decoder = Sysmon-EventID#1 + +[Sysmon EventID#1 - non-Suspicious svchost process] +log 1 pass = 2014 Dec 20 12:15:13 (HME-TEST-01) 10.0.15.14->WinEvtLog 2014 Dec 20 09:29:47 WinEvtLog: Microsoft-Windows-Sysmon/Operational: INFORMATION(1): Microsoft-Windows-Sysmon: SYSTEM: NT AUTHORITY: WIN-U93G48C7BOP: Process Create: UtcTime: 12/20/2014 12:15 PM ProcessGuid: {00000000-87DB-5495-0000-001045F25A00} ProcessId: 3048 Image: C:\Windows\system32\svchost.exe CommandLine: "C:\windows\system32\svchost.exe -k defragsvc" User: NT AUTHORITY\SYSTEM LogonGuid: {00000000-84B8-5494-0000-0020CB330200} LogonId: 0x233CB TerminalSessionId: 1 IntegrityLevel: High HashType: SHA1 Hash: 9FEF303BEDF8430403915951564E0D9888F6F365 ParentProcessGuid: {00000000-84B9-5494-0000-0010BE4A0200} ParentProcessId: 848 ParentImage: C:\Windows\System32\services.exe ParentCommandLine: C:\Windows\System32\services.exe +rule = 18502 +alert = 0 +decoder = Sysmon-EventID#1 + +[Windows Event] +2015 Mar 30 15:47:04 WinEvtLog: System: INFORMATION(1): Sysmon: UserName: SYSTEM-NAME: SYSTEM-NAME: Process Create: UtcTime: 3/30/2015 10:47:04.494 PM ProcessGuid: {7531FA7E-D268-5519-0000-00105DF81A06} ProcessId: 4388 Image: C:\WINDOWS\system32\cmd.exe CommandLine: "C:\windows\system32\cmd.exe" User: SYSTEM-NAME\UserName LogonGuid: {7531FA7E-CFE1-5519-0000-0020F62C1906} LogonId: 0x6192cf6 TerminalSessionId: 3 IntegrityLevel: no level HashType: SHA1 Hash: 254E37EC33C921C5AB253F14F9274F349B3CCC2D ParentProcessGuid: {7531FA7E-CFE2-5519-0000-0010CC5A1906} ParentProcessId: 1008 ParentImage: C:\WINDOWS\explorer.exe ParentCommandLine: C:\windows\Explorer.EXE +rule = 18101 +alert = 0 +decoder = Sysmon-EventID#1 + diff --git a/contrib/openarmor-testing/tests/systemd.ini b/contrib/openarmor-testing/tests/systemd.ini new file mode 100644 index 000000000..73b9f5052 --- /dev/null +++ b/contrib/openarmor-testing/tests/systemd.ini @@ -0,0 +1,7 @@ +[Stale file handle.] +log 3 fail = Jul 19 07:28:02 localhost systemd: Failed to mark scope session-1024.scope as abandoned : Stale file handle + +rule = 40701 +alert = 0 +decoder = + diff --git a/contrib/openarmor-testing/tests/unbound.ini b/contrib/openarmor-testing/tests/unbound.ini new file mode 100644 index 000000000..d82ba1176 --- /dev/null +++ b/contrib/openarmor-testing/tests/unbound.ini @@ -0,0 +1,30 @@ +;[Can't assign requested address.] +;log 1 pass = 2014-05-20T09:01:07.283219-04:00 arrakis unbound: [9405:0] notice: sendto failed: Can't assign requested address +; +;rule = 500100 +;alert = 2 +;decoder = unbound +; +;[DNS A request] +;log 1 pass = 2014-07-14T14:00:02.814490-04:00 arrakis unbound: [2541:0] info: 127.0.0.1 talkgadget.google.com. A IN +; +;rule = 500101 +;alert = 0 +;decoder = unbound +; +;[Info grouping.] +;log 1 pass = 2014-07-14T14:00:05.507848-04:00 arrakis unbound: [2541:0] info: server stats for thread 0: 3 queries, 2 answers from cache, 1 recursions, 0 prefetch +; +;rule = 500002 +;alert = 1 +;decoder = unbound +; +;[Info grouping.] +;log 1 pass = 2014-07-14T14:00:05.507955-04:00 arrakis unbound: [2541:0] info: server stats for thread 0: requestlist max 0 avg 0 exceeded 0 jostled 0 +; +;rule = 500002 +;alert = 1 +;decoder = unbound +; + + diff --git a/contrib/openarmor-testing/tests/vsftpd.ini b/contrib/openarmor-testing/tests/vsftpd.ini new file mode 100644 index 000000000..32edb78c3 --- /dev/null +++ b/contrib/openarmor-testing/tests/vsftpd.ini @@ -0,0 +1,16 @@ +[CONNECT] +log 1 pass = Wed Jul 27 18:32:27 2016 [pid 2] CONNECT: Client "fe80::baac:6fff:fe7d:d2e0" +log 2 pass = Wed Jul 27 18:32:27 2016 [pid 2] CONNECT: Client "10.11.12.13" + +rule = 11401 +alert = 3 +decoder = vsftpd + +[LOGIN] +log 1 pass = Mon Oct 24 11:32:53 2016 [pid 1] [$ALOC$] FAIL LOGIN: Client "10.55.112.101" +log 2 pass = Mon Oct 24 11:32:53 2016 [pid 1] [$ALOC$] FAIL LOGIN: Client "fe80::baac:6fff:fe7d:d2e0" + +rule = 11403 +alert = 5 +decoder = vsftpd + diff --git a/contrib/openarmor-testing/tests/web_appsec.ini b/contrib/openarmor-testing/tests/web_appsec.ini new file mode 100644 index 000000000..22be8005e --- /dev/null +++ b/contrib/openarmor-testing/tests/web_appsec.ini @@ -0,0 +1,161 @@ +[WordPress Comment Spam (coming from a fake search engine UA).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-comments-post.php HTTP/1.1" 403 181 "-" "Googlebot/1 +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-comments-post.php HTTP/1.1" 403 181 "-" "msnbot/1 +log 3 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-comments-post.php HTTP/1.1" 403 181 "-" "BingBot/1 + +rule = 31501 +alert = 6 +decoder = web-accesslog + + +[TimThumb vulnerability exploit attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /examplethumb.php?src=example.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31502 +alert = 6 +decoder = web-accesslog + + +[osCommerce login.php bypass attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /example.php/login.php?cPath= HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31503 +alert = 6 +decoder = web-accesslog + + +[osCommerce file manager login.php bypass attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /admin/example.php/login.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31504 +alert = 6 +decoder = web-accesslog + + +[TimThumb backdoor access attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /example/cache/externalexample.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31505 +alert = 6 +decoder = web-accesslog + + +[Cart.php directory transversal attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /examplecart.php?exampletemplatefile=../ HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31506 +alert = 6 +decoder = web-accesslog + + +[MSSQL Injection attempt (ur.php, urchin.js).] + +rule = 31507 +alert = 6 +decoder = web-accesslog + +[Blacklisted user agent (known malicious user agent).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "ZmEu" +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "libwww-perl/1.1 (X11)" +log 3 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "the beast" +log 4 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "Morfeus" +log 5 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "ZmEu (X11)" +log 6 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "Nikto (X11)" +log 7 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "w3af.sourceforge.net (X11)" +log 8 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "MJ12bot/v (X11)" + +rule = 31508 +alert = 6 +decoder = web-accesslog + + +[CMS (WordPress or Joomla) login attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /example/wp-login.php HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /administrator HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +rule = 31509 +alert = 3 +decoder = web-accesslog + + +# Can't yet test repeat logs +;[CMS (WordPress or Joomla) brute force attempt.] +; +;rule = 31510 +;alert = 8 +;decoder = web-accesslog + +[Blacklisted user agent (wget).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /index.html? HTTP/1.1" 200 4617 "-" "Wget/1.15 (linux-gnu)" + +rule = 31511 +alert = 0 +decoder = web-accesslog + +[Uploadify vulnerability exploit attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /example/uploadify.php?src=http://example.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31512 +alert = 6 +decoder = web-accesslog + +[BBS delete.php exploit attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET example/delete.php?board_skin_path=http://example.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31513 +alert = 6 +decoder = web-accesslog + +[Simple shell.php command execution.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET example/shell.php?cmd= HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31514 +alert = 6 +decoder = web-accesslog + +[PHPMyAdmin scans (looking for setup.php).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" + +rule = 31515 +alert = 6 +decoder = web-accesslog + +[Suspicious URL access.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /db/config.php.swp HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /db/config.php.bak HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 3 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /db/.htaccess HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 4 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /server-status HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 5 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /.ssh HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 6 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /.history HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" + +rule = 31516 +alert = 6 +decoder = web-accesslog + +[POST request received.] +log 1 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST / HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31530 +alert = 3 +decoder = web-accesslog + +[Ignoring often post requests inside /wp-admin and /admin.] +log 1 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-admin HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +log 2 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /admin HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +rule = 31531 +alert = 0 +decoder = web-accesslog + +# Can't currently test repeat requests +;[High amount of POST requests in a small period of time (likely bot).] +;log 1 fail = 10.1.1.5 - - [29/Dec/2014:11:37:47 -0500] POST / HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" +;rule = 31533 +;alert = 10 +;decoder = web-accesslog + +# This never matches due to Rule web_rules.xml id: '31104' Description: 'Common web attack.' +;[Anomaly URL query (attempting to pass null termination).] +;log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /example.php?example%00 HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" +; +;rule = 31550 +;alert = 6 +;decoder = web-accesslog diff --git a/contrib/openarmor-testing/tests/web_rules.ini b/contrib/openarmor-testing/tests/web_rules.ini new file mode 100644 index 000000000..6c3125743 --- /dev/null +++ b/contrib/openarmor-testing/tests/web_rules.ini @@ -0,0 +1,29 @@ +[A web attack returned code 200 (success).] +log 1 pass = 2014-12-20 21:34:37 W3SVC58 XXX-XXWEB-01 1.2.3.4 GET /search/programdetails.aspx id=3542&print=');declare%20@c%20cursor;declare%20@d%20varchar(4000);set%20@c=cursor%20for%20select%20'update%20%5B'%2BTABLE_NAME%2B'%5D%20set%20%5B'%2BCOLUMN_NAME%2B'%5D=%5B'%2BCOLUMN_NAME%2B'%5D%2Bcase%20ABS(CHECKSUM(NewId()))%257%20when%200%20then%20''''%2Bchar(60)%2B''div%20style=%22display:none%22''%2Bchar(62)%2B''abortion%20pill%20prescription%20''%2Bchar(60)%2B''a%20href=%22http:''%2Bchar(47)%2Bchar(47)%2BREPLACE(case%20ABS(CHECKSUM(NewId()))%253%20when%200%20then%20''www.yeronimo.com@template''%20when%201%20then%20''www.tula-point.ru@template''%20else%20''blog.tchami.com@template''%20end,''@'',char(47))%2B''%22''%2Bchar(62)%2Bcase%20ABS(CHECKSUM(NewId()))%253%20when%200%20then%20''online''%20when%201%20then%20''i%20need%20to%20buy%20the%20abortion%20pill''%20else%20''abortion%20pill''%20end%20%2Bchar(60)%2Bchar(47)%2B''a''%2Bchar(62)%2B''%20where%20to%20buy%20abortion%20pill''%2Bchar(60)%2Bchar(47)%2B''div''%2Bchar(62)%2B''''%20else%20''''%20end'%20FROM%20sysindexes%20AS%20i%20INNER%20JOIN%20sysobjects%20AS%20o%20ON%20i.id=o.id%20INNER%20JOIN%20INFORMATION_SCHEMA.COLUMNS%20ON%20o.NAME=TABLE_NAME%20WHERE(indid=0%20or%20indid=1)%20and%20DATA_TYPE%20like%20'%25varchar'%20and(CHARACTER_MAXIMUM_LENGTH=-1%20or%20CHARACTER_MAXIMUM_LENGTH=2147483647);open%20@c;fetch%20next%20from%20@c%20into%20@d;while%20@@FETCH_STATUS=0%20begin%20exec%20(@d);fetch%20next%20from%20@c%20into%20@d;end;close%20@c-- 80 - 173.201.216.6 HTTP/1.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64;+rv:24.0)+Gecko/20100101+Firefox/24.0');declare+@c+cursor;declare+@d+varchar(4000);set+@c=cursor+for+select+'update+['+TABLE_NAME+']+set+['+COLUMN_NAME+']=['+COLUMN_NAME+']+case+ABS(CHECKSUM(NewId()))%7+when+0+then+''''+char(60)+''div+style="display:none"''+char(62)+''abortion+pill+prescription+''+char(60)+''a+href="http:''+char(47)+char(47)+REPLACE(case+ABS(CHECKSUM(NewId()))%3+when+0+then+''www.yeronimo.com@template''+when+1+then+''www.tula-point.ru@template''+else+''blog.tchami.com@template''+end,''@'',char(47))+''"''+char(62)+case+ABS(CHECKSUM(NewId()))%3+when+0+then+''online''+when+1+then+''i+need+to+buy+the+abortion+pill''+else+''abortion+pill''+end++char(60)+char(47)+''a''+char(62)+''+where+to+buy+abortion+pill''+char(60)+char(47)+''div''+char(62)+''''+else+''''+end'+FROM+sysindexes+AS+i+INNER+JOIN+sysobjects+AS+o+ON+i.id=o.id+INNER+JOIN+INFORMATION_SCHEMA.COLUMNS+ON+o.NAME=TABLE_NAME+WHERE(indid=0+or+indid=1)+and+DATA_TYPE+like+'%varchar'+and(CHARACTER_MAXIMUM_LENGTH=-1+or+CHARACTER_MAXIMUM_LENGTH=2147483647);open+@c;fetch+next+from+@c+into+@d;while+@@FETCH_STATUS=0+begin+exec+(@d);fetch+next+from+@c+into+@d;end;close+@c-- - http://google.com');declare+@c+cursor;declare+@d+varchar(4000);set+@c=cursor+for+select+'update+['+TABLE_NAME+']+set+['+COLUMN_NAME+']=['+COLUMN_NAME+']+case+ABS(CHECKSUM(NewId()))%7+when+0+then+''''+char(60)+''div+style="display:none"''+char(62)+''abortion+pill+prescription+''+char(60)+''a+href="http:''+char(47)+char(47)+REPLACE(case+ABS(CHECKSUM(NewId()))%3+when+0+then+''www.yeronimo.com@template''+when+1+then+''www.tula-point.ru@template''+else+''blog.tchami.com@template''+end,''@'',char(47))+''"''+char(62)+case+ABS(CHECKSUM(NewId()))%3+when+0+then+''online''+when+1+then+''i+need+to+buy+the+abortion+pill''+else+''abortion+pill''+end++char(60)+char(47)+''a''+char(62)+''+where+to+buy+abortion+pill''+char(60)+char(47)+''div''+char(62)+''''+else+''''+end'+FROM+sysindexes+AS+i+INNER+JOIN+sysobjects+AS+o+ON+i.id=o.id+INNER+JOIN+INFORMATION_SCHEMA.COLUMNS+ON+o.NAME=TABLE_NAME+WHERE(indid=0+or+indid=1)+and+DATA_TYPE+like+'%varchar'+and(CHARACTER_MAXIMUM_LENGTH=-1+or+CHARACTER_MAXIMUM_LENGTH=2147483647);open+@c;fetch+next+from+@c+into+@d;while+@@FETCH_STATUS=0+begin+exec+(@d);fetch+next+from+@c+into+@d;end;close+@c-- www.somesite.org 200 0 0 36560 3942 78 +rule = 31106 +alert = 6 +decoder = web-accesslog-iis6 + +[NOT A web attack returned code 200 (success).] +log 1 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-admin HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +rule = 31106 +alert = 6 +decoder = web-accesslog + +[A web page returned code 302 code] +log 1 pass = 2015-07-28 15:07:26 1.2.3.4 GET /QOsa/Browser/Default.aspx UISessionId=SN1234123&DeviceId=SN12312232SHARP+MX-4111N 80 - 31.3.3.7 OpenSystems/1.0;+product-family="85";+product-version="123ER123" 302 0 0 624 +rule = 31108 +alert = 0 +decoder = web-accesslog-iis-default + +[A web page returned code 404 (not found)] +log 1 pass = 2015-03-11 21:59:09 1.2.3.4 GET /console/faces/com_sun_web_ui/jsp/version/version_30.jsp - 80 - 31.3.3.7 Sun+Web+Console+Fingerprinter/7.15 - 404 0 2 0 +rule = 31101 +alert = 5 +decoder = web-accesslog-iis-default + +[A web attacked returned code 404] +log 1 pass = 2015-03-11 22:01:59 1.2.3.4 GET /CFIDE/adminapi/customtags/l10n.cfm attributes.id=test&attributes.file=../../administrator/mail/download.cfm&filename=../lib/password.properties&attributes.locale=it&attributes.var=it&attributes.jscript=false&attributes.type=text/html&attributes.charset=UTF-8&thisTag.executionmode=end&thisTag.generatedContent=test 443 - 31.3.3.7 - - 404 0 2 0 +rule = 31104 +alert = 6 +decoder = web-accesslog-iis-default diff --git a/contrib/openarmor2mysql.conf b/contrib/openarmor2mysql.conf new file mode 100644 index 000000000..0e8c4655f --- /dev/null +++ b/contrib/openarmor2mysql.conf @@ -0,0 +1,11 @@ +# PARAMS USED BY openarmor2BASED +dbhost=localhost +database=openarmorbase +debug=5 +dbport=3306 +dbpasswd=yourpassword +dbuser=youruser +daemonize=0 +sensor=centralserver +hids_interface=openarmor +resolve=1 diff --git a/contrib/openarmor2mysql.pl b/contrib/openarmor2mysql.pl new file mode 100644 index 000000000..b5ee3936d --- /dev/null +++ b/contrib/openarmor2mysql.pl @@ -0,0 +1,483 @@ +#!/usr/bin/perl -w +use Socket; +use POSIX 'setsid'; +use strict; +use Regexp::IPv6 qw($IPv6_re); +# --------------------------------------------------------------------------- +# Author: Meir Michanie (meirm@riunx.com) +# Co-Author: J.A.Senger (jorge@br10.com.br) +# $Id$ +# --------------------------------------------------------------------------- +# http://www.riunx.com/ +# --------------------------------------------------------------------------- +# +# --------------------------------------------------------------------------- +# About this script +# --------------------------------------------------------------------------- +# +# "openarmor to Mysql" records the openarmor HIDS alert logs in MySQL database. +# It can run as a daemon (openarmor2mysqld.pl), recording in real-time the logs in database or +# as a simple script (openarmor2mysql.pl). +# +# --------------------------------------------------------------------------- +# Prerequisites +# --------------------------------------------------------------------------- +# +# MySQL Server +# Perl DBD::mysql module +# Perl DBI module +# +# --------------------------------------------------------------------------- +# Installation steps +# --------------------------------------------------------------------------- +# +# 1) Create new database +# 2a) Run openarmor2mysql.sql to create MySQL tables in your database +# 2b) Create BASE tables with snort tables extention +# 3) Create a user to access the database; +# 4) Copy openarmor2mysql.conf to /etc/openarmor2mysql.conf with 0600 permissions +# 3) Edit /etc/openarmor2mysql.conf according to your configuration: +# dbhost=localhost +# database=openarmorbase +# debug=5 +# dbport=3306 +# dbpasswd=mypassword +# dbuser=openarmoruser +# daemonize=0 +# resolve=1 +# +# +# --------------------------------------------------------------------------- +# License +# --------------------------------------------------------------------------- +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# --------------------------------------------------------------------------- +# About openarmor HIDS +# --------------------------------------------------------------------------- +# +# openarmor HIDS is an Open Source Host-based Intrusion Detection System. +# It performs log analysis and correlation, integrity checking, +# rootkit detection, time-based alerting and active response. +# http://www.theopenarmor.org +# +# --------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- +# Parameters +# --------------------------------------------------------------------------- +$SIG{TERM} = sub { &gracefulend('TERM')}; +$SIG{INT} = sub { &gracefulend('INT')}; +my ($RUNASDAEMON)=0; +my ($DAEMONLOGFILE)='/var/log/openarmor2mysql.log'; +my ($DAEMONLOGERRORFILE) = '/var/log/openarmor2mysql.err'; +my ($LOGGER)='openarmor2mysql'; +use openarmormysql; + +my %conf; +$conf{dbhost}='localhost'; +$conf{database}='snort'; +$conf{debug}=5; +$conf{dbport}='3306'; +$conf{dbpasswd}='password'; +$conf{dbuser}='user'; +$conf{daemonize}=0; +$conf{sensor}='sensor'; +$conf{hids_interface}='openarmor'; +$conf{resolve}=1; + + +my($OCT) = '(?:25[012345]|2[0-4]\d|1?\d\d?)'; + +my($IP) = $OCT . '\.' . $OCT . '\.' . $OCT . '\.' . $OCT . '\|' . $IPv6_re; + +my $VERSION="0.4"; +my $sig_class_id=1; +&help() unless @ARGV; +my $dump=0; +my ($hids_id,$hids,$hids_interface,$last_cid)=(undef, 'localhost', 'openarmor',0); +my ($tempvar,$VERBOSE)=(0,0); +# --------------------------------------------------------------------------- +# Arguments parsing +# --------------------------------------------------------------------------- +while (@ARGV){ + $_= shift @ARGV; + if (m/^-d$|^--daemon$/){ + $conf{daemonize}=1; + }elsif ( m/^-h$|^--help$/){ + &help(); + }elsif ( m/^-n$|^--noname$/){ + $conf{'resolve'}=0; + }elsif ( m/^-v$|^--verbose$/){ + $VERBOSE=1; + }elsif ( m/^--interface$/){ + $conf{hids_interface}= shift @ARGV if @ARGV; # openarmor-rt/openarmor-feed + }elsif ( m/^--sensor$/){ + $conf{sensor}= shift @ARGV if @ARGV; # monitor + }elsif ( m/^--conf$/){ + $conf{conf}= shift @ARGV if @ARGV; # localhost + &loadconf(\%conf); + }elsif ( m/^--dbhost$/){ + $conf{dbhost}= shift @ARGV if @ARGV; # localhost + }elsif ( m/^--dbport$/){ + $conf{dbport}= shift @ARGV if @ARGV; # localhost + }elsif ( m/^--dbname$/){ + $conf{database}= shift @ARGV if @ARGV; # snort + }elsif ( m/^--dbuser$/){ + $conf{dbuser}= shift @ARGV if @ARGV; # root + }elsif ( m/^--dbpass$/){ + $conf{dbpasswd}= shift @ARGV if @ARGV; # monitor + } + +} +if ($conf{dbpasswd}=~ m/^--stdin$/){ + print "dbpassword:"; + $conf{dbpasswd}=<>; + chomp $conf{dbpasswd}; +} +$hids=$conf{sensor} if exists($conf{sensor}); +$hids_interface=$conf{hids_interface} if exists($conf{hids_interface}); + +&daemonize() if $conf{daemonize}; +my $dbi= openarmormysql->new(%conf) || die ("Could not connect to $conf{dbhost}:$conf{dbport}:$conf{database} as $conf{dbpasswd}\n"); +#### +# SQL vars; +my ($query,$numrows,$row_ref); +#### +#get sensor id +$query= 'select sid,last_cid from sensor where hostname=? and interface=?'; +$numrows= $dbi->execute($query,$hids,$hids_interface); +if (1==$numrows){ + $row_ref=$dbi->{sth}->fetchrow_hashref; + $hids_id=$row_ref->{sid}; + $last_cid=$row_ref->{last_cid}; +}else{ + $query="INSERT INTO sensor ( sid , hostname , interface , filter , detail , encoding , last_cid ) +VALUES ( +NULL , ?, ? , NULL , ? , ?, ? +)"; + $numrows= $dbi->execute($query,$hids,$hids_interface,1,2,0); + $hids_id=$dbi->lastid(); +} +$dbi->{sth}->finish; +&forceprintlog ("SENSOR:$hids; feed:$hids_interface; id:$hids_id; last cid:$last_cid"); + +my $newrecord=0; +my %stats; +my %resolv; +my ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description, + $srcip,$dstip,$user,$text)=(); +my $lasttimestamp=0; +my $delta=0; +######################################################## +my $datepath=`date "+%Y/%b/openarmor-alerts-%d.log"`; +my $LOG='/var/openarmor/logs/alerts/'. $datepath; +chomp $LOG; +&taillog($last_cid,$LOG); +################################################################ +sub forceprintlog(){ + $tempvar=$VERBOSE; + $VERBOSE=1; + &printlog (@_); + $VERBOSE=$tempvar; +} + + +sub taillog { + my ($last_cid,$LOG)=@_; + while (<>) { + if (m/^$/){ + $newrecord=1; + next unless $timestamp; + $alerthostip=$alerthost if $alerthost=~ m/^$IP$/; + if ($alerthostip){ + $dstip=$alerthostip; + $resolv{$alerthost}=$dstip; + }else{ + if (exists $resolv{$alerthost}){ + $dstip=$resolv{$alerthost}; + }else{ + if ($conf{'resolve'}){ + $dstip=`host $alerthost 2>/dev/null | grep 'has address\|has IPv6 address' `; + if ($dstip =~m/($IP)/ ){ + $dstip=$1; + }else{ + $dstip=$srcip; + } + }else{ + $dstip=$alerthost; + } + $resolv{$alerthost}=$dstip; + + } + } + # + $last_cid= &prepair2basedata( + $hids_id, + $last_cid, + $timestamp, + $sec, + $mail, + $date, + $alerthost, + $datasource, + $rule, + $level, + $description, + $srcip, + $dstip, + $user, + $text + ); + ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description, + $srcip,$dstip,$user,$text)=(); + next ; + } + if (m/^\*\* Alert ([0-9]+).([0-9]+):(.*)$/){ + $timestamp=$1; + if ( $timestamp == $lasttimestamp){ + $delta++; + }else{ + $delta=0; + $lasttimestamp=$timestamp; + } + $sec=$2; + $mail=$3; + $mail=$mail ? $mail : 'nomail'; +#2006 Aug 29 17:19:52 firewall -> /var/log/messages +#2006 Aug 30 11:52:14 192.168.0.45->/var/log/secure +#2006 Sep 12 11:12:16 92382-Snort1 -> 172.16.176.132 +# + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+(\S+)\s*->(.*)$/){ + $date=$1; + $alerthost=$2; + $datasource=$3; + if ($datasource=~ m/($IP)/){ + $alerthost=$1; + $datasource="remoted"; + } + + +#2006 Aug 29 17:33:31 (recepcao) 10.0.3.154 -> syscheck + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+\((.*?)\)\s+(\S+)\s*->(.*)$/){ + $date=$1; + $alerthost=$2; + $alerthostip=$3; + $datasource=$4; + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s(.*?)$/){ + $date=$1; + $alerthost='localhost'; + $datasource=$2; + }elsif ( m/Rule: ([0-9]+) \(level ([0-9]+)\) -> (.*)$/ ){ + $rule=$1; + $level=$2; + $description= $3; + }elsif ( m/Src IP:/){ + if ( m/Src IP: (\S+)/){ + $srcip=$1; + }else{ + $srcip=''; + } + }elsif ( m/User: (.*)$/){ + $user=$1; + }elsif( m/(.*)$/){ + $text .=$1; + } + + + } # End while read line +} + + +sub prepair2basedata(){ + my ( + $hids_id, + $last_cid, + $timestamp, + $sec, + $mail, + $date, + $alerthost, + $datasource, + $rule, + $level, + $description, + $srcip, + $dstip, + $user, + $text + )=@_; + my ($count,$query,$row_ref,$sig_id); +### +# +# Get/Set signature id + $query = "SELECT sig_id FROM signature where sig_name=? and sig_class_id=? and sig_priority=? and sig_rev=? and sig_sid=? and sig_gid is NULL"; + $dbi->execute($query,$description,1,$level,0,$rule); + $count=$dbi->{sth}->rows; + if ($count){ + $row_ref=$dbi->{sth}->fetchrow_hashref; + $sig_id=$row_ref->{sig_id}; + &printlog ("REUSING SIGNATURE\n"); + }else{ + $query="INSERT INTO signature ( sig_id , sig_name , sig_class_id , sig_priority , sig_rev , sig_sid , sig_gid ) +VALUES ( +NULL ,?, ? , ? , ? , ?, NULL +)"; + $dbi->execute($query,$description,1,$level,0,$rule); + $sig_id = $dbi->lastid(); + } +$dbi->{sth}->finish; +&printlog ("SIGNATURE: $sig_id\n"); +####### +# +# Set event + $query="INSERT INTO event ( sid , cid , signature , timestamp ) +VALUES ( +? , ? , ? ,? +)"; + $last_cid++; + $dbi->execute($query,$hids_id,$last_cid,$sig_id,&fixdate2base($date)); + +&printlog ("EVENT: ($query,$hids_id,$last_cid,$sig_id,&fixdate2base($date)\n"); +$dbi->{sth}->finish; +######### +# +# Set acid_event + $query=" INSERT INTO acid_event ( sid , cid , signature , sig_name , sig_class_id , sig_priority , timestamp , ip_src , ip_dst , ip_proto , layer4_sport , layer4_dport ) +VALUES ( +? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ?, ? +) "; + $dbi->execute($query,$hids_id,$last_cid,$sig_id,$description,1,$level,&fixdate2base($date),$srcip,$dstip,undef,undef,undef); +&printlog ("ACID_EVENT: ($query,$hids_id,$last_cid,$sig_id,$description,1,$level,&fixdate2base($date),$srcip,$dstip,undef,undef)\n"); +$dbi->{sth}->finish; + +######### +# +# +# Set data + $text = "** Alert $timestamp.$sec:\t$mail\n$date $alerthost -> $datasource\nRule: $rule (level $level) -> $description\nSrc IP: ($srcip)\nUser: $user\n$text"; + $query=" INSERT INTO data ( sid , cid , data_payload ) +VALUES ( +?,?,?)"; + $dbi->execute($query,$hids_id,$last_cid,$text); +&printlog ("DATA: ($query,$hids_id,$last_cid,$text)\n"); +$dbi->{sth}->finish; +########## +# + $query="UPDATE sensor SET last_cid=? where sid=? limit 1"; + $numrows= $dbi->execute($query,$last_cid,$hids_id); +# end sub +$dbi->{sth}->finish; +return $last_cid; +} + +sub fixdate2base(){ + my ($date)=@_; + $date=~ s/ Jan /-01-/; + $date=~ s/ Feb /-02-/; + $date=~ s/ Mar /-03-/; + $date=~ s/ Apr /-04-/; + $date=~ s/ May /-05-/; + $date=~ s/ Jun /-06-/; + $date=~ s/ Jul /-07-/; + $date=~ s/ Aug /-08-/; + $date=~ s/ Sep /-09-/; + $date=~ s/ Oct /-10-/; + $date=~ s/ Nov /-11-/; + $date=~ s/ Dec /-12-/; + $date=~ s/\s$//g; + return $date; +} +sub version(){ + print "openarmor report tool $VERSION\n"; + print "Licensed under GPL\n"; + print "Contributor Meir Michanie\n"; +} + +sub help(){ + &version(); + print "This tool helps you import into base the alerts generated by openarmor." + . " More info in the doc directory .\n"; + print "Usage:\n"; + print "$0 [-h|--help] # This text you read now\n"; + print "Options:\n"; + print "\t--dbhost \n"; + print "\t--dbname \n"; + print "\t--dbport <[0-9]+>\n"; + print "\t--dbpass \n"; + print "\t--dbuser \n"; + print "\t-d|--daemonize\n"; + print "\t-n|--noname\n"; + print "\t-v|--verbose\n"; + print "\t--conf \n"; + print "\t--sensor \n"; + print "\t--interface \n"; + + exit 0; +} + + +sub daemonize { + chdir '/' or die "Can't chdir to /: $!"; + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDOUT, ">>$DAEMONLOGFILE" + or die "Can't write to $DAEMONLOGFILE: $!"; + defined(my $pid = fork) or die "Can't fork: $!"; + if ($pid){ + open (PIDFILE , ">/var/run/openarmor2base2.pid") ; + print PIDFILE "$pid\n"; + close (PIDFILE); + exit 0; + } + setsid or die "Can't start a new session: $!"; + open STDERR, ">>$DAEMONLOGERRORFILE" or die "Can't write to $DAEMONLOGERRORFILE: $!"; +} + +sub gracefulend(){ + my ($signal)=@_; + &forceprintlog ("Terminating upon signal $signal"); + &forceprintlog ("Daemon halted"); + close STDOUT; + close STDERR; + exit 0; +} + +sub printlog(){ + return unless $VERBOSE; + my (@lines)=@_; + foreach my $line(@lines){ + chomp $line; + my ($date)=scalar localtime; + $date=~ s/^\S+\s+(\S+.*\s[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}).*$/$1/; + print "$date $LOGGER: $line\n"; + } +} + + +sub loadconf(){ + my ($hash_ref)=@_; + my $conf=$hash_ref->{conf}; + unless (-f $conf) { &printlog ("ERROR: I can't find config file $conf"); exit 1;} + unless (open ( CONF , "$conf")){ &printlog ("ERROR: I can't open file $conf");exit 1;} + while (){ + next if m/^$|^#/; + if ( m/^(\S+)\s?=\s?(.*?)$/) { + $hash_ref->{$1} = $2; + } + } + close CONF; +} + diff --git a/contrib/openarmor2mysql.sql b/contrib/openarmor2mysql.sql new file mode 100644 index 000000000..40f934b9e --- /dev/null +++ b/contrib/openarmor2mysql.sql @@ -0,0 +1,96 @@ + +-- +-- Table structure for table `acid_event` +-- + +CREATE TABLE `acid_event` ( + `sid` int(10) unsigned NOT NULL, + `cid` int(10) unsigned NOT NULL, + `signature` varchar(255) NOT NULL, + `sig_name` varchar(255) default NULL, + `sig_class_id` int(10) unsigned default NULL, + `sig_priority` int(10) unsigned default NULL, + `timestamp` datetime NOT NULL, + `ip_src` int(10) unsigned default NULL, + `ip_dst` int(10) unsigned default NULL, + `ip_proto` int(11) default NULL, + `layer4_sport` int(10) unsigned default NULL, + `layer4_dport` int(10) unsigned default NULL, + `username` varchar(255) default NULL, + PRIMARY KEY (`sid`,`cid`), + KEY `signature` (`signature`), + KEY `sig_name` (`sig_name`), + KEY `sig_class_id` (`sig_class_id`), + KEY `sig_priority` (`sig_priority`), + KEY `timestamp` (`timestamp`), + KEY `ip_src` (`ip_src`), + KEY `ip_dst` (`ip_dst`), + KEY `ip_proto` (`ip_proto`), + KEY `layer4_sport` (`layer4_sport`), + KEY `layer4_dport` (`layer4_dport`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `data` +-- + +CREATE TABLE `data` ( + `sid` int(10) unsigned NOT NULL, + `cid` int(10) unsigned NOT NULL, + `data_payload` text, + PRIMARY KEY (`sid`,`cid`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `event` +-- + +CREATE TABLE `event` ( + `sid` int(10) unsigned NOT NULL, + `cid` int(10) unsigned NOT NULL, + `signature` int(10) unsigned NOT NULL, + `timestamp` datetime NOT NULL, + PRIMARY KEY (`sid`,`cid`), + KEY `sig` (`signature`), + KEY `time` (`timestamp`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `sensor` +-- + +CREATE TABLE `sensor` ( + `sid` int(10) unsigned NOT NULL auto_increment, + `hostname` text, + `interface` text, + `filter` text, + `detail` tinyint(4) default NULL, + `encoding` tinyint(4) default NULL, + `last_cid` int(10) unsigned NOT NULL, + PRIMARY KEY (`sid`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `signature` +-- + +CREATE TABLE `signature` ( + `sig_id` int(10) unsigned NOT NULL auto_increment, + `sig_name` varchar(255) NOT NULL, + `sig_class_id` int(10) unsigned NOT NULL, + `sig_priority` int(10) unsigned default NULL, + `sig_rev` int(10) unsigned default NULL, + `sig_sid` int(10) unsigned default NULL, + `sig_gid` int(10) unsigned default NULL, + PRIMARY KEY (`sig_id`), + KEY `sign_idx` (`sig_name`(20)), + KEY `sig_class_id_idx` (`sig_class_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=47 ; diff --git a/contrib/openarmor2mysqld.pl b/contrib/openarmor2mysqld.pl new file mode 100644 index 000000000..d3f7f27ed --- /dev/null +++ b/contrib/openarmor2mysqld.pl @@ -0,0 +1,513 @@ +#!/usr/bin/perl -w +use strict; +use Socket; +use POSIX 'setsid'; +use Regexp::IPv6 qw($IPv6_re); +# --------------------------------------------------------------------------- +# Author: Meir Michanie (meirm@riunx.com) +# Co-Author: J.A.Senger (jorge@br10.com.br) +# $Id$ +# $Revision$ +## --------------------------------------------------------------------------- +# http://www.riunx.com/ +# --------------------------------------------------------------------------- +# +# --------------------------------------------------------------------------- +# About this script +# --------------------------------------------------------------------------- +# +# "openarmor to Mysql" records the openarmor HIDS alert logs in MySQL database. +# It can run as a daemon (openarmor2mysqld.pl), recording in real-time the logs in database or +# as a simple script (openarmor2mysql.pl). +# +# --------------------------------------------------------------------------- +# Prerequisites +# --------------------------------------------------------------------------- +# +# MySQL Server +# Perl DBD::mysql module +# Perl DBI module +# +# --------------------------------------------------------------------------- +# Installation steps +# --------------------------------------------------------------------------- +# +# 1) Create new database +# 2a) Run openarmor2mysql.sql to create MySQL tables in your database +# 2b) Create BASE tables with snort tables extention +# 3) Create a user to access the database; +# 4) Copy openarmor2mysql.conf to /etc/openarmor2mysql.conf with 0600 permissions +# 3) Edit /etc/openarmor2mysql.conf according to your configuration: +# dbhost=localhost +# database=openarmorbase +# debug=5 +# dbport=3306 +# dbpasswd=mypassword +# dbuser=openarmoruser +# daemonize=0 +# resolve=1 +# +# +# --------------------------------------------------------------------------- +# License +# --------------------------------------------------------------------------- +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# --------------------------------------------------------------------------- +# About openarmor HIDS +# --------------------------------------------------------------------------- +# +# openarmor HIDS is an Open Source Host-based Intrusion Detection System. +# It performs log analysis and correlation, integrity checking, +# rootkit detection, time-based alerting and active response. +# http://www.theopenarmor.org +# +# --------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- +# Parameters +# --------------------------------------------------------------------------- +$SIG{TERM} = sub { &gracefulend('TERM')}; +$SIG{INT} = sub { &gracefulend('INT')}; +my ($RUNASDAEMON)=0; +my ($DAEMONLOGFILE)='/var/log/openarmor2mysql.log'; +my ($DAEMONLOGERRORFILE) = '/var/log/openarmor2mysql.err'; +my ($LOGGER)='openarmor2mysql'; +use openarmormysql; + +my %conf; +$conf{dbhost}='localhost'; +$conf{database}='snort'; +$conf{debug}=5; +$conf{dbport}='3306'; +$conf{dbpasswd}='password'; +$conf{dbuser}='user'; +$conf{daemonize}=0; +$conf{sensor}='sensor'; +$conf{hids_interface}='openarmor'; +$conf{resolve}=1; + + +my($OCT) = '(?:25[012345]|2[0-4]\d|1?\d\d?)'; + +my($IP) = $OCT . '\.' . $OCT . '\.' . $OCT . '\.' . $OCT . '\|' . $IPv6_re; + +my $VERSION="0.4"; +my $sig_class_id=1; +&help() unless @ARGV; +my $dump=0; +my ($hids_id,$hids,$hids_interface,$last_cid)=(undef, 'localhost', 'openarmor',0); +my ($tempvar,$VERBOSE)=(0,0); +# --------------------------------------------------------------------------- +# Arguments parsing +# --------------------------------------------------------------------------- + +while (@ARGV){ + $_= shift @ARGV; + if (m/^-d$|^--daemon$/){ + $conf{daemonize}=1; + }elsif ( m/^-h$|^--help$/){ + &help(); + }elsif ( m/^-n$|^--noname$/){ + $conf{'resolve'}=0; + }elsif ( m/^-v$|^--verbose$/){ + $VERBOSE=1; + }elsif ( m/^--interface$/){ + $conf{hids_interface}= shift @ARGV if @ARGV; # openarmor-rt/openarmor-feed + }elsif ( m/^--sensor$/){ + $conf{sensor}= shift @ARGV if @ARGV; # monitor + }elsif ( m/^--conf$/){ + $conf{conf}= shift @ARGV if @ARGV; # localhost + &loadconf(\%conf); + }elsif ( m/^--dbhost$/){ + $conf{dbhost}= shift @ARGV if @ARGV; # localhost + }elsif ( m/^--dbport$/){ + $conf{dbport}= shift @ARGV if @ARGV; # localhost + }elsif ( m/^--dbname$/){ + $conf{database}= shift @ARGV if @ARGV; # snort + }elsif ( m/^--dbuser$/){ + $conf{dbuser}= shift @ARGV if @ARGV; # root + }elsif ( m/^--dbpass$/){ + $conf{dbpasswd}= shift @ARGV if @ARGV; # monitor + } + +} +if ($conf{dbpasswd}=~ m/^--stdin$/){ + print "dbpassword:"; + $conf{dbpasswd}=<>; + chomp $conf{dbpasswd}; +} +$hids=$conf{sensor} if exists($conf{sensor}); +$hids_interface=$conf{hids_interface} if exists($conf{hids_interface}); + +&daemonize() if $conf{daemonize}; +my $dbi= openarmormysql->new(%conf) || die ("Could not connect to $conf{dbhost}:$conf{dbport}:$conf{database} as $conf{dbpasswd}\n"); +#### +# SQL vars; +my ($query,$numrows,$row_ref); +#### +#get sensor id +$query= 'select sid,last_cid from sensor where hostname=? and interface=?'; +$numrows= $dbi->execute($query,$hids,$hids_interface); +if (1==$numrows){ + $row_ref=$dbi->{sth}->fetchrow_hashref; + $hids_id=$row_ref->{sid}; + $last_cid=$row_ref->{last_cid}; +}else{ + $query="INSERT INTO sensor ( sid , hostname , interface , filter , detail , encoding , last_cid ) +VALUES ( +NULL , ?, ? , NULL , ? , ?, ? +)"; + $numrows= $dbi->execute($query,$hids,$hids_interface,1,2,0); + $hids_id=$dbi->lastid(); +} +$dbi->{sth}->finish; +&forceprintlog ("SENSOR:$hids; feed:$hids_interface; id:$hids_id; last cid:$last_cid"); +#exit ; + +my $newrecord=0; +my %stats; +my %resolv; +my ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description, + $srcip,$dstip,$user,$text)=(); +my $lasttimestamp=0; +my $delta=0; +######################################################## +my $datepath=`date "+%Y/%b/openarmor-alerts-%d.log"`; +my $LOG='/var/openarmor/logs/alerts/'. $datepath; +chomp $LOG; +&taillog($last_cid,$LOG); +############################################################### +sub forceprintlog(){ + $tempvar=$VERBOSE; + $VERBOSE=1; + &printlog (@_); + $VERBOSE=$tempvar; +} +sub taillog { + my ($last_cid,$LOG)=@_; + my($offset, $line, $stall) = ''; + + $offset = (-s $LOG); # Don't start at beginning, go to end + + while (1==1) { + sleep(1); + %resolv=(); + $| = 1; + $stall += 1; + $datepath=`date "+%Y/%b/openarmor-alerts-%d.log"`; + $LOG='/var/openarmor/logs/alerts/'. $datepath; + chomp $LOG; + unless ( -f $LOG){&forceprintlog ("Error -f $LOG"); next; } + if ((-s $LOG) < $offset) { + &forceprintlog ("Log shrunk, resetting.."); + $offset = 0; + } + + unless (open(TAIL, $LOG)){ &forceprintlog ("Error opening $LOG: $!\n");next ;} + + if (seek(TAIL, $offset, 0)) { + # found offset, log not rotated + } else { + # log reset, follow + $offset=0; + seek(TAIL, $offset, 0); + } + while () { + if (m/^$/){ + $newrecord=1; + next unless $timestamp; + $alerthostip=$alerthost if $alerthost=~ m/^$IP$/; + if ($alerthostip){ + $dstip=$alerthostip; + $resolv{$alerthost}=$dstip; + }else{ + if (exists $resolv{$alerthost}){ + $dstip=$resolv{$alerthost}; + }else{ + if ($conf{'resolve'}){ + $dstip=`host $alerthost 2>/dev/null | grep 'has address\|has IPv6 address' `; + if ($dstip =~m/($IP)/ ){ + $dstip=$1; + }else{ + $dstip=$srcip; + } + }else{ + $dstip=$alerthost; + } + $resolv{$alerthost}=$dstip; + + } + } + $last_cid= &prepair2basedata( + $hids_id, + $last_cid, + $timestamp, + $sec, + $mail, + $date, + $alerthost, + $datasource, + $rule, + $level, + $description, + $srcip, + $dstip, + $user, + $text + ); + ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description, + $srcip,$dstip,$user,$text)=(); + next ; + } + if (m/^\*\* Alert ([0-9]+).([0-9]+):(.*)$/){ + $timestamp=$1; + if ( $timestamp == $lasttimestamp){ + $delta++; + }else{ + $delta=0; + $lasttimestamp=$timestamp; + } + $sec=$2; + $mail=$3; + $mail=$mail ? $mail : 'nomail'; +#2006 Aug 29 17:19:52 firewall -> /var/log/messages +#2006 Aug 30 11:52:14 192.168.0.45->/var/log/secure +#2006 Sep 12 11:12:16 92382-Snort1 -> 172.16.176.132 +# + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+(\S+)\s*->(.*)$/){ + $date=$1; + $alerthost=$2; + $datasource=$3; + if ($datasource=~ m/($IP)/){ + $alerthost=$1; + $datasource="remoted"; + } + +#2006 Aug 29 17:33:31 (recepcao) 10.0.3.154 -> syscheck + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+\((.*?)\)\s+(\S+)\s*->(.*)$/){ + $date=$1; + $alerthost=$2; + $alerthostip=$3; + $datasource=$4; + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s(.*?)$/){ + $date=$1; + $alerthost='localhost'; + $datasource=$2; + }elsif ( m/Rule: ([0-9]+) \(level ([0-9]+)\) -> (.*)$/ ){ + $rule=$1; + $level=$2; + $description= $3; + }elsif ( m/Src IP:/){ + if ( m/Src IP: (\S+)/){ + $srcip=$1; + }else{ + $srcip=''; + } + }elsif ( m/User: (.*)$/){ + $user=$1; + }elsif( m/(.*)$/){ + $text .=$1; + } + + + } # End while read line + $offset=tell(TAIL); + close(TAIL); + } +} + + +sub prepair2basedata(){ + my ( + $hids_id, + $last_cid, + $timestamp, + $sec, + $mail, + $date, + $alerthost, + $datasource, + $rule, + $level, + $description, + $srcip, + $dstip, + $user, + $text + )=@_; + my ($count,$query,$row_ref,$sig_id); +### +# +# Get/Set signature id + $query = "SELECT sig_id FROM signature where sig_name=? and sig_class_id=? and sig_priority=? and sig_rev=? and sig_sid=? and sig_gid is NULL"; + $dbi->execute($query,$description,1,$level,0,$rule); + $count=$dbi->{sth}->rows; + if ($count){ + $row_ref=$dbi->{sth}->fetchrow_hashref; + $sig_id=$row_ref->{sig_id}; + &printlog ("REUSING SIGNATURE\n"); + }else{ + $query="INSERT INTO signature ( sig_id , sig_name , sig_class_id , sig_priority , sig_rev , sig_sid , sig_gid ) +VALUES ( +NULL ,?, ? , ? , ? , ?, NULL +)"; + $dbi->execute($query,$description,1,$level,0,$rule); + $sig_id = $dbi->lastid(); + } +$dbi->{sth}->finish; +&printlog ("SIGNATURE: $sig_id\n"); +####### +# +# Set event + $query="INSERT INTO event ( sid , cid , signature , timestamp ) +VALUES ( +? , ? , ? ,? +)"; + $last_cid++; + $dbi->execute($query,$hids_id,$last_cid,$sig_id,&fixdate2base($date)); + +&printlog ("EVENT: ($query,$hids_id,$last_cid,$sig_id,&fixdate2base($date)\n"); +$dbi->{sth}->finish; +######### +# +# Set acid_event + $query=" INSERT INTO acid_event ( sid , cid , signature , sig_name , sig_class_id , sig_priority , timestamp , ip_src , ip_dst , ip_proto , layer4_sport , layer4_dport ) +VALUES ( +? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ?, ? +) "; + $dbi->execute($query,$hids_id,$last_cid,$sig_id,$description,1,$level,&fixdate2base($date),$srcip,$dstip,undef,undef,undef); +&printlog ("ACID_EVENT: ($query,$hids_id,$last_cid,$sig_id,$description,1,$level,&fixdate2base($date),$srcip,$dstip,undef,undef)\n"); +$dbi->{sth}->finish; + +######### +# +# +# Set data + $text = "** Alert $timestamp.$sec:\t$mail\n$date $alerthost -> $datasource\nRule: $rule (level $level) -> $description\nSrc IP: ($srcip)\nUser: $user\n$text"; + $query=" INSERT INTO data ( sid , cid , data_payload ) +VALUES ( +?,?,?)"; + $dbi->execute($query,$hids_id,$last_cid,$text); +&printlog ("DATA: ($query,$hids_id,$last_cid,$text)\n"); +$dbi->{sth}->finish; +########## +# + $query="UPDATE sensor SET last_cid=? where sid=? limit 1"; + $numrows= $dbi->execute($query,$last_cid,$hids_id); +# end sub +$dbi->{sth}->finish; +return $last_cid; +} + +sub fixdate2base(){ + my ($date)=@_; + $date=~ s/ Jan /-01-/; + $date=~ s/ Feb /-02-/; + $date=~ s/ Mar /-03-/; + $date=~ s/ Apr /-04-/; + $date=~ s/ May /-05-/; + $date=~ s/ Jun /-06-/; + $date=~ s/ Jul /-07-/; + $date=~ s/ Aug /-08-/; + $date=~ s/ Sep /-09-/; + $date=~ s/ Oct /-10-/; + $date=~ s/ Nov /-11-/; + $date=~ s/ Dec /-12-/; + $date=~ s/\s$//g; + return $date; +} +sub version(){ + print "openarmor report tool $VERSION\n"; + print "Licensed under GPL\n"; + print "Contributor Meir Michanie\n"; +} + +sub help(){ + &version(); + print "This tool helps you import into base the alerts generated by openarmor." + . " More info in the doc directory .\n"; + print "Usage:\n"; + print "$0 [-h|--help] # This text you read now\n"; + print "Options:\n"; + print "\t--dbhost \n"; + print "\t--dbname \n"; + print "\t--dbport <[0-9]+>\n"; + print "\t--dbpass \n"; + print "\t--dbuser \n"; + print "\t-d|--daemonize\n"; + print "\t-n|--noname\n"; + print "\t-v|--verbose\n"; + print "\t--conf \n"; + print "\t--sensor \n"; + print "\t--interface \n"; + + exit 0; +} + + +sub daemonize { + chdir '/' or die "Can't chdir to /: $!"; + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDOUT, ">>$DAEMONLOGFILE" + or die "Can't write to $DAEMONLOGFILE: $!"; + defined(my $pid = fork) or die "Can't fork: $!"; + if ($pid){ + open (PIDFILE , ">/var/run/openarmor2base2.pid") ; + print PIDFILE "$pid\n"; + close (PIDFILE); + exit 0; + } + setsid or die "Can't start a new session: $!"; + open STDERR, ">>$DAEMONLOGERRORFILE" or die "Can't write to $DAEMONLOGERRORFILE: $!"; +} + +sub gracefulend(){ + my ($signal)=@_; + &forceprintlog ("Terminating upon signal $signal"); + close TAIL; + &forceprintlog ("Daemon halted"); + close STDOUT; + close STDERR; + exit 0; +} + +sub printlog(){ + return unless $VERBOSE; + my (@lines)=@_; + foreach my $line(@lines){ + chomp $line; + my ($date)=scalar localtime; + $date=~ s/^\S+\s+(\S+.*\s[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}).*$/$1/; + print "$date $LOGGER: $line\n"; + } +} + + +sub loadconf(){ + my ($hash_ref)=@_; + my $conf=$hash_ref->{conf}; + unless (-f $conf) { &printlog ("ERROR: I can't find config file $conf"); exit 1;} + unless (open ( CONF , "$conf")){ &printlog ("ERROR: I can't open file $conf");exit 1;} + while (){ + next if m/^$|^#/; + if ( m/^(\S+)\s?=\s?(.*?)$/) { + $hash_ref->{$1} = $2; + } + } + close CONF; +} + diff --git a/contrib/openarmor2rss.php b/contrib/openarmor2rss.php new file mode 100644 index 000000000..8a0457d98 --- /dev/null +++ b/contrib/openarmor2rss.php @@ -0,0 +1,124 @@ + 30000) +{ + fseek($fh, -30000, SEEK_END); + $line = fgets($fh, 4096); +} + + +$lastlines = array(); +$event = array(); +while($line = fgets($fh, 4096)) +{ + $line = trim($line); + if($line == "") + { + continue; + } + + if(strncmp($line, "** Alert ", 9) == 0) + { + if(strncmp($event, "** Alert ", 9) == 0) + { + array_push($lastlines, $event); + } + unset($event); + $event = array(); + $event[] = htmlspecialchars($line); + } + else + { + $event[] = htmlspecialchars($line); + } +} +fclose($fh); + +$lastlines = array_reverse($lastlines); +$myhost = gethostname(); +if($myhost === FALSE) +{ + $myhost = ""; +} + +echo ' + + + +openarmor '.$myhost.' RSS Feed +http://theopenarmor.org +openarmor RSS Feed for '.$myhost.' +en-us +'.date("r", $timelp).' +'.date("r", $timelp).' +(C) theopenarmor.org 2008-2011 +theopenarmor.org RSS feed +30 +dcid@theopenarmor.org + + + openarmor Alert Feed + http://www.theopenarmor.org/img/openarmor_logo.jpg + http://theopenarmor.org + +'; + +foreach($lastlines as $myentry) +{ +echo $myentry; + + if(preg_match("/^.. Alert (\d+)\./", $myentry[0], $regs, PREG_OFFSET_CAPTURE, 0)) + { + $myunixtime = $regs[1][0]; + } + else + { + continue; + } + + + echo ' + + '.$myentry[2]." ,from ".substr($myentry[1], 20).' + http://theopenarmor.org + '.$myentry[0].' + \n"; } + + echo ' + ]]> + '.date("r", $myunixtime).' + + '; +} + +echo ' + + +'; + + +?> diff --git a/contrib/openarmor_report.txt b/contrib/openarmor_report.txt new file mode 100644 index 000000000..63b84c119 --- /dev/null +++ b/contrib/openarmor_report.txt @@ -0,0 +1,26 @@ +openarmor report tool 0.1 +Licensed under GPL +Contributor Meir Michanie +openarmor_report_contrib.pl [-h|--help] # This text you read now +openarmor_report_contrib.pl [-r|--report] # prints a report for each element +openarmor_report_contrib.pl [-s|--summary] # prints a summary report +openarmor_report_contrib.pl [-t|--top] #prints the top list + +How To: +======= + +openarmor_report_contrib.pl openarmor report tool 0.1 +openarmor_report_contrib.pl is a GNU style program. +It reads from STDIN and write to stdout. This gives you the advantage to use it in pipes. +i.e. +cat openarmor-alerts-05.log | openarmor_report_contrib.pl -r | mail root -s 'openarmor detailed report' +cat openarmor-alerts-05.log | openarmor_report_contrib.pl -s | mail root -s 'openarmor summary report' +cat | openarmor_report_contrib.pl -t | head -n 15 (for top 15) +cat | openarmor_report_contrib.pl -s (for summary) + +Crontab entry: +58 23 * * * (cat openarmor-alerts-05.log | openarmor_report_contrib.pl -s) + + +The could be any one of the variables used in openarmor log: +mail,alerthost,datasource,rule,level,description,srcip,user. diff --git a/contrib/openarmor_report_contrib.pl b/contrib/openarmor_report_contrib.pl new file mode 100644 index 000000000..ea9ee055d --- /dev/null +++ b/contrib/openarmor_report_contrib.pl @@ -0,0 +1,184 @@ +#!/usr/bin/perl -w +# by Meir Michanie +# GPL licensed +# meirm@riunx.com +my $VERSION="0.1"; +use strict; +&help() unless @ARGV; +if ($ARGV[0]=~ m/^-h$|^--help$/i){ + &help(); +} +&help unless $ARGV[0]=~ m/^-r$|^--report$|^-s$|^--summary$|^-t$|^--top$/; +my (@argv) = (); +while (@ARGV){ + push @argv, shift @ARGV; +} + +my $newrecord=0; +my %stats; +my ($timestamp,$sec,$mail,$date,$alerthost,$datasource,$rule,$level,$description, +$srcip,$user,$text); +while(<>){ + if (m/^$/){ + $newrecord=1; + $stats{$alerthost}{mail}{$mail}++; + $stats{$alerthost}{alerthost}{$alerthost}++; + $stats{$alerthost}{datasource}{$datasource}++; + $stats{$alerthost}{rule}{$rule}++; + $stats{$alerthost}{level}{$level}++; + $stats{$alerthost}{description}{$description}++; + if (defined $srcip) { $stats{$alerthost}{srcip}{$srcip}++; } + if (defined $user) { $stats{$alerthost}{user}{$user}++; } + next ; + } + if (m/^\*\* Alert ([0-9]+).([0-9]+):(.*)$/){ + $timestamp=$1; + $sec=$2; + $mail=$3; + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s(.*?)->(.*)$/){ + $date=$1; + $alerthost=$2; + $datasource=$3; + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s(.*?)$/){ + $date=$1; + $alerthost='none'; + $datasource=$2; + }elsif ( m/Rule: ([0-9]+) \(level ([0-9]+)\) -> (.*)$/ ){ + $rule=$1; + $level=$2; + $description= $3; + }elsif ( m/Src IP: (.*)$/){ + $srcip=$1; + }elsif ( m/User: (.*)$/){ + $user=$1; + }elsif( m/(.*)$/){ + $text=$1; + } + + +} +if ($argv[0]=~ m/^-r$|^--report$/i){ + &report(\%stats); +}elsif ($argv[0]=~ m/^-s$|^--summary$/){ + &summary(\%stats); +}elsif ($argv[0]=~ m/^-t$|^--top$/){ + $argv[1]= $argv[1] ? $argv[1] : 'srcip' ; + &top(\%stats,$argv[1]); +}else{ + &help(); +} + +sub printversion(){ + print "openarmor report tool $VERSION\n"; + print "Licensed under GPL\n"; + print "Contributor Meir Michanie\n"; +} + +sub help(){ + &printversion(); + print "$0 [-h|--help] # This text you read now\n"; + print "$0 [-r|--report] # prints a report for each element\n"; + print "$0 [-s|--summary] # prints a summary report\n"; + print "$0 [-t|--top] #prints the top list\n"; + print "\nHow To:\n"; + print "=======\n"; + print "$0\topenarmor report tool $VERSION\n"; + print " $0 is a GNU style program.\nIt reads from STDIN and write to stdout. "; + print "This gives you the advantage to use it in pipes.\n"; + print "i.e.\n"; + print " cat openarmor-alerts-05.log | $0 -r | mail root -s 'openarmor detailed report'\n"; + print " cat openarmor-alerts-05.log | $0 -s | mail root -s 'openarmor summary report'\n"; + print " cat openarmor-alerts-05.log | $0 -t srcip | head -n 15 | mail root -s 'openarmor top 15 offenders report'\n"; + print " Crontab entry:\n"; + print "58 23 * * * (cat openarmor-alerts-05.log | $0 -s)\n"; + exit 0; +} + +sub report(){ + my ($statref)=@_; +my ($stat,$key,$value); +format TOPREPORT = +============================================================================= +| Summary report | +============================================================================= +|Alerthost | Stat | Key | Count | +============================================================================= +. +$~='TOPREPORT'; +write; +format REPORT = +|@<<<<<<<<<<|@<<<<<<<<<<<|@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<|@######| +$alerthost,$stat,$key,$value +. +$~='REPORT'; +foreach(sort keys %{$statref}){ + $alerthost=$_; + foreach(sort keys %{${$statref}{$alerthost}}){ + $stat=$_; + foreach(sort keys %{${$statref}{$alerthost}{$stat}}){ + $key=$_; + $value=${$statref}{$alerthost}{$stat}{$key}; + write; + } + } +} +} + +sub summary(){ +my ($statref)=@_; +my (%totals); +my ($stat,$key,$value); +foreach(sort keys %{$statref}){ + $alerthost=$_; + foreach(sort keys %{${$statref}{$alerthost}}){ + $stat=$_; + foreach(sort keys %{${$statref}{$alerthost}{$stat}}){ + $key=$_; + $value=${$statref}{$alerthost}{$stat}{$key}; + $totals{$stat}{$key}+=$value; + } + } +} +format TOPSUMREPORT = +================================================================= +| Statistic report | +================================================================= +|Stat | Key | Count | +================================================================= +. +$~='TOPSUMREPORT'; +write; +format SUMREPORT = +|@<<<<<<<<<<<|@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<|@######| +$stat,$key,$value +. +$~='SUMREPORT'; +foreach(sort keys %totals){ + $stat=$_; + foreach(sort keys %{$totals{$stat}}){ + $key=$_; + $value=$totals{$stat}{$key}; + write; + } +} +} + +sub top(){ +my ($statref,$stat)=@_; +my (%totals,%mytest); +my ($key,$value); +foreach(keys %{$statref}){ + $alerthost=$_; + foreach( keys %{${$statref}{$alerthost}{$stat}}){ + $key=$_; + $value=${$statref}{$alerthost}{$stat}{$key}; + $totals{$stat}{$key}+=$value; + } +} +foreach (keys %{$totals{$stat}}){ + $mytest{$totals{$stat}{$_}}=$_; +}; +foreach (sort {$b <=> $a} keys %mytest){ + print "$mytest{$_} => $_\n"; +} +} diff --git a/contrib/openarmor_rules_list.py b/contrib/openarmor_rules_list.py new file mode 100644 index 000000000..be7d78a51 --- /dev/null +++ b/contrib/openarmor_rules_list.py @@ -0,0 +1,55 @@ +#!/usr/bin/python +# openarmor Rules list +# Simple script to get a short brief of every rule in openarmor rules folder +# Written Feb 25, 2016 and released under the GNU/GPLv2 license ## +# By pedro@wazuh.com @ Wazuh, Inc. + +import sys +import re +import os + +rules_directory = "/var/openarmor/rules/" + +def GetRulesList(fulldir, filename): + rule_detected = 0 + rule_description = 0 + level = "" + sidid = "" + description = "" + pattern_idlevel = re.compile(r'(.+?)') + pattern_endrule = re.compile(r'') + try: + with open(fulldir) as f: + lines = f.readlines() + for line in lines: + if rule_detected == 0: + match = re.findall(pattern_idlevel, line) + if match: + rule_detected = 1 + sidid = match[0][0] + level = match[0][1] + else: + if rule_description == 0: + match = re.findall(pattern_description, line) + if match: + rule_description = 1 + description = match[0] + if rule_description == 1: + match = re.findall(pattern_endrule, line) + if match: + print "%s - Rule %s - Level %s -> %s" % (filename,sidid,level,description) + rule_detected = 0 + rule_description = 0 + level = "" + sidid = "" + description = "" + except EnvironmentError: + print ("Error: openarmor rules directory does not appear to exist") + +if __name__ == "__main__": + print ("Reading rules from directory %s") % (rules_directory) + for root, directories, filenames in os.walk(rules_directory): + for filename in filenames: + if filename[-4:] == ".xml": + GetRulesList(os.path.join(root,filename), filename) diff --git a/contrib/openarmormysql.pm b/contrib/openarmormysql.pm new file mode 100644 index 000000000..cea530d1e --- /dev/null +++ b/contrib/openarmormysql.pm @@ -0,0 +1,75 @@ +use DBI; +use strict; +package openarmormysql; + +sub new(){ + my $type = shift; + my %conf=@_; + my $self={}; + my $flag; + $self->{database}=$conf{database}; + $self->{dbhost}=$conf{dbhost}; + $self->{dbport}=$conf{dbport}; + $self->{dbuser}=$conf{dbuser}; + $self->{dbpasswd}=$conf{dbpasswd}; + + $self->{dsn} = "DBI:mysql:database=$self->{database};host=$self->{dbhost};port=$self->{dbport}"; + $self->{dbh} = DBI->connect($self->{dsn}, $self->{dbuser},$self->{dbpasswd}); + bless $self, $type; +} +sub fetchrecord(){ + my $self= shift ; + my ($rows)=@_; + my ($pointer,$numrows,$fields)=(${$rows}[0],${$rows}[1],${$rows}[2]); + my @result; + return if $pointer == $numrows; + for (my $i=0; $i < $fields; $i ++){ + my $field= @{$rows}[($pointer * $fields) + 3 + $i ]; + push (@result, $field); + } + ${$rows}[0] ++; + + return @result; +} +sub fetchrows(){ + my $self = shift ; + my ($query)=shift; + my @params= @_; + my @rows; + my $numFields; + my $numRows; + $numRows=$numFields=0; + $self->{sth}=$self->{dbh}->prepare($query); + $self->{sth}->execute(@params) ; + $numRows = $self->{sth}->rows; + my @row=(); + return @rows unless $numRows>0; + $numFields = $self->{sth}->{'NUM_OF_FIELDS'}; + push (@rows,0,$numRows,$numFields); + while(@row=$self->{sth}->fetchrow_array){ + push (@rows,@row); + } + + $self->{sth}->finish; + return @rows; + +} + +sub execute(){ + my $self = shift ; + my $flag; + my ($query)=shift; + my @params= @_; + my @rows= (); + my $numFields; + my $numRows; + $numRows=$numFields=0; + $self->{sth} = $self->{dbh}->prepare($query); + return $self->{sth}->execute(@params) ; +} + +sub lastid(){ + my $self = shift ; + return $self->{sth}->{mysql_insertid}; +} +1 diff --git a/contrib/openarmortop.pl b/contrib/openarmortop.pl new file mode 100644 index 000000000..333e71282 --- /dev/null +++ b/contrib/openarmortop.pl @@ -0,0 +1,245 @@ +#!/usr/bin/perl -w +#use strict; +#use Socket; +#use POSIX 'setsid'; +use Regexp::IPv6 qw($IPv6_re); +# --------------------------------------------------------------------------- +# Author: Meir Michanie (meirm@riunx.com) +# File: openarmortop.pl +# Version 0.1 (09/2006) +# +# --------------------------------------------------------------------------- +# License +# --------------------------------------------------------------------------- +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# --------------------------------------------------------------------------- +# About openarmor HIDS +# --------------------------------------------------------------------------- +# +# openarmor HIDS is an Open Source Host-based Intrusion Detection System. +# It performs log analysis and correlation, integrity checking, +# rootkit detection, time-based alerting and active response. +# http://www.theopenarmor.org +# +# --------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- +# Parameters +# --------------------------------------------------------------------------- +$SIG{TERM} = sub { &gracefulend('TERM')}; +$SIG{INT} = sub { &gracefulend('INT')}; + +my %conf; +$conf{resolve}=1; + + +my($OCT) = '(?:25[012345]|2[0-4]\d|1?\d\d?)'; + +my($IP) = $OCT . '\.' . $OCT . '\.' . $OCT . '\.' . $OCT . '\|' . $IPv6_re; + +my $VERSION="0.1"; +my $sig_class_id=1; +my $dump=0; +my ($hids_id,$hids,$hids_interface,$last_cid)=(undef, 'localhost', 'openarmor',0); +my ($tempvar,$VERBOSE)=(0,0); +# --------------------------------------------------------------------------- +# Arguments parsing +# --------------------------------------------------------------------------- + +while (@ARGV){ + $_= shift @ARGV; + if ( m/^-h$|^--help$/){ + &help(); + }elsif ( m/^-n$|^--noname$/){ + $conf{'resolve'}=0; + } +} + + +my $newrecord=0; +my %stats; +my %resolv; +my ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description, + $srcip,$dstip,$user,$text)=(); +my $lasttimestamp=0; +my $delta=0; +######################################################## +my $datepath=`date "+%Y/%b/openarmor-alerts-%d.log"`; +my $LOG='/var/openarmor/logs/alerts/'. $datepath; +chomp $LOG; +$date=''; +format TOPREPORT = + ========================================================================================================================== +| openarmor-HIDS TOP | + ========================================================================================================================== +| Alert | Date | SRC | DST | LVL | Name | + ========================================================================================================================== +. +format REPORT = +|@<<<<< |@<<<<<<<<<<<<<<<<<<<<< |@<<<<<<<<<<<< |@<<<<<<<<<<<< |@<<< |@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | +$rule,$date,$srcip,$dstip,$level,$description +. +#$~='REPORT'; +#$~='TOPREPORT'; + +&taillog(); +############################################################### +sub taillog { + my($offset, $line, $stall) = ''; + + $offset = (-s $LOG); # Don't start at beginning, go to end + + my $count=10; + while (1==1) { + sleep(1); + %resolv=(); + $| = 1; + $stall += 1; + $datepath=`date "+%Y/%b/openarmor-alerts-%d.log"`; + $LOG='/var/openarmor/logs/alerts/'. $datepath; + chomp $LOG; + unless ( -f $LOG){print "Error -f $LOG\n"; next; } + if ((-s $LOG) < $offset) { + $offset = 0; + } + + unless (open(TAIL, $LOG)){ print "Error opening $LOG: $!\n";next ;} + + if (seek(TAIL, $offset, 0)) { + # found offset, log not rotated + } else { + # log reset, follow + $offset=0; + seek(TAIL, $offset, 0); + } + while () { + if (m/^$/){ + $newrecord=1; + next unless $timestamp; + $count++; + if ($count>10){ + system ("clear"); + $~='TOPREPORT'; + write; + $count=0; + } + + $alerthostip=$alerthost if $alerthost=~ m/^$IP$/; + if ($alerthostip){ + $dstip=$alerthostip; + $resolv{$alerthost}=$dstip; + }else{ + if (exists $resolv{$alerthost}){ + $dstip=$resolv{$alerthost}; + }else{ + if ($conf{'resolve'}){ + $dstip=`host $alerthost 2>/dev/null | grep 'has address\|has IPv6 address' `; + if ($dstip =~m/($IP)/ ){ + $dstip=$1; + }else{ + $dstip=$srcip; + } + }else{ + $dstip=$alerthost; + } + $resolv{$alerthost}=$dstip; + + } + } + $~='REPORT'; + write; + ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description, + $srcip,$dstip,$user,$text)=(); + next ; + } + if (m/^\*\* Alert ([0-9]+).([0-9]+):(.*)$/){ + $timestamp=$1; + if ( $timestamp == $lasttimestamp){ + $delta++; + }else{ + $delta=0; + $lasttimestamp=$timestamp; + } + $sec=$2; + $mail=$3; + $mail=$mail ? $mail : 'nomail'; +#2006 Aug 29 17:19:52 firewall -> /var/log/messages +#2006 Aug 30 11:52:14 192.168.0.45->/var/log/secure +# + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+(\S+)\s*->(.*)$/){ + $date=$1; + $alerthost=$2; + $datasource=$3; +#2006 Aug 29 17:33:31 (recepcao) 10.0.3.154 -> syscheck + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+\((.*?)\)\s+(\S+)\s*->(.*)$/){ + $date=$1; + $alerthost=$2; + $alerthostip=$3; + $datasource=$4; + }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s(.*?)$/){ + $date=$1; + $alerthost='localhost'; + $datasource=$2; + }elsif ( m/Rule: ([0-9]+) \(level ([0-9]+)\) -> '(.*)'$/ ){ + $rule=$1; + $level=$2; + $description= $3; + }elsif ( m/Src IP:/){ + if ( m/Src IP: (\S+)/){ + $srcip=$1; + }else{ + $srcip=''; + } + }elsif ( m/User: (.*)$/){ + $user=$1; + }elsif( m/(.*)$/){ + $text .=$1; + } + + + } # End while read line + $offset=tell(TAIL); + close(TAIL); + } +} + +sub version(){ + print "openarmor report tool $VERSION\n"; + print "Licensed under GPL\n"; + print "Contributor Meir Michanie\n"; +} + +sub help(){ + &version(); + print "List alerts generated by openarmor." + . " More info in the doc directory .\n"; + print "Usage:\n"; + print "$0 [-h|--help] # This text you read now\n"; + print "Options:\n"; + print "\t-n|--noname\n"; + + exit 0; +} + + +sub gracefulend(){ + my ($signal)=@_; + close TAIL; + close STDOUT; + close STDERR; + exit 0; +} diff --git a/contrib/rename_agent.sh b/contrib/rename_agent.sh new file mode 100644 index 000000000..61cfa5509 --- /dev/null +++ b/contrib/rename_agent.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# Rename an openarmor agent (must be run on both agent and server) + +# Sanity checks + +if [ $# -ne 2 ]; then + echo Usage: $0 old-name new-name + exit 1 +fi + +if ! [ -e /etc/openarmor-init.conf ]; then + echo openarmor-init.conf not found. Exiting... + exit 1 +fi + +. /etc/openarmor-init.conf +KEYFILE=$DIRECTORY/etc/client.keys + +# Get the IP address from the key file +IPADDR=`grep -w "${1}" $KEYFILE | cut -d " " -f 3` +if [ -z ${IPADDR} ]; then + echo Agent ${1} not found. Exiting... + exit 1 +fi + +# stop openarmor +/var/openarmor/bin/openarmor-control stop + +# Update the key record +sed -i $KEYFILE -e "s/${1}/${2}/" + +# Rename files and directories (manager) + +cd $DIRECTORY/queue + +if [ -e "agent-info/${1}-${IPADDR}" ]; then + mv "agent-info/${1}-${IPADDR}" \ + "agent-info/${2}-${IPADDR}" +fi + +if [ -e "diff/${1}" ]; then + mv "diff/${1}" \ + "diff/${2}" +fi + +if [ -e "rootcheck/(${1}) ${IPADDR}->rootcheck" ]; then + mv "rootcheck/(${1}) ${IPADDR}->rootcheck" \ + "rootcheck/(${2}) ${IPADDR}->rootcheck" +fi + +if [ -e "syscheck/(${1}) ${IPADDR}->syscheck" ]; then + mv "syscheck/(${1}) ${IPADDR}->syscheck" \ + "syscheck/(${2}) ${IPADDR}->syscheck" +fi + +if [ -e "syscheck/.(${1}) ${IPADDR}->syscheck.cpt" ]; then + mv "syscheck/.(${1}) ${IPADDR}->syscheck.cpt" \ + "syscheck/.(${2}) ${IPADDR}->syscheck.cpt" +fi + +# Restart openarmor +/var/openarmor/bin/openarmor-control start diff --git a/contrib/renumber_agent.sh b/contrib/renumber_agent.sh new file mode 100644 index 000000000..ca8063de3 --- /dev/null +++ b/contrib/renumber_agent.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# Renumber (change IP address) an openarmor agent (must be run on both agent +# and server) + +# Sanity checks + +if [ $# -ne 2 ]; then + echo Usage: $0 agent-name new-IP-address + exit 1 +fi + +if ! [ -e /etc/openarmor-init.conf ]; then + echo openarmor-init.conf not found. Exiting... + exit 1 +fi + +. /etc/openarmor-init.conf +KEYFILE=$DIRECTORY/etc/client.keys + +# Get the IP address from the key file +IPADDR=`grep -w "${1}" $KEYFILE | cut -d " " -f 3` +if [ -z ${IPADDR} ]; then + echo Agent ${1} not found. Exiting... + exit 1 +fi + +# stop openarmor +/var/openarmor/bin/openarmor-control stop + +# Update the key record +sed -i $KEYFILE -e "s/${IPADDR}/${2}/" + +# Rename files and directories (manager) + +cd $DIRECTORY/queue + +if [ -e "agent-info/${1}-${IPADDR}" ]; then + mv "agent-info/${1}-${IPADDR}" \ + "agent-info/${1}-${2}" +fi + +if [ -e "rootcheck/(${1}) ${IPADDR}->rootcheck" ]; then + mv "rootcheck/(${1}) ${IPADDR}->rootcheck" \ + "rootcheck/(${1}) ${2}->rootcheck" +fi + +if [ -e "syscheck/(${1}) ${IPADDR}->syscheck" ]; then + mv "syscheck/(${1}) ${IPADDR}->syscheck" \ + "syscheck/(${1}) ${2}->syscheck" +fi + +if [ -e "syscheck/.(${1}) ${IPADDR}->syscheck.cpt" ]; then + mv "syscheck/.(${1}) ${IPADDR}->syscheck.cpt" \ + "syscheck/.(${1}) ${2}->syscheck.cpt" +fi + +# Restart openarmor +/var/openarmor/bin/openarmor-control start diff --git a/contrib/selinux/README.md b/contrib/selinux/README.md new file mode 100644 index 000000000..44d055faa --- /dev/null +++ b/contrib/selinux/README.md @@ -0,0 +1,20 @@ +## openarmor-agent SELinux module + +SELinux module provides additional security protection for openarmor application + +## Installation + +1. Run semodule -i openarmor_agent.pp.bz2 on a running SELinux installation +2. Run restorecon -R /var/openarmor +3. Restart openarmor agent via systemd/init/etc +4. Check if it get right context ( ps -AZ ) + +You should do chcon manually if your put openarmor installation in different place, see .fc file for details + +## Configuration + +Nothing to configure :) + +## Bug reports & contribution + +Contact: ivan.agarkov@gmail.com diff --git a/contrib/selinux/openarmor_agent.pp.bz2 b/contrib/selinux/openarmor_agent.pp.bz2 new file mode 100644 index 000000000..098a0fe36 Binary files /dev/null and b/contrib/selinux/openarmor_agent.pp.bz2 differ diff --git a/contrib/selinux/openarmor_agent/openarmor_agent.fc b/contrib/selinux/openarmor_agent/openarmor_agent.fc new file mode 100644 index 000000000..158a8c5fd --- /dev/null +++ b/contrib/selinux/openarmor_agent/openarmor_agent.fc @@ -0,0 +1,23 @@ +/var/openarmor/bin/agent-auth -- system_u:object_r:openarmor_admin_exec_t:s0 +/var/openarmor/bin/manage_client -- system_u:object_r:openarmor_admin_exec_t:s0 +/var/openarmor/bin/openarmor-client.sh -- system_u:object_r:openarmor_admin_exec_t:s0 +/var/openarmor/bin/openarmor-configure -- system_u:object_r:openarmor_admin_exec_t:s0 +/var/openarmor/bin/openarmor-control system_u:object_r:openarmor_admin_exec_t:s0 +/var/openarmor/bin/openarmor-fix-id.sh -- system_u:object_r:openarmor_admin_exec_t:s0 + +/var/openarmor/bin/openarmor-logcollector system_u:object_r:openarmor_logcollector_exec_t:s0 +/var/openarmor/bin/client-logcollector system_u:object_r:openarmor_logcollector_exec_t:s0 +/var/openarmor/bin/client-syscheckd system_u:object_r:openarmor_syscheck_exec_t:s0 +/var/openarmor/bin/openarmor-agentd -- system_u:object_r:openarmor_agent_exec_t:s0 +/var/openarmor/bin/openarmor-syscheckd system_u:object_r:openarmor_syscheck_exec_t:s0 +/var/openarmor/bin/openarmor-execd -- system_u:object_r:openarmor_exec_exec_t:s0 + +/var/openarmor system_u:object_r:usr_t:s0 +/var/openarmor/bin system_u:object_r:bin_t:s0 +/var/openarmor/agentless(/.*)? system_u:object_r:bin_t:s0 +/var/openarmor/active-response(/.*)? system_u:object_r:bin_t:s0 +/var/openarmor/etc(/.*)? system_u:object_r:openarmor_conf_t:s0 +/var/openarmor/queue(/.*)? system_u:object_r:openarmor_queue_t:s0 +/var/openarmor/logs(/.*)? system_u:object_r:openarmor_log_t:s0 +/var/openarmor/tmp(/.*)? system_u:object_r:openarmor_tmp_t:s0 +/var/openarmor/var(/.*)? system_u:object_r:openarmor_var_t:s0 diff --git a/contrib/selinux/openarmor_agent/openarmor_agent.if b/contrib/selinux/openarmor_agent/openarmor_agent.if new file mode 100644 index 000000000..3eb6a3057 --- /dev/null +++ b/contrib/selinux/openarmor_agent/openarmor_agent.if @@ -0,0 +1 @@ +## diff --git a/contrib/selinux/openarmor_agent/openarmor_agent.te b/contrib/selinux/openarmor_agent/openarmor_agent.te new file mode 100644 index 000000000..b7d16d33a --- /dev/null +++ b/contrib/selinux/openarmor_agent/openarmor_agent.te @@ -0,0 +1,100 @@ +policy_module(openarmor_agent, 1.0.4) +# selinux module for openarmor (tm) agent +# (C) Ivan Agarkov, 2017 +# exec file types +type openarmor_agent_exec_t; +type openarmor_exec_exec_t; +type openarmor_logcollector_exec_t; +type openarmor_syscheck_exec_t; +type openarmor_admin_exec_t; +# data file types +type openarmor_log_t; # logs/ +type openarmor_conf_t; # /etc +type openarmor_queue_t; # /queue +type openarmor_tmp_t; # /tmp +type openarmor_var_t; # /var +# process attributes +attribute openarmor_process; +# process types +type openarmor_agent_t, openarmor_process; +type openarmor_exec_t, openarmor_process; +type openarmor_logcollector_t, openarmor_process; +type openarmor_syscheck_t, openarmor_process; +type openarmor_admin_t; + +# types definitions +init_daemon_domain(openarmor_agent_t, openarmor_agent_exec_t) +init_daemon_domain(openarmor_logcollector_t, openarmor_logcollector_exec_t) +init_daemon_domain(openarmor_syscheck_t, openarmor_syscheck_exec_t) +init_daemon_domain(openarmor_exec_t, openarmor_exec_exec_t) +application_domain(openarmor_admin_t, openarmor_admin_exec_t) + +files_type(openarmor_queue_t) +files_type(openarmor_var_t) +logging_log_file(openarmor_log_t) +files_config_file(openarmor_conf_t) +files_tmp_file(openarmor_tmp_t) +# type transition for all +files_tmp_filetrans(openarmor_process, openarmor_tmp_t, {file dir lnk_file}) +filetrans_pattern(openarmor_process, openarmor_queue_t, openarmor_queue_t, {file dir lnk_file sock_file}) +filetrans_pattern(openarmor_process, openarmor_var_t, openarmor_var_t, {file dir lnk_file }) +filetrans_pattern(openarmor_process, openarmor_conf_t, openarmor_conf_t, {file dir lnk_file }) +filetrans_pattern(openarmor_process, openarmor_tmp_t, openarmor_tmp_t, {file dir lnk_file }) +# allow openarmor agent to read & edit all +read_files_pattern(openarmor_process, openarmor_conf_t, openarmor_conf_t) +admin_pattern(openarmor_process, openarmor_queue_t, openarmor_queue_t) + +admin_pattern(openarmor_process, openarmor_log_t, openarmor_log_t) +admin_pattern(openarmor_process, openarmor_var_t, openarmor_var_t) +optional_policy(` + gen_require(` + type passwd_file_t, etc_t; + ') + read_files_pattern(openarmor_process, etc_t, passwd_file_t) +') +allow openarmor_process openarmor_process:unix_dgram_socket all_unix_dgram_socket_perms; +sysnet_dns_name_resolve(openarmor_process) +allow openarmor_process self:capability { dac_override setgid setuid sys_chroot }; +# for agent +admin_pattern(openarmor_agent_t, openarmor_conf_t, openarmor_conf_t) +admin_pattern(openarmor_agent_t, openarmor_tmp_t, openarmor_tmp_t) + +# logcollector read all logs +logging_read_all_logs(openarmor_logcollector_t) +logging_read_audit_log(openarmor_logcollector_t) +# syscheck read all file +files_read_all_files(openarmor_syscheck_t) +allow openarmor_syscheck_t self:process setsched; +allow openarmor_syscheck_t self:capability sys_nice; +# admin policy +admin_pattern(openarmor_admin_t, openarmor_conf_t, openarmor_conf_t) +admin_pattern(openarmor_admin_t, openarmor_queue_t, openarmor_queue_t) +admin_pattern(openarmor_admin_t, openarmor_var_t, openarmor_var_t) +# allow to kill +allow openarmor_admin_t openarmor_process:process { signal sigkill ptrace sigstop getattr setrlimit noatsecure }; +# for different roles +optional_policy(` + gen_require(` + type unconfined_t; + role unconfined_r; + ') + role unconfined_r types openarmor_admin_t; + domtrans_pattern(unconfined_t, openarmor_admin_exec_t, openarmor_admin_t) +') +optional_policy(` + gen_require(` + type sysadm_t; + role sysadm_r; + ') + role sysadm_r types openarmor_admin_t; + domtrans_pattern(sysadm_t, openarmor_admin_exec_t, openarmor_admin_t) +') +optional_policy(` + gen_require(` + type staff_t; + role staff_r; + ') + role staff_r types openarmor_admin_t; + domtrans_pattern(staff_t, openarmor_admin_exec_t, openarmor_admin_t) +') + diff --git a/contrib/snapcraft/files/bin/wrapper b/contrib/snapcraft/files/bin/wrapper new file mode 100644 index 000000000..1f9d334e1 --- /dev/null +++ b/contrib/snapcraft/files/bin/wrapper @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# On Fedora $SNAP is under /var and there is some magic to map it to /snap. +# We need to handle that case and reset $SNAP +SNAP=$(echo $SNAP | sed -e "s|/var/lib/snapd||g") + +if [ "$SNAP_ARCH" == "amd64" ]; then + ARCH="x86_64-linux-gnu" +elif [ "$SNAP_ARCH" == "armhf" ]; then + ARCH="arm-linux-gnueabihf" +elif [ "$SNAP_ARCH" == "arm64" ]; then + ARCH="aarch64-linux-gnu" +else + ARCH="$SNAP_ARCH-linux-gnu" +fi + +export XDG_CACHE_HOME=$SNAP_USER_COMMON/.cache +if [[ -d $SNAP_USER_DATA/.cache && ! -e $XDG_CACHE_HOME ]]; then + # the .cache directory used to be stored under $SNAP_USER_DATA, migrate it + mv $SNAP_USER_DATA/.cache $SNAP_USER_COMMON/ +fi +mkdir -p $XDG_CACHE_HOME + +# Gdk-pixbuf loaders +export GDK_PIXBUF_MODULE_FILE=$XDG_CACHE_HOME/gdk-pixbuf-loaders.cache +export GDK_PIXBUF_MODULEDIR=$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders +if [ -f $SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders ]; then + $SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders > $GDK_PIXBUF_MODULE_FILE +fi + +# Create $XDG_RUNTIME_DIR if not exists. +[ -n "$XDG_RUNTIME_DIR" ] && mkdir -p $XDG_RUNTIME_DIR -m 700 + +# Display migration alert +$SNAP/usr/bin/yad \ + --title="${MIGRATION_TITLE}" \ + --text="${MIGRATION_TEXT}" \ + --center \ + --on-top \ + --fixed + +exec "$@" diff --git a/contrib/snapcraft/snap/snapcraft.yaml b/contrib/snapcraft/snap/snapcraft.yaml new file mode 100644 index 000000000..f865f3944 --- /dev/null +++ b/contrib/snapcraft/snap/snapcraft.yaml @@ -0,0 +1,114 @@ +name: openarmor-hids +version: latest +version-script: cat $SNAPCRAFT_STAGE/version +summary: Security tool. +description: An Open Source Host-based Intrusion Detection System that performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response. + + +grade: devmode +base: core18 + +architectures: + - build-on: amd64 + +parts: + gnome: + plugin: nil + build-packages: + - software-properties-common + override-pull: | + add-apt-repository -y ppa:ubuntu-desktop/gnome-3-28 + apt -y update + apt -y upgrade + + openarmor-hids: + after: + - gnome + plugin: dump + source: + # openarmor-hids is only available for i386 (x86) and amd64 (x86_64), + # so fail the build on other architectures. + - on amd64: https://updates.atomicorp.com/openarmor-hids-agent_3.3.0-7681bionic_amd64.deb + + source-type: deb + override-build: | + ARCHITECTURE=$(dpkg --print-architecture) + if [ "${ARCHITECTURE}" = "amd64" ]; then + DEB_API="https://updates.atomicorp.com/openarmor-hids-agent_3.3.0-7681bionic_amd64.deb" + else + echo "ERROR! openarmor-hids agent produces debs for amd64. Failing the build here." + exit 1 + fi + + DEB_URL=$(curl -w "%{url_effective}\n" -I -L -s -S "${DEB_API}" -o /dev/null) + VERSION=$(echo "${DEB_URL}" | cut -d'_' -f2) + echo $VERSION > $SNAPCRAFT_STAGE/version + + - on amd64: https://updates.atomicorp.com/openarmor-hids-server_3.3.0-6515bionic_amd64.deb + + source-type: deb + override-build: | + ARCHITECTURE=$(dpkg --print-architecture) + if [ "${ARCHITECTURE}" = "amd64" ]; then + DEB_API="https://updates.atomicorp.com/openarmor-hids-server_3.3.0-6515bionic_amd64.deb" + else + echo "ERROR! openarmor-hids server produces debs for amd64. Failing the build here." + exit 1 + fi + + DEB_URL=$(curl -w "%{url_effective}\n" -I -L -s -S "${DEB_API}" -o /dev/null) + VERSION=$(echo "${DEB_URL}" | cut -d'_' -f2) + echo $VERSION > $SNAPCRAFT_STAGE/version + + snapcraftctl build + build-packages: + - curl + - dpkg + - sed + stage-packages: + - fcitx-frontend-gtk3 + - gvfs-libs + - libasound2 + - libgconf-2-4 + - libglib2.0-bin + - libgnome-keyring0 + - libgtk-3-0 + - libnotify4 + - libnspr4 + - libnss3 + - libpcre3 + - libpulse0 + - libsecret-1-0 + - libxss1 + - libxtst6 + - yad + - zlib1g + prime: + - -usr/share/doc + - -usr/share/fonts + - -usr/share/icons + - -usr/share/lintian + - -usr/share/man + + wrapper: + after: + - openarmor-hids + plugin: dump + source: files/ + +apps: + openarmor-hids: + command: bin/wrapper $SNAP/usr/share/openarmor/bin/openarmor + desktop: usr/share/applications/openarmor.desktop + environment: + # Fallback to XWayland if running in a Wayland session. + DISABLE_WAYLAND: 1 + GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas + + url-handler: + command: bin/wrapper $SNAP/usr/share/openarmor/bin/openarmor --open-url + desktop: usr/share/applications/openarmor-url-handler.desktop + environment: + # Fallback to XWayland if running in a Wayland session. + DISABLE_WAYLAND: 1 + GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas diff --git a/contrib/specs/agent/openarmor-hids-agent.spec b/contrib/specs/agent/openarmor-hids-agent.spec new file mode 100644 index 000000000..bd4c643c5 --- /dev/null +++ b/contrib/specs/agent/openarmor-hids-agent.spec @@ -0,0 +1,220 @@ +# +# openarmor 1.3 .spec file - AGENT +# Fri Aug 17 15:19:40 EDT 2007 +# +# +# TODO: +# +# o Safety checks for %clean +# +# o Remove script +# +# o create an RPM_README.txt and put it in the source tree +# +# + +Summary: Open Source Host-based Intrusion Detection System (Server) +Name: openarmor-hids-agent-FC7 +Version: 1.3 +Release: 1 +License: GPLv2 +Group: Applications/Security +URL: http://www.theopenarmor.org +Packager: Michael Williams (maverick@maverick.org) +Source: http://www.theopenarmor.org/files/openarmor-hids-1.3.tar.gz +Requires: /usr/sbin/useradd, /usr/sbin/groupadd, /usr/sbin/groupdel, /usr/sbin/userdel, /sbin/service, /sbin/chkconfig + +%description +openarmor is an Open Source Host-based Intrusion +Detection System. It performs log analysis, +integrity checking, Windows registry monitoring, +rootkit detection, real-time alerting and active +response. + + +%prep + +%setup -n openarmor-hids-1.3 + +%build +/bin/cp /usr/local/src/openarmor-RPM/1.3/agent/preloaded-vars.conf ${RPM_BUILD_DIR}/openarmor-hids-1.3/etc/ + +./install.sh + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +################################################################################ +# Create openarmor group +# +if ! grep "^openarmor" /etc/group > /dev/null ; then + /usr/sbin/groupadd --system openarmor +fi + + +################################################################################ +# Create openarmor users +# +for USER in openarmor ; do + if ! grep "^${USER}" /etc/passwd > /dev/null ; then + /usr/sbin/useradd --system -d /var/openarmor -s /bin/false -g openarmor ${USER} + fi +done + +%post + + + +################################################################################ +# Create openarmor /etc/init.d/openarmor file +# +cat < /etc/init.d/openarmor +#!/bin/bash +# +# openarmor Starts openarmor +# +# +# chkconfig: 2345 12 88 +# description: openarmor is an open source host based IDS +### BEGIN INIT INFO +# Provides: $openarmor +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +[ -f /var/openarmor/bin/openarmor-control ] || exit 0 + +RETVAL=0 + +umask 077 + +case "\$1" in + start) + /var/openarmor/bin/openarmor-control start + ;; + stop) + /var/openarmor/bin/openarmor-control stop + ;; + status) + /var/openarmor/bin/openarmor-control status + ;; + restart|reload) + /var/openarmor/bin/openarmor-control restart + ;; + *) + echo "Usage: /var/openarmor/bin/openarmor-control {start|stop|status|restart}" + exit 1 +esac + +EOF + +/bin/chown root.root /etc/init.d/openarmor +/bin/chmod 755 /etc/init.d/openarmor + +################################################################################ +# Set configuration so openarmor starts on reboot +# +/sbin/chkconfig --add openarmor +/sbin/chkconfig openarmor on + +%postun +# Run service command, make sure openarmor is stopped +/sbin/service openarmor stop + +# Run chkconfig, stop openarmor from starting on boot +/sbin/chkconfig openarmor off +/sbin/chkconfig --del openarmor + +# Remove init.d file +[ -f /etc/init.d/openarmor ] && rm /etc/init.d/openarmor + +# Remove openarmor users +for USER in openarmor openarmorm openarmorr ; do + if grep "^${USER}" /etc/passwd > /dev/null ; then + /usr/sbin/userdel -r ${USER} + fi +done + +# Remove openarmor group +if grep "^openarmor" /etc/group > /dev/null ; then + /usr/sbin/groupdel openarmor +fi + + +%files +%doc README BUGS CONFIG CONTRIB INSTALL LICENSE + +%dir /var/openarmor/ +%attr(550, root, openarmor) /var/openarmor/ +%dir /var/openarmor/var +%attr(550, root, openarmor) /var/openarmor/var +%dir /var/openarmor/var/run +%attr(770, root, openarmor) /var/openarmor/var/run +%dir /var/openarmor/active-response +%attr(550, root, openarmor) /var/openarmor/active-response +%dir /var/openarmor/active-response/bin +%attr(550, root, openarmor) /var/openarmor/active-response/bin +/var/openarmor/active-response/bin/route-null.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/route-null.sh +/var/openarmor/active-response/bin/host-deny.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/host-deny.sh +/var/openarmor/active-response/bin/firewall-drop.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/firewall-drop.sh +%dir /var/openarmor/active-response/bin/firewalls +%attr(755, root, openarmor) /var/openarmor/active-response/bin/firewalls +/var/openarmor/active-response/bin/firewalls/pf.sh +/var/openarmor/active-response/bin/firewalls/ipfw.sh +/var/openarmor/active-response/bin/firewalls/ipfw_mac.sh +/var/openarmor/active-response/bin/disable-account.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/disable-account.sh +%dir /var/openarmor/bin +%attr(550, root, openarmor) /var/openarmor/bin +/var/openarmor/bin/openarmor-agentd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-agentd +/var/openarmor/bin/openarmor-logcollector +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-logcollector +/var/openarmor/bin/openarmor-control +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-control +/var/openarmor/bin/openarmor-syscheckd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-syscheckd +/var/openarmor/bin/manage_agents +%attr(550, root, openarmor) /var/openarmor/bin/manage_agents +/var/openarmor/bin/openarmor-execd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-execd +%dir /var/openarmor/etc +%attr(550, root, openarmor) /var/openarmor/etc +/var/openarmor/etc/internal_options.conf +%attr(440, root, openarmor) /var/openarmor/etc/internal_options.conf +/var/openarmor/etc/localtime +%attr(644, root, root) /var/openarmor/etc/localtime +%dir /var/openarmor/etc/shared +%attr(770, root, openarmor) /var/openarmor/etc/shared +/var/openarmor/etc/shared/win_malware_rcl.txt +%attr(770, openarmor, openarmor) /var/openarmor/etc/shared/win_malware_rcl.txt +/var/openarmor/etc/shared/win_applications_rcl.txt +%attr(770, openarmor, openarmor) /var/openarmor/etc/shared/win_applications_rcl.txt +/var/openarmor/etc/shared/win_audit_rcl.txt +%attr(770, openarmor, openarmor) /var/openarmor/etc/shared/win_audit_rcl.txt +/var/openarmor/etc/shared/rootkit_files.txt +%attr(770, osse, openarmor) /var/openarmor/etc/shared/rootkit_files.txt +/var/openarmor/etc/shared/rootkit_trojans.txt +%attr(770, openarmor, openarmor) /var/openarmor/etc/shared/rootkit_trojans.txt +/var/openarmor/etc/openarmor.conf +%attr(440, root, openarmor) /var/openarmor/etc/openarmor.conf +%dir /var/openarmor/logs +%attr(750, openarmor, openarmor) /var/openarmor/logs +/var/openarmor/logs/openarmor.log +%attr(664, openarmor, openarmor) /var/openarmor/logs/openarmor.log +%dir /var/openarmor/queue +%attr(550, root, openarmor) /var/openarmor/queue +%dir /var/openarmor/queue/rids +%attr(775, root, openarmor) /var/openarmor/queue/rids +%dir /var/openarmor/queue/alerts +%attr(550, root, openarmor) /var/openarmor/queue/alerts +%dir /var/openarmor/queue/syscheck +%attr(550, root, openarmor) /var/openarmor/queue/syscheck +%dir /var/openarmor/queue/openarmor +%attr(770, openarmor, openarmor) /var/openarmor/queue/openarmor + diff --git a/contrib/specs/agent/preloaded-vars.conf b/contrib/specs/agent/preloaded-vars.conf new file mode 100644 index 000000000..5aa7ffcfd --- /dev/null +++ b/contrib/specs/agent/preloaded-vars.conf @@ -0,0 +1,121 @@ +# preloaded-vars.conf, Daniel B. Cid (dcid @ theopenarmor.org). +# +# RPM: server/local/agent version, 1.2, 2007.07.23 +# +# +# Use this file to customize your installations. +# It will make the install.sh script pre-load some +# specific options to make it run automatically +# or with less questions. + +# PLEASE NOTE: +# When we use "n" or "y" in here, it should be changed +# to "n" or "y" in the language your are doing the +# installation. For example, in portuguese it would +# be "s" or "n". + + +# USER_LANGUAGE defines to language to be used. +# It can be "en", "br", "tr", "it", "de" or "pl". +# In case of an invalid language, it will default +# to English "en" +USER_LANGUAGE="en" # For english +#USER_LANGUAGE="br" # For portuguese + + +# If USER_NO_STOP is set to anything, the confirmation +# messages are not going to be asked. +USER_NO_STOP="y" + + +# USER_INSTALL_TYPE defines the installation type to +# be used during install. It can only be "local", +# "agent" or "server". +#USER_INSTALL_TYPE="local" +USER_INSTALL_TYPE="agent" +#USER_INSTALL_TYPE="server" + + +# USER_DIR defines the location to install openarmor +USER_DIR="/var/openarmor" + + +# If USER_DELETE_DIR is set to "y", the directory +# to install openarmor will be removed if present. +USER_DELETE_DIR="y" + + +# If USER_ENABLE_ACTIVE_RESPONSE is set to "n", +# active response will be disabled. +USER_ENABLE_ACTIVE_RESPONSE="n" + + +# If USER_ENABLE_SYSCHECK is set to "y", +# syscheck will be enabled. Set to "n" to +# disable it. +USER_ENABLE_SYSCHECK="y" + + +# If USER_ENABLE_ROOTCHECK is set to "y", +# rootcheck will be enabled. Set to "n" to +# disable it. +USER_ENABLE_ROOTCHECK="y" + + +# If USER_UPDATE is set to anything, the update +# installation will be done. +#USER_UPDATE="y" + +# If USER_UPDATE_RULES is set to anything, the +# rules will also be updated. +USER_UPDATE_RULES="y" + +# If USER_BINARYINSTALL is set, the installation +# is not going to compile the code, but use the +# binaries from ./bin/ +#USER_BINARYINSTALL="x" + + +### Agent Installation variables. ### + +# USER_AGENT_SERVER_IP specifies the IP address of the +# openarmor server. Only used on agent installations. +USER_AGENT_SERVER_IP="127.0.0.1" + + + +### Server/Local Installation variables. ### + +# USER_ENABLE_EMAIL enables or disables email alerting. +USER_ENABLE_EMAIL="n" + +# USER_EMAIL_ADDRESS defines the destination e-mail of the alerts. +#USER_EMAIL_ADDRESS="dcid@test.theopenarmor.org" + +# USER_EMAIL_SMTP defines the SMTP server to send the e-mails. +#USER_EMAIL_SMTP="test.theopenarmor.org" + + +# USER_ENABLE_SYSLOG enables or disables remote syslog. +USER_ENABLE_SYSLOG="n" + + +# USER_ENABLE_FIREWALL_RESPONSE enables or disables +# the firewall response. +USER_ENABLE_FIREWALL_RESPONSE="n" + + +# Enable PF firewall (OpenBSD, FreeBSD and Darwin only) +USER_ENABLE_PF="n" + + +# PF table to use (OpenBSD, FreeBSD and Darwin only). +#USER_PF_TABLE="openarmor_fwtable" + + +# USER_WHITE_LIST is a list of IPs or networks +# that are going to be set to never be blocked. +#USER_WHITE_LIST="192.168.2.1 192.168.1.0/24" + + +#### exit ? ### diff --git a/contrib/specs/getattr.pl b/contrib/specs/getattr.pl new file mode 100644 index 000000000..248bb94d7 --- /dev/null +++ b/contrib/specs/getattr.pl @@ -0,0 +1,61 @@ +#!/usr/bin/perl -w + +# +# find /var/openarmor/ -exec ./getattr.pl {} \; +# + +use File::stat; + +my %UID; +my %GUID; + +$filename = shift || die "\nsyntax: $0 \n\n"; + +get_uid(); +get_gid(); + +$sb = stat($filename); + +die "\nUID $sb->uid doesn't exist?! ($filename)\n\n" if (! exists($UID[$sb->uid])); +die "\nGID $sb->uid doesn't exist?! ($filename)\n\n" if (! exists($GID[$sb->gid])); + +if ( -d $filename ) { ### directory + print '%dir ' . $filename . "\n"; +} elsif ( -f $filename ) { ### file + print $filename . "\n"; +} else { + die("\nI can't handle: $filename\n\n"); +} + +# %attr(550, root, openarmor) /var/openarmor/etc + +printf "%%attr(%03o, %s, %s) %s\n", + $sb->mode & 07777, + $UID[$sb->uid], $GID[$sb->gid], $filename; + +#printf "%s: perm %04o, owner: %s, group: %s \n", +# $filename, $sb->mode & 07777, +# $UID[$sb->uid], $GID[$sb->gid]; + +sub get_uid +{ + open(FP,') { + ($name,$id) = (split(/:/,$line,))[0,2]; + $UID[$id] = $name; + } + close(FP); +} + +sub get_gid +{ + open(FP,') { + ($name,$id) = (split(/:/,$line,))[0,2]; + $GID[$id] = $name; + } + close(FP); +} + diff --git a/contrib/specs/local/openarmor-hids-local.spec b/contrib/specs/local/openarmor-hids-local.spec new file mode 100644 index 000000000..e4c29c9f2 --- /dev/null +++ b/contrib/specs/local/openarmor-hids-local.spec @@ -0,0 +1,331 @@ +# +# openarmor 1.3 .spec file - LOCAL +# Fri Aug 17 15:13:04 EDT 2007 +# +# +# TODO: +# +# o Safety checks for %clean +# +# o Remove script +# +# o create an RPM_README.txt and put it in the source tree +# +# + +Summary: Open Source Host-based Intrusion Detection System (Server) +Name: openarmor-hids-local-FC7 +Version: 1.3 +Release: 1 +License: GPLv2 +Group: Applications/Security +URL: http://www.theopenarmor.org +Packager: Michael Williams (maverick@maverick.org) +Source: http://www.theopenarmor.org/files/openarmor-hids-1.3.tar.gz +Requires: /usr/sbin/useradd, /usr/sbin/groupadd, /usr/sbin/groupdel, /usr/sbin/userdel, /sbin/service, /sbin/chkconfig + +%description +openarmor is an Open Source Host-based Intrusion +Detection System. It performs log analysis, +integrity checking, Windows registry monitoring, +rootkit detection, real-time alerting and active +response. + + +%prep + +%setup -n openarmor-hids-1.3 + +%build +/bin/cp /usr/local/src/openarmor-RPM/1.3/local/preloaded-vars.conf ${RPM_BUILD_DIR}/openarmor-hids-1.3/etc/ + +./install.sh + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +################################################################################ +# Create openarmor group +# +if ! grep "^openarmor" /etc/group > /dev/null ; then + /usr/sbin/groupadd --system openarmor +fi + + +################################################################################ +# Create openarmor users +# +for USER in openarmor openarmorm openarmorr ; do + if ! grep "^${USER}" /etc/passwd > /dev/null ; then + /usr/sbin/useradd --system -d /var/openarmor -s /bin/false -g openarmor ${USER} + fi +done + +%post + + + +################################################################################ +# Create openarmor /etc/init.d/openarmor file +# +cat <> /etc/init.d/openarmor +#!/bin/bash +# +# openarmor Starts openarmor +# +# +# chkconfig: 2345 12 88 +# description: openarmor is an open source host based IDS +### BEGIN INIT INFO +# Provides: $openarmor +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +[ -f /var/openarmor/bin/openarmor-control ] || exit 0 + +RETVAL=0 + +umask 077 + +case "\$1" in + start) + /var/openarmor/bin/openarmor-control start + ;; + stop) + /var/openarmor/bin/openarmor-control stop + ;; + status) + /var/openarmor/bin/openarmor-control status + ;; + restart|reload) + /var/openarmor/bin/openarmor-control restart + ;; + *) + echo "Usage: /var/openarmor/bin/openarmor-control {start|stop|status|restart}" + exit 1 +esac + +EOF + +/bin/chown root.root /etc/init.d/openarmor +/bin/chmod 755 /etc/init.d/openarmor + +################################################################################ +# Set configuration so openarmor starts on reboot +# +/sbin/chkconfig --add openarmor +/sbin/chkconfig openarmor on + +%postun +# Run service command, make sure openarmor is stopped +/sbin/service openarmor stop + +# Run chkconfig, stop openarmor from starting on boot +/sbin/chkconfig openarmor off +/sbin/chkconfig --del openarmor + +# Remove init.d file +[ -f /etc/init.d/openarmor ] && rm /etc/init.d/openarmor + +# Remove openarmor users +for USER in openarmor openarmorm openarmorr ; do + if grep "^${USER}" /etc/passwd > /dev/null ; then + /usr/sbin/userdel -r ${USER} + fi +done + +# Remove openarmor group +if grep "^openarmor" /etc/group > /dev/null ; then + /usr/sbin/groupdel openarmor +fi + + +%files +%doc README BUGS CONFIG CONTRIB INSTALL LICENSE + +%dir /var/openarmor/ +%attr(550, root, openarmor) /var/openarmor/ +%dir /var/openarmor/stats +%attr(750, openarmor, openarmor) /var/openarmor/stats +%dir /var/openarmor/var +%attr(550, root, openarmor) /var/openarmor/var +%dir /var/openarmor/var/run +%attr(770, root, openarmor) /var/openarmor/var/run +%dir /var/openarmor/active-response +%attr(550, root, openarmor) /var/openarmor/active-response +%dir /var/openarmor/active-response/bin +%attr(550, root, openarmor) /var/openarmor/active-response/bin +/var/openarmor/active-response/bin/route-null.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/route-null.sh +/var/openarmor/active-response/bin/host-deny.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/host-deny.sh +/var/openarmor/active-response/bin/firewall-drop.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/firewall-drop.sh +/var/openarmor/active-response/bin/disable-account.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/disable-account.sh +%dir /var/openarmor/tmp +%attr(550, root, openarmor) /var/openarmor/tmp +%dir /var/openarmor/bin +%attr(550, root, openarmor) /var/openarmor/bin +/var/openarmor/bin/openarmor-agentd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-agentd +/var/openarmor/bin/openarmor-logcollector +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-logcollector +/var/openarmor/bin/openarmor-control +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-control +/var/openarmor/bin/openarmor-syscheckd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-syscheckd +/var/openarmor/bin/manage_agents +%attr(550, root, openarmor) /var/openarmor/bin/manage_agents +/var/openarmor/bin/openarmor-remoted +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-remoted +/var/openarmor/bin/openarmor-monitord +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-monitord +/var/openarmor/bin/list_agents +%attr(550, root, openarmor) /var/openarmor/bin/list_agents +/var/openarmor/bin/clear_stats +%attr(550, root, openarmor) /var/openarmor/bin/clear_stats +/var/openarmor/bin/openarmor-execd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-execd +/var/openarmor/bin/openarmor-maild +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-maild +/var/openarmor/bin/openarmor-analysisd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-analysisd +/var/openarmor/bin/syscheck_update +%attr(550, root, openarmor) /var/openarmor/bin/syscheck_update +%dir /var/openarmor/etc +%attr(550, root, openarmor) /var/openarmor/etc +/var/openarmor/etc/internal_options.conf +%attr(440, root, openarmor) /var/openarmor/etc/internal_options.conf +/var/openarmor/etc/localtime +%attr(555, root, openarmor) /var/openarmor/etc/localtime +%dir /var/openarmor/etc/shared +%attr(550, root, openarmor) /var/openarmor/etc/shared +/var/openarmor/etc/shared/win_malware_rcl.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/win_malware_rcl.txt +/var/openarmor/etc/shared/win_applications_rcl.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/win_applications_rcl.txt +/var/openarmor/etc/shared/win_audit_rcl.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/win_audit_rcl.txt +/var/openarmor/etc/shared/rootkit_files.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/rootkit_files.txt +/var/openarmor/etc/shared/rootkit_trojans.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/rootkit_trojans.txt +/var/openarmor/etc/openarmor.conf +%attr(440, root, openarmor) /var/openarmor/etc/openarmor.conf +/var/openarmor/etc/decoder.xml +%attr(440, root, openarmor) /var/openarmor/etc/decoder.xml +%dir /var/openarmor/rules +%attr(550, root, openarmor) /var/openarmor/rules +/var/openarmor/rules/ms_ftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ms_ftpd_rules.xml +/var/openarmor/rules/zeus_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/zeus_rules.xml +/var/openarmor/rules/squid_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/squid_rules.xml +/var/openarmor/rules/racoon_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/racoon_rules.xml +/var/openarmor/rules/smbd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/smbd_rules.xml +/var/openarmor/rules/proftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/proftpd_rules.xml +/var/openarmor/rules/msauth_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/msauth_rules.xml +/var/openarmor/rules/ms-exchange_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ms-exchange_rules.xml +/var/openarmor/rules/symantec-ws_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/symantec-ws_rules.xml +/var/openarmor/rules/sendmail_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/sendmail_rules.xml +/var/openarmor/rules/web_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/web_rules.xml +/var/openarmor/rules/netscreenfw_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/netscreenfw_rules.xml +/var/openarmor/rules/attack_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/attack_rules.xml +/var/openarmor/rules/hordeimp_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/hordeimp_rules.xml +/var/openarmor/rules/postfix_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/postfix_rules.xml +/var/openarmor/rules/rules_config.xml +%attr(550, root, openarmor) /var/openarmor/rules/rules_config.xml +/var/openarmor/rules/spamd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/spamd_rules.xml +/var/openarmor/rules/cisco-ios_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/cisco-ios_rules.xml +/var/openarmor/rules/local_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/local_rules.xml +/var/openarmor/rules/apache_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/apache_rules.xml +/var/openarmor/rules/mailscanner_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/mailscanner_rules.xml +/var/openarmor/rules/vpn_concentrator_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/vpn_concentrator_rules.xml +/var/openarmor/rules/firewall_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/firewall_rules.xml +/var/openarmor/rules/named_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/named_rules.xml +/var/openarmor/rules/openarmor_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/openarmor_rules.xml +/var/openarmor/rules/courier_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/courier_rules.xml +/var/openarmor/rules/vsftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/vsftpd_rules.xml +/var/openarmor/rules/vpopmail_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/vpopmail_rules.xml +/var/openarmor/rules/pure-ftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/pure-ftpd_rules.xml +/var/openarmor/rules/telnetd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/telnetd_rules.xml +/var/openarmor/rules/pix_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/pix_rules.xml +/var/openarmor/rules/ftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ftpd_rules.xml +/var/openarmor/rules/ids_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ids_rules.xml +/var/openarmor/rules/symantec-av_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/symantec-av_rules.xml +/var/openarmor/rules/arpwatch_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/arpwatch_rules.xml +/var/openarmor/rules/policy_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/policy_rules.xml +/var/openarmor/rules/sshd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/sshd_rules.xml +/var/openarmor/rules/syslog_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/syslog_rules.xml +/var/openarmor/rules/pam_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/pam_rules.xml +/var/openarmor/rules/imapd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/imapd_rules.xml +%dir /var/openarmor/logs +%attr(750, openarmor, openarmor) /var/openarmor/logs +%dir /var/openarmor/logs/alerts +%attr(750, openarmor, openarmor) /var/openarmor/logs/alerts +%dir /var/openarmor/logs/firewall +%attr(750, openarmor, openarmor) /var/openarmor/logs/firewall +%dir /var/openarmor/logs/archives +%attr(750, openarmor, openarmor) /var/openarmor/logs/archives +/var/openarmor/logs/openarmor.log +%attr(664, openarmor, openarmor) /var/openarmor/logs/openarmor.log +%dir /var/openarmor/queue +%attr(550, root, openarmor) /var/openarmor/queue +%dir /var/openarmor/queue/fts +%attr(750, openarmor, openarmor) /var/openarmor/queue/fts +%dir /var/openarmor/queue/rids +%attr(755, openarmorr, openarmor) /var/openarmor/queue/rids +%dir /var/openarmor/queue/alerts +%attr(770, openarmor, openarmor) /var/openarmor/queue/alerts +%dir /var/openarmor/queue/rootcheck +%attr(750, openarmor, openarmor) /var/openarmor/queue/rootcheck +%dir /var/openarmor/queue/agent-info +%attr(755, openarmorr, openarmor) /var/openarmor/queue/agent-info +%dir /var/openarmor/queue/syscheck +%attr(750, openarmor, openarmor) /var/openarmor/queue/syscheck +%dir /var/openarmor/queue/openarmor +%attr(770, openarmor, openarmor) /var/openarmor/queue/openarmor + + + diff --git a/contrib/specs/local/preloaded-vars.conf b/contrib/specs/local/preloaded-vars.conf new file mode 100644 index 000000000..c013f4e35 --- /dev/null +++ b/contrib/specs/local/preloaded-vars.conf @@ -0,0 +1,121 @@ +# preloaded-vars.conf, Daniel B. Cid (dcid @ theopenarmor.org). +# +# RPM: server/local/agent version, 1.2, 2007.07.23 +# +# +# Use this file to customize your installations. +# It will make the install.sh script pre-load some +# specific options to make it run automatically +# or with less questions. + +# PLEASE NOTE: +# When we use "n" or "y" in here, it should be changed +# to "n" or "y" in the language your are doing the +# installation. For example, in portuguese it would +# be "s" or "n". + + +# USER_LANGUAGE defines to language to be used. +# It can be "en", "br", "tr", "it", "de" or "pl". +# In case of an invalid language, it will default +# to English "en" +USER_LANGUAGE="en" # For english +#USER_LANGUAGE="br" # For portuguese + + +# If USER_NO_STOP is set to anything, the confirmation +# messages are not going to be asked. +USER_NO_STOP="y" + + +# USER_INSTALL_TYPE defines the installation type to +# be used during install. It can only be "local", +# "agent" or "server". +USER_INSTALL_TYPE="local" +#USER_INSTALL_TYPE="agent" +#USER_INSTALL_TYPE="server" + + +# USER_DIR defines the location to install openarmor +USER_DIR="/var/openarmor" + + +# If USER_DELETE_DIR is set to "y", the directory +# to install openarmor will be removed if present. +USER_DELETE_DIR="y" + + +# If USER_ENABLE_ACTIVE_RESPONSE is set to "n", +# active response will be disabled. +USER_ENABLE_ACTIVE_RESPONSE="n" + + +# If USER_ENABLE_SYSCHECK is set to "y", +# syscheck will be enabled. Set to "n" to +# disable it. +USER_ENABLE_SYSCHECK="y" + + +# If USER_ENABLE_ROOTCHECK is set to "y", +# rootcheck will be enabled. Set to "n" to +# disable it. +USER_ENABLE_ROOTCHECK="y" + + +# If USER_UPDATE is set to anything, the update +# installation will be done. +#USER_UPDATE="y" + +# If USER_UPDATE_RULES is set to anything, the +# rules will also be updated. +USER_UPDATE_RULES="y" + +# If USER_BINARYINSTALL is set, the installation +# is not going to compile the code, but use the +# binaries from ./bin/ +#USER_BINARYINSTALL="x" + + +### Agent Installation variables. ### + +# USER_AGENT_SERVER_IP specifies the IP address of the +# openarmor server. Only used on agent installations. +#USER_AGENT_SERVER_IP="1.2.3.4" + + + +### Server/Local Installation variables. ### + +# USER_ENABLE_EMAIL enables or disables email alerting. +USER_ENABLE_EMAIL="n" + +# USER_EMAIL_ADDRESS defines the destination e-mail of the alerts. +#USER_EMAIL_ADDRESS="dcid@test.theopenarmor.org" + +# USER_EMAIL_SMTP defines the SMTP server to send the e-mails. +#USER_EMAIL_SMTP="test.theopenarmor.org" + + +# USER_ENABLE_SYSLOG enables or disables remote syslog. +USER_ENABLE_SYSLOG="n" + + +# USER_ENABLE_FIREWALL_RESPONSE enables or disables +# the firewall response. +USER_ENABLE_FIREWALL_RESPONSE="n" + + +# Enable PF firewall (OpenBSD, FreeBSD and Darwin only) +USER_ENABLE_PF="n" + + +# PF table to use (OpenBSD, FreeBSD and Darwin only). +#USER_PF_TABLE="openarmor_fwtable" + + +# USER_WHITE_LIST is a list of IPs or networks +# that are going to be set to never be blocked. +#USER_WHITE_LIST="192.168.2.1 192.168.1.0/24" + + +#### exit ? ### diff --git a/contrib/specs/remove_openarmor b/contrib/specs/remove_openarmor new file mode 100644 index 000000000..b5a5be1e3 --- /dev/null +++ b/contrib/specs/remove_openarmor @@ -0,0 +1,19 @@ +#!/bin/bash + +rpm -e openarmor-hids-server-FC7 +rpm -e openarmor-hids-local-FC7 +rpm -e openarmor-hids-agent-FC7 + +rm -fr /var/openarmor/ + +for A in openarmor openarmorm openarmorr ; do /usr/sbin/userdel -r $A ; done + +/usr/sbin/groupdel openarmor + +/sbin/chkconfig openarmor off +/sbin/chkconfig --del openarmor + +# Remove init.d file +[ -f /etc/init.d/openarmor ] && rm /etc/init.d/openarmor + + diff --git a/contrib/specs/server/openarmor-hids-server.spec b/contrib/specs/server/openarmor-hids-server.spec new file mode 100644 index 000000000..0b856e5e9 --- /dev/null +++ b/contrib/specs/server/openarmor-hids-server.spec @@ -0,0 +1,329 @@ +# +# openarmor 1.3 .spec file - SERVER +# Fri Aug 17 15:13:32 EDT 2007 +# +# +# TODO: +# +# o Safety checks for %clean +# +# o Remove script +# +# o create an RPM_README.txt and put it in the source tree +# +# + +Summary: Open Source Host-based Intrusion Detection System (Server) +Name: openarmor-hids-server-FC7 +Version: 1.3 +Release: 1 +License: GPLv2 +Group: Applications/Security +URL: http://www.theopenarmor.org +Packager: Michael Williams (maverick@maverick.org) +Source: http://www.theopenarmor.org/files/openarmor-hids-1.3.tar.gz +Requires: /usr/sbin/useradd, /usr/sbin/groupadd, /usr/sbin/groupdel, /usr/sbin/userdel, /sbin/service, /sbin/chkconfig + +%description +openarmor is an Open Source Host-based Intrusion +Detection System. It performs log analysis, +integrity checking, Windows registry monitoring, +rootkit detection, real-time alerting and active +response. + + +%prep + +%setup -n openarmor-hids-1.3 + +%build +/bin/cp /usr/local/src/openarmor-RPM/1.3/server/preloaded-vars.conf ${RPM_BUILD_DIR}/openarmor-hids-1.3/etc/ + +./install.sh + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +################################################################################ +# Create openarmor group +# +if ! grep "^openarmor" /etc/group > /dev/null ; then + /usr/sbin/groupadd --system openarmor +fi + + +################################################################################ +# Create openarmor users +# +for USER in openarmor openarmorm openarmorr ; do + if ! grep "^${USER}" /etc/passwd > /dev/null ; then + /usr/sbin/useradd --system -d /var/openarmor -s /bin/false -g openarmor ${USER} + fi +done + +%post + + + +################################################################################ +# Create openarmor /etc/init.d/openarmor file +# +cat <> /etc/init.d/openarmor +#!/bin/bash +# +# openarmor Starts openarmor +# +# +# chkconfig: 2345 12 88 +# description: openarmor is an open source host based IDS +### BEGIN INIT INFO +# Provides: $openarmor +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +[ -f /var/openarmor/bin/openarmor-control ] || exit 0 + +RETVAL=0 + +umask 077 + +case "\$1" in + start) + /var/openarmor/bin/openarmor-control start + ;; + stop) + /var/openarmor/bin/openarmor-control stop + ;; + status) + /var/openarmor/bin/openarmor-control status + ;; + restart|reload) + /var/openarmor/bin/openarmor-control restart + ;; + *) + echo "Usage: /var/openarmor/bin/openarmor-control {start|stop|status|restart}" + exit 1 +esac + +EOF + +/bin/chown root.root /etc/init.d/openarmor +/bin/chmod 755 /etc/init.d/openarmor + +################################################################################ +# Set configuration so openarmor starts on reboot +# +/sbin/chkconfig --add openarmor +/sbin/chkconfig openarmor on + +%postun +# Run service command, make sure openarmor is stopped +/sbin/service openarmor stop + +# Run chkconfig, stop openarmor from starting on boot +/sbin/chkconfig openarmor off +/sbin/chkconfig --del openarmor + +# Remove init.d file +[ -f /etc/init.d/openarmor ] && rm /etc/init.d/openarmor + +# Remove openarmor users +for USER in openarmor openarmorm openarmorr ; do + if grep "^${USER}" /etc/passwd > /dev/null ; then + /usr/sbin/userdel -r ${USER} + fi +done + +# Remove openarmor group +if grep "^openarmor" /etc/group > /dev/null ; then + /usr/sbin/groupdel openarmor +fi + + +%files +%doc README BUGS CONFIG CONTRIB INSTALL LICENSE + +%dir /var/openarmor/ +%attr(550, root, openarmor) /var/openarmor/ +%dir /var/openarmor/stats +%attr(750, openarmor, openarmor) /var/openarmor/stats +%dir /var/openarmor/var +%attr(550, root, openarmor) /var/openarmor/var +%dir /var/openarmor/var/run +%attr(770, root, openarmor) /var/openarmor/var/run +%dir /var/openarmor/active-response +%attr(550, root, openarmor) /var/openarmor/active-response +%dir /var/openarmor/active-response/bin +%attr(550, root, openarmor) /var/openarmor/active-response/bin +/var/openarmor/active-response/bin/route-null.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/route-null.sh +/var/openarmor/active-response/bin/host-deny.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/host-deny.sh +/var/openarmor/active-response/bin/firewall-drop.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/firewall-drop.sh +/var/openarmor/active-response/bin/disable-account.sh +%attr(755, root, openarmor) /var/openarmor/active-response/bin/disable-account.sh +%dir /var/openarmor/tmp +%attr(550, root, openarmor) /var/openarmor/tmp +%dir /var/openarmor/bin +%attr(550, root, openarmor) /var/openarmor/bin +/var/openarmor/bin/openarmor-agentd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-agentd +/var/openarmor/bin/openarmor-logcollector +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-logcollector +/var/openarmor/bin/openarmor-control +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-control +/var/openarmor/bin/openarmor-syscheckd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-syscheckd +/var/openarmor/bin/manage_agents +%attr(550, root, openarmor) /var/openarmor/bin/manage_agents +/var/openarmor/bin/openarmor-remoted +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-remoted +/var/openarmor/bin/openarmor-monitord +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-monitord +/var/openarmor/bin/list_agents +%attr(550, root, openarmor) /var/openarmor/bin/list_agents +/var/openarmor/bin/clear_stats +%attr(550, root, openarmor) /var/openarmor/bin/clear_stats +/var/openarmor/bin/openarmor-execd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-execd +/var/openarmor/bin/openarmor-maild +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-maild +/var/openarmor/bin/openarmor-analysisd +%attr(550, root, openarmor) /var/openarmor/bin/openarmor-analysisd +/var/openarmor/bin/syscheck_update +%attr(550, root, openarmor) /var/openarmor/bin/syscheck_update +%dir /var/openarmor/etc +%attr(550, root, openarmor) /var/openarmor/etc +/var/openarmor/etc/internal_options.conf +%attr(440, root, openarmor) /var/openarmor/etc/internal_options.conf +/var/openarmor/etc/localtime +%attr(555, root, openarmor) /var/openarmor/etc/localtime +%dir /var/openarmor/etc/shared +%attr(550, root, openarmor) /var/openarmor/etc/shared +/var/openarmor/etc/shared/win_malware_rcl.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/win_malware_rcl.txt +/var/openarmor/etc/shared/win_applications_rcl.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/win_applications_rcl.txt +/var/openarmor/etc/shared/win_audit_rcl.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/win_audit_rcl.txt +/var/openarmor/etc/shared/rootkit_files.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/rootkit_files.txt +/var/openarmor/etc/shared/rootkit_trojans.txt +%attr(440, root, openarmor) /var/openarmor/etc/shared/rootkit_trojans.txt +/var/openarmor/etc/openarmor.conf +%attr(440, root, openarmor) /var/openarmor/etc/openarmor.conf +/var/openarmor/etc/decoder.xml +%attr(440, root, openarmor) /var/openarmor/etc/decoder.xml +%dir /var/openarmor/rules +%attr(550, root, openarmor) /var/openarmor/rules +/var/openarmor/rules/ms_ftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ms_ftpd_rules.xml +/var/openarmor/rules/zeus_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/zeus_rules.xml +/var/openarmor/rules/squid_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/squid_rules.xml +/var/openarmor/rules/racoon_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/racoon_rules.xml +/var/openarmor/rules/smbd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/smbd_rules.xml +/var/openarmor/rules/proftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/proftpd_rules.xml +/var/openarmor/rules/msauth_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/msauth_rules.xml +/var/openarmor/rules/ms-exchange_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ms-exchange_rules.xml +/var/openarmor/rules/symantec-ws_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/symantec-ws_rules.xml +/var/openarmor/rules/sendmail_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/sendmail_rules.xml +/var/openarmor/rules/web_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/web_rules.xml +/var/openarmor/rules/netscreenfw_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/netscreenfw_rules.xml +/var/openarmor/rules/attack_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/attack_rules.xml +/var/openarmor/rules/hordeimp_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/hordeimp_rules.xml +/var/openarmor/rules/postfix_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/postfix_rules.xml +/var/openarmor/rules/rules_config.xml +%attr(550, root, openarmor) /var/openarmor/rules/rules_config.xml +/var/openarmor/rules/spamd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/spamd_rules.xml +/var/openarmor/rules/cisco-ios_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/cisco-ios_rules.xml +/var/openarmor/rules/local_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/local_rules.xml +/var/openarmor/rules/apache_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/apache_rules.xml +/var/openarmor/rules/mailscanner_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/mailscanner_rules.xml +/var/openarmor/rules/vpn_concentrator_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/vpn_concentrator_rules.xml +/var/openarmor/rules/firewall_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/firewall_rules.xml +/var/openarmor/rules/named_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/named_rules.xml +/var/openarmor/rules/openarmor_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/openarmor_rules.xml +/var/openarmor/rules/courier_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/courier_rules.xml +/var/openarmor/rules/vsftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/vsftpd_rules.xml +/var/openarmor/rules/vpopmail_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/vpopmail_rules.xml +/var/openarmor/rules/pure-ftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/pure-ftpd_rules.xml +/var/openarmor/rules/telnetd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/telnetd_rules.xml +/var/openarmor/rules/pix_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/pix_rules.xml +/var/openarmor/rules/ftpd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ftpd_rules.xml +/var/openarmor/rules/ids_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/ids_rules.xml +/var/openarmor/rules/symantec-av_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/symantec-av_rules.xml +/var/openarmor/rules/arpwatch_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/arpwatch_rules.xml +/var/openarmor/rules/policy_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/policy_rules.xml +/var/openarmor/rules/sshd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/sshd_rules.xml +/var/openarmor/rules/syslog_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/syslog_rules.xml +/var/openarmor/rules/pam_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/pam_rules.xml +/var/openarmor/rules/imapd_rules.xml +%attr(550, root, openarmor) /var/openarmor/rules/imapd_rules.xml +%dir /var/openarmor/logs +%attr(750, openarmor, openarmor) /var/openarmor/logs +%dir /var/openarmor/logs/alerts +%attr(750, openarmor, openarmor) /var/openarmor/logs/alerts +%dir /var/openarmor/logs/firewall +%attr(750, openarmor, openarmor) /var/openarmor/logs/firewall +%dir /var/openarmor/logs/archives +%attr(750, openarmor, openarmor) /var/openarmor/logs/archives +/var/openarmor/logs/openarmor.log +%attr(664, openarmor, openarmor) /var/openarmor/logs/openarmor.log +%dir /var/openarmor/queue +%attr(550, root, openarmor) /var/openarmor/queue +%dir /var/openarmor/queue/fts +%attr(750, openarmor, openarmor) /var/openarmor/queue/fts +%dir /var/openarmor/queue/rids +%attr(755, openarmorr, openarmor) /var/openarmor/queue/rids +%dir /var/openarmor/queue/alerts +%attr(770, openarmor, openarmor) /var/openarmor/queue/alerts +%dir /var/openarmor/queue/rootcheck +%attr(750, openarmor, openarmor) /var/openarmor/queue/rootcheck +%dir /var/openarmor/queue/agent-info +%attr(755, openarmorr, openarmor) /var/openarmor/queue/agent-info +%dir /var/openarmor/queue/syscheck +%attr(750, openarmor, openarmor) /var/openarmor/queue/syscheck +%dir /var/openarmor/queue/openarmor +%attr(770, openarmor, openarmor) /var/openarmor/queue/openarmor + diff --git a/contrib/specs/server/preloaded-vars.conf b/contrib/specs/server/preloaded-vars.conf new file mode 100644 index 000000000..264ac75b8 --- /dev/null +++ b/contrib/specs/server/preloaded-vars.conf @@ -0,0 +1,121 @@ +# preloaded-vars.conf, Daniel B. Cid (dcid @ theopenarmor.org). +# +# RPM: server/local/agent version, 1.2, 2007.07.23 +# +# +# Use this file to customize your installations. +# It will make the install.sh script pre-load some +# specific options to make it run automatically +# or with less questions. + +# PLEASE NOTE: +# When we use "n" or "y" in here, it should be changed +# to "n" or "y" in the language your are doing the +# installation. For example, in portuguese it would +# be "s" or "n". + + +# USER_LANGUAGE defines to language to be used. +# It can be "en", "br", "tr", "it", "de" or "pl". +# In case of an invalid language, it will default +# to English "en" +USER_LANGUAGE="en" # For english +#USER_LANGUAGE="br" # For portuguese + + +# If USER_NO_STOP is set to anything, the confirmation +# messages are not going to be asked. +USER_NO_STOP="y" + + +# USER_INSTALL_TYPE defines the installation type to +# be used during install. It can only be "local", +# "agent" or "server". +#USER_INSTALL_TYPE="local" +#USER_INSTALL_TYPE="agent" +USER_INSTALL_TYPE="server" + + +# USER_DIR defines the location to install openarmor +USER_DIR="/var/openarmor" + + +# If USER_DELETE_DIR is set to "y", the directory +# to install openarmor will be removed if present. +USER_DELETE_DIR="y" + + +# If USER_ENABLE_ACTIVE_RESPONSE is set to "n", +# active response will be disabled. +USER_ENABLE_ACTIVE_RESPONSE="n" + + +# If USER_ENABLE_SYSCHECK is set to "y", +# syscheck will be enabled. Set to "n" to +# disable it. +USER_ENABLE_SYSCHECK="y" + + +# If USER_ENABLE_ROOTCHECK is set to "y", +# rootcheck will be enabled. Set to "n" to +# disable it. +USER_ENABLE_ROOTCHECK="y" + + +# If USER_UPDATE is set to anything, the update +# installation will be done. +#USER_UPDATE="y" + +# If USER_UPDATE_RULES is set to anything, the +# rules will also be updated. +USER_UPDATE_RULES="y" + +# If USER_BINARYINSTALL is set, the installation +# is not going to compile the code, but use the +# binaries from ./bin/ +#USER_BINARYINSTALL="x" + + +### Agent Installation variables. ### + +# USER_AGENT_SERVER_IP specifies the IP address of the +# openarmor server. Only used on agent installations. +#USER_AGENT_SERVER_IP="1.2.3.4" + + + +### Server/Local Installation variables. ### + +# USER_ENABLE_EMAIL enables or disables email alerting. +USER_ENABLE_EMAIL="n" + +# USER_EMAIL_ADDRESS defines the destination e-mail of the alerts. +#USER_EMAIL_ADDRESS="dcid@test.theopenarmor.org" + +# USER_EMAIL_SMTP defines the SMTP server to send the e-mails. +#USER_EMAIL_SMTP="test.theopenarmor.org" + + +# USER_ENABLE_SYSLOG enables or disables remote syslog. +USER_ENABLE_SYSLOG="n" + + +# USER_ENABLE_FIREWALL_RESPONSE enables or disables +# the firewall response. +USER_ENABLE_FIREWALL_RESPONSE="y" + + +# Enable PF firewall (OpenBSD, FreeBSD and Darwin only) +USER_ENABLE_PF="n" + + +# PF table to use (OpenBSD, FreeBSD and Darwin only). +#USER_PF_TABLE="openarmor_fwtable" + + +# USER_WHITE_LIST is a list of IPs or networks +# that are going to be set to never be blocked. +#USER_WHITE_LIST="192.168.2.1 192.168.1.0/24" + + +#### exit ? ### diff --git a/contrib/util.sh b/contrib/util.sh new file mode 100644 index 000000000..44b838305 --- /dev/null +++ b/contrib/util.sh @@ -0,0 +1,189 @@ +#!/bin/sh +# Simple utilities +# Add a new file +# Add a new remote host to be monitored via lynx +# Add a new remote host to be monitored (DNS) +# Add a new command to be monitored +# by Daniel B. Cid - dcid ( at ) theopenarmor.org + +ACTION=$1 +FILE=$2 +FORMAT=$3 + +if ! [ -e /etc/openarmor-init.conf ]; then + echo openarmor Manager not found. Exiting... + exit 1 +fi + +. /etc/openarmor-init.conf + +if [ "X$FILE" = "X" ]; then + echo "$0: addfile []" + echo "$0: addsite " + echo "$0: adddns " + #echo "$0: addcommand " + echo "" + #echo "Example: $0 addcommand 'netstat -tan |grep LISTEN| grep -v 127.0.0.1'" + echo "Example: $0 adddns theopenarmor.org" + echo "Example: $0 addsite dcid.me" + exit 1; +fi + +if [ "X$FORMAT" = "X" ]; then + FORMAT="syslog" +fi + +# Adding a new file +if [ $ACTION = "addfile" ]; then + # Checking if file is already configured + grep "$FILE" ${DIRECTORY}/etc/openarmor.conf > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "$0: File $FILE already configured at openarmor." + exit 1; + fi + + # Checking if file exist + ls -la $FILE > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "$0: File $FILE does not exist." + exit 1; + fi + + echo " + + + $FORMAT + $FILE + + + " >> ${DIRECTORY}/etc/openarmor.conf + + echo "$0: File $FILE added."; + exit 0; +fi + + +# Adding a new DNS check +if [ $ACTION = "adddns" ]; then + COMMAND="host -W 5 -t NS $FILE; host -W 5 -t A $FILE | sort" + echo $FILE | grep -E '^[a-z0-9A-Z.-]+$' >/dev/null 2>&1 + if [ $? = 1 ]; then + echo "$0: Invalid domain: $FILE" + exit 1; + fi + + grep "host -W 5 -t NS $FILE" ${DIRECTORY}/etc/openarmor.conf >/dev/null 2>&1 + if [ $? = 0 ]; then + echo "$0: Already configured for $FILE" + exit 1; + fi + + MYERR=0 + echo " + + + full_command + $COMMAND + + + " >> ${DIRECTORY}/etc/openarmor.conf || MYERR=1; + + if [ $MYERR = 1 ]; then + echo "$0: Unable to modify the configuration file."; + exit 1; + fi + + FIRSTRULE="150010" + while [ 1 ]; do + grep "\"$FIRSTRULE\"" ${DIRECTORY}/rules/local_rules.xml > /dev/null 2>&1 + if [ $? = 0 ]; then + FIRSTRULE=`expr $FIRSTRULE + 1` + else + break; + fi + done + + + echo " + + + 530 + + ^openarmor: output: 'host -W 5 -t NS $FILE + DNS Changed for $FILE + + + " >> ${DIRECTORY}/rules/local_rules.xml || MYERR=1; + + if [ $MYERR = 1 ]; then + echo "$0: Unable to modify the local rules file."; + exit 1; + fi + + echo "Domain $FILE added to be monitored." + exit 0; +fi + + +# Adding a new lynx check +if [ $ACTION = "addsite" ]; then + COMMAND="lynx --connect_timeout 10 --dump $FILE | head -n 10" + echo $FILE | grep -E '^[a-z0-9A-Z.-]+$' >/dev/null 2>&1 + if [ $? = 1 ]; then + echo "$0: Invalid domain: $FILE" + exit 1; + fi + + grep "lynx --connect_timeout 10 --dump $FILE" ${DIRECTORY}/etc/openarmor.conf >/dev/null 2>&1 + if [ $? = 0 ]; then + echo "$0: Already configured for $FILE" + exit 1; + fi + + MYERR=0 + echo " + + + full_command + $COMMAND + + + " >> ${DIRECTORY}/etc/openarmor.conf || MYERR=1; + + if [ $MYERR = 1 ]; then + echo "$0: Unable to modify the configuration file."; + exit 1; + fi + + FIRSTRULE="150010" + while [ 1 ]; do + grep "\"$FIRSTRULE\"" ${DIRECTORY}/rules/local_rules.xml > /dev/null 2>&1 + if [ $? = 0 ]; then + FIRSTRULE=`expr $FIRSTRULE + 1` + else + break; + fi + done + + + echo " + + + 530 + + ^openarmor: output: 'lynx --connect_timeout 10 --dump $FILE + DNS Changed for $FILE + + + " >> ${DIRECTORY}/rules/local_rules.xml || MYERR=1; + + if [ $MYERR = 1 ]; then + echo "$0: Unable to modify the local rules file."; + exit 1; + fi + + echo "Domain $FILE added to be monitored." + exit 0; +fi + + diff --git a/contrib/version_bump.sh b/contrib/version_bump.sh new file mode 100644 index 000000000..a379fbae5 --- /dev/null +++ b/contrib/version_bump.sh @@ -0,0 +1,43 @@ +#!/bin/sh + + +## Run this from src/ +## Do not add the "v" before the version number + +OLDVERSION=${1} +NEWVERSION=${2} + +if [ "X${OLDVERSION}" == "X" ]; then + echo "You must provide the version numbers" + echo "version_bump.sh x.0.0 x.1.0" + exit 1 +fi + +if [ "X${NEWVERSION}" == "X" ]; then + echo "You must provide the version numbers" + echo "version_bump.sh x.0.0 x.1.0" + exit 1 +fi + +echo "v${NEWVERSION}" > src/VERSION + +# openarmor init scripts +sed -i -e "s/VERSION=\"v${OLDVERSION}/VERSION=\"v${NEWVERSION}/" src/init/openarmor-client.sh +sed -i -e "s/VERSION=\"v${OLDVERSION}/VERSION=\"v${NEWVERSION}/" src/init/openarmor-local.sh +sed -i -e "s/VERSION=\"v${OLDVERSION}/VERSION=\"v${NEWVERSION}/" src/init/openarmor-server.sh + +# Win32 files +sed -i -e "s/VERSION \"${OLDVERSION}/VERSION \"${NEWVERSION}/" src/win32/openarmor-installer.nsi +sed -i -e "s/Agent v${OLDVERSION}/Agent v${NEWVERSION}/" src/win32/help.txt + +# misc +sed -i -e "s/openarmor v${OLDVERSION}/openarmor v${NEWVERSION}/" INSTALL +sed -i -e "s/openarmor v${OLDVERSION}/openarmor v${NEWVERSION}/" README.md +sed -i -e "s/openarmor v${OLDVERSION}/openarmor v${NEWVERSION}/" CONFIG +sed -i -e "s/openarmor v${OLDVERSION}/openarmor v${NEWVERSION}/" BUGS + +# update defs.h +sed -i -e "s/v${OLDVERSION}/v${NEWVERSION}/" src/headers/defs.h + +# Update CONFIG + diff --git a/contrib/zeromq_pubsub.py b/contrib/zeromq_pubsub.py new file mode 100644 index 000000000..6047777fe --- /dev/null +++ b/contrib/zeromq_pubsub.py @@ -0,0 +1,9 @@ +import zmq + +context = zmq.Context() +s = context.socket(zmq.SUB) +s.connect("tcp://localhost:11999") +s.setsockopt(zmq.SUBSCRIBE, "") +while 1: + d = s.recv() + print d diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/changelog b/debian_files/3.6.0/openarmor-hids-agent/debian/changelog new file mode 100644 index 000000000..bb4488b80 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/changelog @@ -0,0 +1,18 @@ +openarmor-hids-agent (3.6.0-1) unstable; urgency=medium + + * support arm64 package + + -- Santiago Bassett Wed, 08 Jan 2020 19:45:23 +0000 + +openarmor-hids-agent (2.8.2-2) unstable; urgency=low + + * Set openarmor user home to /var/openarmor/ + * Added linux-libc-dev build dependency to Debian control file + + -- Santiago Bassett Mon, 15 Jun 2015 08:43:10 +0000 + +openarmor-hids-agent (2.8.2-1) unstable; urgency=low + + * 2.8.2 Initial release. Includes several fixes, and patch for CVE-2015-3222 + + -- Santiago Bassett Mon, 15 Jun 2015 08:43:10 +0000 diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/compat b/debian_files/3.6.0/openarmor-hids-agent/debian/compat new file mode 100644 index 000000000..7f8f011eb --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/conffiles b/debian_files/3.6.0/openarmor-hids-agent/debian/conffiles new file mode 100644 index 000000000..17a44cc26 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/conffiles @@ -0,0 +1 @@ +/var/openarmor/etc/openarmor.conf diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/control b/debian_files/3.6.0/openarmor-hids-agent/debian/control new file mode 100644 index 000000000..387a07270 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/control @@ -0,0 +1,15 @@ +Source: openarmor-hids-agent +Section: admin +Priority: extra +Maintainer: Santiago Bassett +Build-Depends: debhelper (>= 7.0.50~), linux-libc-dev, libssl-dev, libevent-dev, libpcre2-dev, zlib1g-dev +Standards-Version: 3.8.4 +Homepage: http://www.theopenarmor.org + +Package: openarmor-hids-agent +Architecture: any +Depends: ${shlibs:Depends}, debconf, libc6 (>= 2.7) +Conflicts: openarmor-hids +Description: openarmor Agent - Host Based Intrusion Detection System + openarmor HIDS for log analysis, integrity checking, rootkits detection and + active response. This package includes the server and the agent. diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/copyright b/debian_files/3.6.0/openarmor-hids-agent/debian/copyright new file mode 100644 index 000000000..555c197dd --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/copyright @@ -0,0 +1,34 @@ +This work was packaged for Debian by: + + Santiago Bassett on Fri, 29 Nov 2013 03:11:44 +0000 + +It was downloaded from: + + http://www.theopenarmor.org + +Upstream Authors: + + dcid@dcid.me + Jia-BingJB_Cheng@trendmicro.com + vichargrave@gmail.com + openarmor@michaelstarks.com + ddpbsd@gmail.com + scott@atomicorp.com + brad.lhotsky@gmail.com + jeremy@jeremyrossi.com + santiago.bassett@gmail.com + +Copyright: + + GNU General Public License version 2. + +License: + + GNU General Public License version 2. + +The Debian packaging is: + + Copyright (C) 2014 Santiago Bassett + +and is licensed under the GPL version 2, +see "/usr/share/common-licenses/GPL-2". diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/openarmor-hids-agent.lintian-overrides b/debian_files/3.6.0/openarmor-hids-agent/debian/openarmor-hids-agent.lintian-overrides new file mode 100644 index 000000000..4c30cd52b --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/openarmor-hids-agent.lintian-overrides @@ -0,0 +1,9 @@ +openarmor-hids-agent: embedded-library +openarmor-hids-agent: embedded-zlib +openarmor-hids-agent: possible-gpl-code-linked-with-openssl +openarmor-hids-agent: new-package-should-close-itp-bug +openarmor-hids-agent: possibly-insecure-handling-of-tmp-files-in-maintainer-script +openarmor-hids-agent: non-standard-dir-in-var +openarmor-hids-agent: file-in-unusual-dir +openarmor-hids-agent: hardening-no-fortify-functions +openarmor-hids-agent: hardening-no-relro diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/patches/01_makefile.patch b/debian_files/3.6.0/openarmor-hids-agent/debian/patches/01_makefile.patch new file mode 100644 index 000000000..2d3bdf087 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/patches/01_makefile.patch @@ -0,0 +1,59 @@ +Index: openarmor-hids-agent-2.8.2/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ openarmor-hids-agent-2.8.2/Makefile 2015-06-15 03:15:51.083134760 +0000 +@@ -0,0 +1,54 @@ ++# ++# Santiago Bassett ++# 06/15/2015 ++# ++ ++DESTDIR=/ ++DIR=$(DESTDIR)/var/openarmor/ ++openarmor_INIT=$(DIR)/etc/openarmor-init.conf ++CEXTRA="-DCLIENT" ++all: ++ echo "CEXTRA=$(CEXTRA)" >> src/Config.OS ++ (cd src; make TARGET=agent PCRE2_SYSTEM=yes) ++ ++clean: ++ rm bin/* || /bin/true ++ chmod 750 $(DIR) || /bin/true ++ chmod 750 $(DIR)/* || /bin/true ++ (cd src; make clean) ++ rm -f src/Config.OS ++ rm -f src/analysisd/compiled_rules/compiled_rules.h ++ rm -f src/isbigendian.c ++ rm -f src/analysisd/openarmor-makelists ++ rm -f src/analysisd/openarmor-logtest ++ rm -f src/isbigendian ++ ++install: ++ mkdir -p $(DIR) ++ (cd $(DIR); mkdir -p logs bin queue queue/openarmor queue/alerts queue/syscheck queue/diff queue/rids) ++ (cd $(DIR); mkdir -p var var/run etc etc/init.d etc/shared active-response active-response/bin agentless .ssh) ++ cp -pr src/rootcheck/db/*.txt $(DIR)/etc/shared/ ++ chmod -x $(DIR)/etc/shared/*.txt ++ cp -pr etc/internal_options.conf $(DIR)/etc/ ++ chmod -x $(DIR)/etc/internal_options.conf ++ cp -pr etc/local_internal_options.conf $(DIR)/etc/ > /dev/null 2>&1 || /bin/true ++ cp -pr etc/client.keys $(DIR)/etc/ > /dev/null 2>&1 ||/bin/true ++ cp -pr src/agentlessd/scripts/* $(DIR)/agentless/ ++ cp -pr src/openarmor-agentd ${DIR}/bin/ ++ cp -pr src/agent-auth ${DIR}/bin/ ++ cp -pr src/openarmor-logcollector ${DIR}/bin/ ++ cp -pr src/openarmor-syscheckd ${DIR}/bin/ ++ cp -pr src/openarmor-execd ${DIR}/bin/ ++ cp -pr src/init/openarmor-client.sh ${DIR}/bin/openarmor-control ++ cp -pr src/manage_agents ${DIR}/bin/ ++ cp -pr contrib/util.sh ${DIR}/bin/ ++ sh src/init/fw-check.sh execute > /dev/null ++ cp -pr active-response/*.sh ${DIR}/active-response/bin/ ++ cp -pr active-response/firewalls/*.sh ${DIR}/active-response/bin/ ++ cp -pr etc/openarmor-agent.conf $(DIR)/etc/openarmor.conf ++ chmod -x $(DIR)/etc/openarmor.conf ++ cp -p src/init/openarmor-hids-debian.init $(DIR)/etc/init.d/openarmor ++ echo "DIRECTORY=\"/var/openarmor\"" > $(openarmor_INIT) ++ echo "VERSION=\"v3.6.0\"" >> $(openarmor_INIT) ++ echo "DATE=\"`date`\"" >> $(openarmor_INIT) ++ echo "TYPE=\"agent\"" >> $(openarmor_INIT) diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/patches/02_openarmor-agent.conf.patch b/debian_files/3.6.0/openarmor-hids-agent/debian/patches/02_openarmor-agent.conf.patch new file mode 100644 index 000000000..6b675ae23 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/patches/02_openarmor-agent.conf.patch @@ -0,0 +1,58 @@ +--- a/etc/openarmor-agent.conf.orig 2020-01-19 03:45:09.184090231 +0900 ++++ b/etc/openarmor-agent.conf 2020-01-19 03:44:15.844760722 +0900 +@@ -29,16 +29,12 @@ + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt ++ /var/openarmor/etc/shared/system_audit_rcl.txt + + + + syslog +- /var/log/messages +- +- +- +- syslog +- /var/log/authlog ++ /var/log/syslog + + + +@@ -48,26 +44,31 @@ + + + syslog +- /var/log/secure ++ /var/log/dpkg.log + + + + syslog +- /var/log/xferlog ++ /var/log/kern.log + + ++ ++ + diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/patches/series b/debian_files/3.6.0/openarmor-hids-agent/debian/patches/series new file mode 100644 index 000000000..1afdc0fd1 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/patches/series @@ -0,0 +1,2 @@ +02_openarmor-agent.conf.patch +01_makefile.patch diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/postinst b/debian_files/3.6.0/openarmor-hids-agent/debian/postinst new file mode 100644 index 000000000..ae1ddaa66 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/postinst @@ -0,0 +1,153 @@ +#!/bin/sh +# postinst script for openarmor-hids +# Santiago Bassett +# 03/25/2014 + +set -e + +case "$1" in + configure) + + DIR="/var/openarmor/" + USER="openarmor" + GROUP="openarmor" + openarmor_HIDS_TMP_DIR="/tmp/openarmor-hids" + + OSMYSHELL="/sbin/nologin" + if [ ! -f ${OSMYSHELL} ]; then + if [ -f "/bin/false" ]; then + OSMYSHELL="/bin/false" + fi + fi + + if ! getent group | grep -q "^openarmor" + then + addgroup --system openarmor + fi + if ! getent passwd | grep -q "^openarmor" + then + adduser --system --home ${DIR} --shell ${OSMYSHELL} --ingroup ${GROUP} ${USER} > /dev/null 2>&1 + fi + + # Default for all directories + chmod -R 550 ${DIR} + chown -R root:${GROUP} ${DIR} + + # To the openarmor queue (default for agentd to read) + chown -R ${USER}:${GROUP} ${DIR}/queue/openarmor + chmod -R 770 ${DIR}/queue/openarmor + + # For the logging user + chown -R ${USER}:${GROUP} ${DIR}/logs + chmod -R 750 ${DIR}/logs + chmod -R 775 ${DIR}/queue/rids + touch ${DIR}/logs/openarmor.log + chown ${USER}:${GROUP} ${DIR}/logs/openarmor.log + chmod 664 ${DIR}/logs/openarmor.log + + chown -R ${USER}:${GROUP} ${DIR}/queue/diff + chmod -R 750 ${DIR}/queue/diff + chmod 740 ${DIR}/queue/diff/* > /dev/null 2>&1 || true + + # For the etc dir + chmod 550 ${DIR}/etc + chown -R root:${GROUP} ${DIR}/etc + if [ -f /etc/localtime ]; then + cp -pL /etc/localtime ${DIR}/etc/; + chmod 555 ${DIR}/etc/localtime + chown root:${GROUP} ${DIR}/etc/localtime + fi + + if [ -f /etc/TIMEZONE ]; then + cp -p /etc/TIMEZONE ${DIR}/etc/; + chmod 555 ${DIR}/etc/TIMEZONE + fi + + # More files + chown root:${GROUP} ${DIR}/etc/internal_options.conf + chown root:${GROUP} ${DIR}/etc/local_internal_options.conf >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/etc/client.keys >/dev/null 2>&1 || true + chown root:${GROUP} ${DIR}/agentless/* + chown ${USER}:${GROUP} ${DIR}/.ssh + chown root:${GROUP} ${DIR}/etc/shared/* + + chmod 550 ${DIR}/etc + chmod 440 ${DIR}/etc/internal_options.conf + chmod 660 ${DIR}/etc/local_internal_options.conf >/dev/null 2>&1 || true + chmod 440 ${DIR}/etc/client.keys >/dev/null 2>&1 || true + chmod 550 ${DIR}/agentless/* + chmod 700 ${DIR}/.ssh + chmod 770 ${DIR}/etc/shared + chmod 660 ${DIR}/etc/shared/* + + # For the /var/run + chmod 770 ${DIR}/var/run + chown root:${GROUP} ${DIR}/var/run + + # For util.sh + chown root:${GROUP} ${DIR}/bin/util.sh + chmod +x ${DIR}/bin/util.sh + + # For binaries and active response + chmod 755 ${DIR}/active-response/bin/* + chown root:${GROUP} ${DIR}/active-response/bin/* + chown root:${GROUP} ${DIR}/bin/* + chmod 550 ${DIR}/bin/* + + # For openarmor.conf + chown root:${GROUP} ${DIR}/etc/openarmor.conf + chmod 660 ${DIR}/etc/openarmor.conf + + # Debconf + . /usr/share/debconf/confmodule + db_input high openarmor-hids-agent/server-ip || true + db_go + + db_get openarmor-hids-agent/server-ip + SERVER_IP=$RET + + sed -i "s/[^<]\+<\/server-ip>/${SERVER_IP}<\/server-ip>/" ${DIR}/etc/openarmor.conf + db_stop + + # openarmor-init.conf + if [ -e ${DIR}/etc/openarmor-init.conf ] && [ -d /etc/ ]; then + if [ -e /etc/openarmor-init.conf ]; then + rm -f /etc/openarmor-init.conf + fi + ln -s ${DIR}/etc/openarmor-init.conf /etc/openarmor-init.conf + fi + + # init.d/openarmor file + if [ -x ${DIR}/etc/init.d/openarmor ] && [ -d /etc/init.d/ ]; then + if [ -e /etc/init.d/openarmor ]; then + rm -f /etc/init.d/openarmor + fi + ln -s ${DIR}/etc/init.d/openarmor /etc/init.d/openarmor + fi + + # Service + if [ -x /etc/init.d/openarmor ]; then + update-rc.d -f openarmor defaults + fi + + # Delete tmp directory + if [ -d ${openarmor_HIDS_TMP_DIR} ]; then + rm -r ${openarmor_HIDS_TMP_DIR} + fi + + ;; + + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + + *) + echo "postinst called with unknown argument \`$1'" >22 + exit 1 + ;; + +esac + +exit 0 diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/postrm b/debian_files/3.6.0/openarmor-hids-agent/debian/postrm new file mode 100644 index 000000000..1a96bb2f8 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/postrm @@ -0,0 +1,33 @@ +#!/bin/sh +# postrm script for openarmor-hids +# Santiago Bassett +# 03/25/2014 + + +set -e + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + if getent passwd | grep -q "^openarmor" + then + deluser openarmor + fi + if getent group | grep -q "^openarmor" + then + delgroup openarmor + fi + rm -f /etc/init.d/openarmor + rm -f /etc/openarmor-init.conf + update-rc.d -f openarmor remove + + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + + ;; + +esac + +exit 0 diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/preinst b/debian_files/3.6.0/openarmor-hids-agent/debian/preinst new file mode 100644 index 000000000..03539abad --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/preinst @@ -0,0 +1,36 @@ +#!/bin/sh +# preinst script for openarmor-hids +# Santiago Bassett +# 03/25/2014 + +set -e + +# configuration variables +openarmor_HIDS_TMP_DIR="/tmp/openarmor-hids" + +# environment configuration +if [ ! -d ${openarmor_HIDS_TMP_DIR} ]; then + mkdir ${openarmor_HIDS_TMP_DIR} +fi + +case "$1" in + install|upgrade) + # back up the current user rules + if [ -f /var/openarmor/rules/local_rules.xml ]; then + cp /var/openarmor/rules/local_rules.xml ${openarmor_HIDS_TMP_DIR}/local_rules.xml + fi + ;; + + abort-upgrade) + + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + + ;; + +esac + +exit 0 diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/rules b/debian_files/3.6.0/openarmor-hids-agent/debian/rules new file mode 100644 index 000000000..7e26af8bf --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/rules @@ -0,0 +1,29 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. +# +# Modified to make a template file for a multi-binary package with separated +# build-arch and build-indep targets by Bill Allombert 2001 + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This has to be exported to make some magic below work. +export DH_OPTIONS + + +%: + dh $@ + +override_dh_auto_configure: + +override_dh_auto_build: + $(MAKE) all + +override_dh_auto_clean: + $(MAKE) clean diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/source/format b/debian_files/3.6.0/openarmor-hids-agent/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian_files/3.6.0/openarmor-hids-agent/debian/templates b/debian_files/3.6.0/openarmor-hids-agent/debian/templates new file mode 100644 index 000000000..d07270511 --- /dev/null +++ b/debian_files/3.6.0/openarmor-hids-agent/debian/templates @@ -0,0 +1,4 @@ +Template: openarmor-hids-agent/server-ip +Type: string +Default: 127.0.0.1 +Description: openarmor server IP address for this agent. This server is also known as Manager and will receive information from the agent. You need to specify the IP address, the hostname is not valid. The agent still needs to be registered and started manually. diff --git a/doc/README.config b/doc/README.config new file mode 100644 index 000000000..12185f574 --- /dev/null +++ b/doc/README.config @@ -0,0 +1,3 @@ +Configuration options: + +https://www.theopenarmor.org/docs/ diff --git a/doc/active-response-internal.txt b/doc/active-response-internal.txt new file mode 100644 index 000000000..1e8661d21 --- /dev/null +++ b/doc/active-response-internal.txt @@ -0,0 +1,29 @@ +openarmor HIDS 0.6 +Copyright (c) 2004-2006 Daniel B. Cid + + + +How the active response works internally: + +- Read active-response.txt for details on configuration + + +1 - The analysis server receives an event that matches the + active response policy. + +2 - The analysis server verifies that all required fields + are provided with the event. It means that the analysis + server was able to decode the event and extract the + necessary information. One example is if it was able + to extract the IP address from the event to send to + the firewall to be blocked. + +3 - If the active response policy specify that the action + must be executed locally on the AS, a message is sent + to the execd directly. + +4 - If the active response policy specify that the action + must be executed remotely, a message is sent to the + "Active response forwarder" (remoted) to forward the + event to the specified agent. + diff --git a/doc/active-response.txt b/doc/active-response.txt new file mode 100644 index 000000000..ec0aa48d9 --- /dev/null +++ b/doc/active-response.txt @@ -0,0 +1,6 @@ +openarmor HIDS v0.7 +Copyright (c) 2004-2006 Daniel B. Cid + + + +http://www.theopenarmor.org/docs/docs/manual/ar/index.html diff --git a/doc/br/INSTALL.br b/doc/br/INSTALL.br new file mode 100644 index 000000000..0d73f0b7b --- /dev/null +++ b/doc/br/INSTALL.br @@ -0,0 +1,65 @@ +openarmor HIDS 0.7 +Copyright (c) 2004-2006 Daniel B. Cid + + + +** Traduzido por Willian Itiho Amano + + += Informa��es dobropenarmorSSEC HIDS = + +Visite http://www.theopenarmor.org + + += Instala��o recomendada = + +A instala��oopenarmorSSEC HIDS � muito simples. Voc� pode executa-la pela +maneira r�pida (usando o script 'install.sh' com os valores padroes) +ou customizada (mudando na m�o os valores do script install.sh). +Eu REALMENTE recomento SEMPRE o uso da maneira r�pida. + +**Apenas desenvolvedores ou pessoas experientes devem usar outro m�todo. + +Passos do processo r�pido: + +1- Rode o script ./install.sh. Ele ir� guia-lo pelo processo de instala��o. + +2- O script criar� tudo em /vaopenarmorec e tentar� criar um script de + inicializa��o em seu sistema (/etc/rc.local ou /etc/rc.d/iniopenarmorssec). + Se o script de inicializa��o n�o for criado, siga as instru��es do + para iniciar o openarmor HIDS durante o boot. Para iniciar na m�o, digite + /var/openarmor/bin/openarmor-control start + +3- Se voc� for rodar em v�rios clientes, Instale o servidor primeiro. + Use o manage_agents para criar as chaves de encripta��o. + +4- Aproveite. + + += Instala��o e execu��o (99,99% da vezes, leia acima) = + + +Passos para instala��o na m�o: + +1- Crie os diret�rios necess�rios (por default /openarmorssec). +2- Mova os arquivos necess�rios para o diret�openarmorssec. +3- Compile tudo. +4- Mova os bin�rios para o diret�rio default. +5- Crie os usu�rios necess�rios. +6- Sete todas as permi��es dos arquivos. + + +As 5 etapas do Makefile (veja como criar o servidor). + +O Makefile l� as op��es do arquivo LOCATION. Mude +o que necessitar de l�. + +Para compilar tudo use: + + % make clean + % make all (step 3) + % su + # make server (will do steps 1,2,4 and 6 above) + +*Antes de rodas make server, make sure Dever� ter os usu�rios criados. +O Makefile n�o far� isso. diff --git a/doc/br/README.config b/doc/br/README.config new file mode 100644 index 000000000..4a08ff5fe --- /dev/null +++ b/doc/br/README.config @@ -0,0 +1,3 @@ +Op��es de configura��o: + +http://www.theopenarmor.org/docs/ diff --git a/doc/br/TRANSLATION b/doc/br/TRANSLATION new file mode 100644 index 000000000..e682ee5de --- /dev/null +++ b/doc/br/TRANSLATION @@ -0,0 +1,2 @@ +** Traduzido por Willian Itiho Amano +** Translated by Willian Itiho Amano diff --git a/doc/br/active-response-internal.txt b/doc/br/active-response-internal.txt new file mode 100644 index 000000000..3677dd236 --- /dev/null +++ b/doc/br/active-response-internal.txt @@ -0,0 +1,28 @@ +openarmor HIDS 0.6 +Copyright (c) 2004-2006 Daniel B. Cid + + + +Como a resposta ativa trabalha internamente: + +- Leia o arquivo active-respose-doc.txt para maiores detalhes + de configura��o + + +1 - O servidor de an�lize recebe um evento que acione a + pol�tica de resposta ativa. + +2 - O servidor de an�lize verifica todos os campos requeridos + fornecidos pelo evento. Isto significa que o servidor + de an�lise decodificar� o evento e ir� extrair as informa��es + necess�rias. Um exemplo disto � que pode-se extrair o n�mero + de IP de um evento e envi�lo para o firewall bloquear. + +3 - Se a pol�tica de resposta ativa especificar esta a��o, e esta + dever ser executada localmente no AS, uma mensagem deve ser + enviada diretamente. + +4 - Se a pol�tica de resposta ativa especificar uma a��o, + e esta deve ser executada remotamente, uma mensagem � enviada para + o servidor (remoted) para enviar o evento ao cliente especificado. + diff --git a/doc/br/active-response.txt b/doc/br/active-response.txt new file mode 100644 index 000000000..ec0aa48d9 --- /dev/null +++ b/doc/br/active-response.txt @@ -0,0 +1,6 @@ +openarmor HIDS v0.7 +Copyright (c) 2004-2006 Daniel B. Cid + + + +http://www.theopenarmor.org/docs/docs/manual/ar/index.html diff --git a/doc/br/logs.txt b/doc/br/logs.txt new file mode 100644 index 000000000..6c096824f --- /dev/null +++ b/doc/br/logs.txt @@ -0,0 +1,51 @@ +openarmor HIDS 0.5 +Copyright (c) 2004,2005 Daniel B. Cid + + + + +openarmor Hids Logging + +== Introdu��o == + +O sistema suporta dois tipos de logs. Logs de alertas e eventos +ou arquivos de logs. + +Todas as mensagens recebidas s�o tratadas como um envento. Todas as +mensagens de log, avisos de integridade, informa��es de sistema s�o +tratadas como tal. Fazer log de � muito pesado para o sistema pois +o sistema tem de arquivar cada evendo. Entretanto, � muito bom para +se ter uma vis�o geral de tentativas de ataque. + +Criar logs de alertas � muito importante. Pode ser gerado quando um evento +vai de encontro com uma regra de detec��o. AdicionalmentopenarmorSSEC hids +suporta envio de em-ails e execu��o de comandos esternos como m�todo de alerta. + +== Criando logs de eventos == + +O diret�rio de logs dopenarmorEC (by default /vaopenarmorec/logs) +poss�i entrada para arquivos (/vaopenarmorec/logs/archives). Dentro deste diret�rio, +todos os enventos s�o classificados por data. +Por exemplo, todos os eventos recebidos em 22 de maio de 2004, ser�o guardados em: + +/var/openarmor/logs/archives/2004/May/events-22.log + +Ap�s cada dia, uma combina��o ser� criada para cada dia espec�fico. + +/var/openarmor/logs/archives/2004/May/events-22.log.md5 + +Este ser� uma combina��o do arquivo do dia 22 com o do dia 21. + +A combina��o do dia 1, ser� feita com o dia 31(ou 30 ou 28) do mes anterior. + +Isto assegurar� que o log n�o seja modificado. Para que isto aconte�a, +todos os logs (desde o primeiro dia) dever�o ser modificados. + + +== Criando logs de alerta == + +Haver� um diret�rio de alerta dentro do diret�rio defauopenarmor OSSEC. +Este ser� organizado da mesma forma que os logs de envetos. Por facor leia +a explica��o acima. + + diff --git a/doc/br/manager.txt b/doc/br/manager.txt new file mode 100644 index 000000000..dc783400d --- /dev/null +++ b/doc/br/manager.txt @@ -0,0 +1,20 @@ +openarmor HIDS 0.5 +Copyright (c) 2004,2005 Daniel B. Cid + + + + +Como usar o gerenciamento de clientes do servidor. + +-A m�quina cliente deve abrir a porta 1514 (por default) para enviar� + mensagens para o server. Somente o IP do servidor ser� liberado. + +-A cada 10 minutos, o cliente envia uma notifica��o com o status para + o servidor. Esta mensagem de status contem informa��es sobre o + sistema do cliente e sobre os arquivos do diret�rio compartilhado. + +-O servidor recebe a mensagem de status, atualiza o arquivo de status + do cliente e checa se h� algum arquivo para ser enviado para o cliente. + Se ouver, este conectar� com o cliente e enviar� o arquivo. + +-Todas as mensagens s�o criptografadas. \ No newline at end of file diff --git a/doc/br/rootcheck.txt b/doc/br/rootcheck.txt new file mode 100644 index 000000000..f94601b40 --- /dev/null +++ b/doc/br/rootcheck.txt @@ -0,0 +1,64 @@ +T�cnicas de detec��o de Rootkit usadasopenarmor OSSEC HIDS +por Daniel B. Cid, daniel.cid@gmail.com + + +Comen�ando na vers�o 0.4openarmorSSEC HIDS executar� a detec��o +de rootkit em todos os sistemas que o cliente estiver instalado. +O rootcheck (Sistema de detec��o de rootkit) ser� executado +a cada X minutos (Especificado pelo usu�rio --por default +a cada 2 horas) para detectar possiveis rootkits instalados. +Em conjunto com a an�lize de logs e o sistema de checagem de integridade, +ele torna-se uma solu��o poderosa de monitoramentoopenarmorSSEC HIDS executa +a an�lize de logs e verifica��o de integridade desde a vers�o 0.1). + +Outra caracter�stica inclu�da na vers�o 0.4 � que o servidor de an�lize +enviar� automaticamente as assinaturas de detec��o de rootkit aos +clientes, reduzindo o trabalho com administra��o para o administrador +de sistemas. Os clientes e servidor manter�o contato a cada 10 minutos +e se o servidor for atualizado com um novo arquivo de assinatura, ele enviar� +para todos os clientes configurados. De uma olhada na documenta��o para maiores +informa��es. + +O rootcheck executar� as seguintes etapas para verificar a presen�a de +rootkits: + + +1- Ler� o arquivo rootkit_files.txt que contem um grande banco de dados + de rootkits e arquivos usados pelo mesmo. Tentar� usar as fun��es + fopen e opendir no arquivo especificado. N�s usamos todas a chamadas do + sistema,por causa de que rootkits que rodam a nivel de kernel, escondem as + chamadas dos sistema. N�s tentamos melhoras as coutras chamadas do sistema, + para uma melhor detec��o. Este m�todo � mais parecido com uma regra de + ant�-virus, que necessita ser atualizado contantemente. As chances de + falso-positivos s�o pequenas, mas falso-negativos podem ser produzidos + modificando os rootkits. + +2- Ler� o arquivo rootkit_trojans.txt que contem um banco de dados de + assinaturas de arquivos infectados por rootkits. Esta t�cnica verifica + bin�rios modificados por trojans conhecidos. Este m�todo de detec��o + n�o encontra nenhum rootkit a nivel de kernel ou nenhum rootkit desconhecido. + +3- Escaneia o diret�rio /dev procurando por anomalias. O /dev cont�m todos os + arquivos de device e scripts de Makedev. V�rios rootkits usam arquivos + escondidoso no /dev. Esta t�cnica pode detectar rootkits desconhecidos. + +4- Escaneia o sistema de arquivos a procura por arquivos incomuns e problema de + permi��o. Arquivos setados para root, com permi��o de escrita para outros + s�o muito perigosos e a detec��o de rootkit olha isso. Arquivos com Suid, + diret�rios e arquivos escondidos s�o inspecionados. + +5- Procura pela presen�a de processos ocultos. N�s usamos as fun��es getsid e + kill para checar se algum PID est� sendo usado ou n�o. Se estiver, mas a fun��o + n�o pode ve-lo, � uma indica��o de rootkit a nivel de kernel ou o ps foi + infectado. N�s verificamos tamb�m a sa�da do kill e do getid que deve ser a mesma. + +6- Olha a presen�a de portas escondidas. N�s usamos a fun��o bind para checar todas + as portas TCP e UDP to do sistema. Se n�o podemos usar o bind na porta (ele est� + sendo usado), mas o netsatat n�o mostra, provavelmente h� um rootkit instalado. + +7- Escaneia todas a interfaces do sistema e procura por alguma com m�do "promisc" + abilitado. Se a interface est� neste modo, a sa�da do ifconfig mostrar�. Se n�o, + h� a possibilidade de haver um rootkit instalado. + + +EOF diff --git a/doc/br/rule_ids.txt b/doc/br/rule_ids.txt new file mode 100644 index 000000000..bb7544863 --- /dev/null +++ b/doc/br/rule_ids.txt @@ -0,0 +1,29 @@ +0100 - 0199 Mensagens de erro do Syslog +0200 - 0299 Mensagens NFS +0300 - 0399 Mensagens do Xinetd +0400 - 0499 Mensagens do controle de acesso +0500 - 0599 Mensagens do Sendmail +0600 - 0699 Mensagens do Ftp +0700 - 0799 Mensagens do Smartd +0800 - 0899 Mensagens do Kernel +0900 - 0949 Mensagens do Crond +0950 - 0999 Mensagens automticas +1000 - 1099 Mensagens do Syslog a respeito do Squid +1100 - 1199 Mensagens do su +1200 - 1299 Mensagens do tripwire +1300 - 1399 Mensagens do adduser +1400 - 1499 Mensagens do sudo +1500 - 1599 Mensagens do sshd +1600 - 1699 Testes padres de ataques +1700 - 1799 Testes padres da escala de privilgios +1800 - 1899 Testes padres de scaners +1900 - 1999 Regras de DNS +2000 - 2499 Regras de PIX +2500 - 2599 Regras do proftpd +2600 - 2699 Mensagens do PPTP +2700 - 2799 Regras do FTS +2800 - 2899 Regras do Pure-FTPD +3000 - 3099 Regras do log de erro do Apache +3100 - 3199 Regras do log de acesso do Apache +4000 - 4999 Regras de IDS +5000 - 5999 Regras do Squid diff --git a/doc/br/rules.txt b/doc/br/rules.txt new file mode 100644 index 000000000..316cbfb2f --- /dev/null +++ b/doc/br/rules.txt @@ -0,0 +1,66 @@ +openarmor HIDS v0.7 +Copyright (c) 2004-2006 Daniel B. Cid + + + + +--- Classidica��o das regras --- + + +-- Classifica��o -- + +As regras s�o classificadas em v�rios niveis, indo do menos (00) para o maior (16). +Alguns n�veis n�o est�o sendo usados. Voc� pode adicionar mais entre ou ap�s estes. + +**As regras ser�o lidas partindo do menor nivel para o maior. ** + +00 - Ignorado - N�o h� nehum a��o. Usado para evitar falso positivos. Estas regras + s�o escaneadas antes das demias e incluem eventos sem relev�ncia de seguran�a. +01 - Nenhuma - +02 - Notifica��o do sistema com baixa prioridade - Notifica��es do sistema ou mensagens + de status. Estas regras n�o posseum relev�ncia de seguran�a. +03 - Eventos de sucesso/Autorizado - Estes incluem tentativas de logins com sucesso, + eventos permitidos pelo, etc. +04 - Erros de sistema com baixa prioridade - Erros relatados por m� configura��o ou + devices/aplica��es n�o usadas. Estas n�o apresentam relev�ncia de seguran�a e + normalmente s�o causadas por instala��es padr�es ou software em testes. +05 - Erros gerados pelo usu�rio - Este incluem senhas erradas, a��es n�o permitidas, + etc, mas n�o tem relev�ncia de seguran�a. +06 - Ataque de baixa relev�ncia - Estas indicam que um worm ou v�rus que n�o afetam + o sistema (como o code red para servidores apache, etc). Incluem tamb�m eventos + de IDS ou erros frequentes. +07 - Combina��o de "Bad word". Estas incluem palavras como "bad", "error", etc. Estes + eventos normalmente n�o s�o classificados e possuem alguma relev�ncia de seguran�a. +08 - Visto pela primeira vez - Incluem eventos vistos pela primeira vez, primeira vez + de ventos de IDS ou primeira vez que um usu�rio loga. Se voc� estiver come�ando a + usar o openarmor HIDS, estas mensagens ser�o frequ�ntes mas depois devem diminuir. + Estas incluem tamb�m a��es de seguran�a relevantes (como iniciar um sniffer ou + algo do g�nero). +09 - Erro de fonte inv�lida - Inclue tentativas de login com um usu�rio desconhecido + ou de uma fonte inv�lida. Pode haver relev�ncia de seguran�a (princilmente se ocorrer + repetidamente). Incluem tamb�m erros a respeito do usu�rio "root". +10 - Erros gerador por v�rios usu�rios - Estas incluem v�rios bad passwords, + v�rios logins falhos, etc. Podem indicar um ataque ou um usu�rio que esqueceu + suas credenciais. +11 - Advert�ncia de checagem de integridade -Estas incluem mensagens a respeito da + modifica��o de bin�rios ou a presen�a de rootkits (pelo rootcheck). Se voc� + houver modificado apenas a configura��o do seu sistema, deve ficar atento as mensagens + do "syscheck". Pode indicar um ataque com sucesso. +12 - Evento de alta import�ncia - Estas incluem erros ou avisos vindos do sistema, kernel, + etc. Podem indicar um ataque a uma aplica��o espec�fica. +13 - Erros incomuns (alta import�ncia) - A maioria das vezes mostra um ataque padr�o. +14 - Evendo de seguran�a de alta import�ncia - Na maioria das vezes s�o eventos de + corela��o e indicam um ataque. +15 - Ataque severo - N�o h� chanses de falso positivo. � necess�ria aten��o imediata. + + +== Grupos de regras == + +-N�s podemos especificar grupos para regras espec�ficas. Isto � usado para +raz�es de resposta ativa ou para corela��o. + + +== Configura��o das regras == + +http://www.theopenarmor.org/docs/docs/manual/rules-decoders/index.html + diff --git a/doc/images/fim-test.gif b/doc/images/fim-test.gif new file mode 100644 index 000000000..e3dc5e800 Binary files /dev/null and b/doc/images/fim-test.gif differ diff --git a/doc/images/ssh-attack.gif b/doc/images/ssh-attack.gif new file mode 100644 index 000000000..b820cebd2 Binary files /dev/null and b/doc/images/ssh-attack.gif differ diff --git a/doc/logs.txt b/doc/logs.txt new file mode 100644 index 000000000..2ec8458f7 --- /dev/null +++ b/doc/logs.txt @@ -0,0 +1,53 @@ +openarmor v0.9 +Copyright (C) 2009 Trend Micro Inc. + + +openarmor Logging + +== Introduction == + +openarmor supports three types of logs. Alert logging, firewall +logging and event (archiving) logging. + +Every message received is treated as an event. +Any log message, integrity report, system information will be treated +as such. Event logging is very expensive for the system because +it will archive every event. However, they can be usefull to get +the big picture if some attack happens. + +Alert logging is the most useful one. An alert is generated when +an event is matched against one of the detection rules. In addition +to the logging, openarmor can also generate e-mail notifications or +execute external commands for them. + + +== Event logging == + +Inside the openarmor default log directory (by default /var/openarmor/logs) +there is an entry for "archives" (/var/openarmor/logs/archives). Inside this +directory, all events will be stored by date. +For example, all events received on May 22 of 2004, will be stored on: + +/var/openarmor/logs/archives/2004/May/events-22.log + +After each day, a hash will be created for this specific day at + +/var/openarmor/logs/archives/2004/May/events-22.log.md5 + +This hash will be the hash of the file from the day 22 plus the hash +from the day 21. + +The hash from the day 1, will be the hash from the day 31 (or 30 or 28) +from the previous month. + +This will ensure that no log will be modified. Also, for this to happen, +all the logs (since the first day) will need to be modified. + + +== Alert logging == + +There will be a "alerts" directory on the openarmor default logging directory. +It will be organized on the same way the event logging is. Please read +above to understand it. + + diff --git a/doc/manage_agents.txt b/doc/manage_agents.txt new file mode 100644 index 000000000..088aefc49 --- /dev/null +++ b/doc/manage_agents.txt @@ -0,0 +1,31 @@ + +== How to add an agent without any keyboard input == + +By default, to add an agent from server side, you must provide your agent +information to `manage_agents` program, by using its interactive mode. +This is really tedious if you have many servers / agents to add. Luckily, +you can use following environment variables as responses + + | variable name | value | description | + +------------------------+---------+----------------------+ + | openarmor_ACTION | A/a | add an agent | + | openarmor_AGENT_NAME | string | name of agent | + | openarmor_AGENT_IP | CIDR | ip address of agent | + | openarmor_AGENT_ID | integer | max length = 8 | + | openarmor_AGENT_KEY | string | base64 format | (*) + | openarmor_ACTION_CONFIRMED | y/Y/n/N | y -> confirmed | + + (*) openarmor_AGENT_KEY is used only on agent (when key is being imported) + +Please note that it's your duty to ensure that name, ip,... of agent are +valid. Otherwise, the program will fall back to interactive mode. In most +case, you should ensure that you new agent has an unique name/id. You can +simply know that by using `manage_agents -l` to list all known agents. + +For more details, please refer to openarmor document + https://www.theopenarmor.org/docs/manual/agent/agent-management.html + +== Notes == + +You can also use some tools (`expect`) to send strings to `manage_agents`, +instead of using the above environment variables. diff --git a/doc/manager.txt b/doc/manager.txt new file mode 100644 index 000000000..722d54839 --- /dev/null +++ b/doc/manager.txt @@ -0,0 +1,21 @@ +openarmor v0.9 +Copyright (C) 2009 Trend Micro Inc. + + +How do the server manager the agents. + +-The server will open port 1514 (by default) and listen for + messages from the clients. Only the IP of the clients will be + allowed. + +-Every 10 minutes, the client will send an status notification + to the server. This status message contain some information + about the agent system and information about the files it + has on the shared directory. + +-The server will receive the status message, update the agent + status file and check if it has any file to be sent to the + agent. If it has, it will connect to the agent and send + the file. + +-Every message will be encrypted. diff --git a/doc/nmap.txt b/doc/nmap.txt new file mode 100644 index 000000000..14e725dce --- /dev/null +++ b/doc/nmap.txt @@ -0,0 +1,59 @@ +openarmor +Copyright (C) 2009 Trend Micro Inc. + + +** Nmap correlation ** + +openarmor can read nmap grepable output files to use as a +correlation tool and also to alert based on host information +changes. Follow the step by step below on how to configure +openarmor: + + +1- Add the nmap output file on openarmor.conf (generally + at /var/openarmor/etc/openarmor.conf): + + + + nmapg + /var/log/nmap-out.log + + + + +2- If the file does not exist, touch it: + +openarmor-test# touch /var/log/nmap-out.log + + +3- Restart openarmor: + +openarmor-test# /var/openarmor/bin/openarmor-control restart + + +4- Run your nmap scans (example scanning 192.168.2.0/24 network): + +openarmor-test# nmap --append_output -sU -sT -oG /var/log/nmap-out.log 192.168.2.0-255 + + + +*** Example of alert when a new host is found: + +** Alert 1152058913.238: mail +2006 Jul 04 20:21:53 /var/log/nmap-out.log +Rule: 15 (level 8) -> 'New host information added.' +Src IP: (none) +User: (none) +Host: 192.168.2.10, open ports: 21(tcp) 22(tcp) 80(tcp) 113(tcp) 514(udp) 1514(udp) 4500(udp) + + +*** Example of alert when a new a host information is changed: + +** Alert 1152058983.487: mail +2006 Jul 04 20:23:03 /var/log/nmap-out.log +Rule: 15 (level 8) -> 'Host information changed.' +Src IP: (none) +User: (none) +Host: 192.168.2.1, open ports: 54(udp) 8080(tcp) 161(udp) 520(udp) 1025(udp) 1900(udp) +Previously open ports: 53(udp) 80(tcp) 161(udp) 520(udp) 1025(udp) 1900(udp) + diff --git a/doc/pl/INSTALL.pl b/doc/pl/INSTALL.pl new file mode 100644 index 000000000..2cb5eec3d --- /dev/null +++ b/doc/pl/INSTALL.pl @@ -0,0 +1,66 @@ +openarmor HIDS 0.8 +Copyright (c) 2004-2006 Daniel B. Cid + + + += Informacje o openarmor HIDS = + +Zobacz http://www.theopenarmor.org + + += Zalecana instalacja = + +Instalacja openarmor HIDS jest bardzo prosta. Może być przeprowadzona +w szybki sposób (przy użyciu skryptu install.sh z domyślnymi +wartościami) lub dostosowana do użytkownika (ręcznie lub poprzez +zmianę domyślnych wartości w skrypcie install.sh). POLECAM KAŻDEMU +używanie SZYBKIEGO SPOSOBU! Tylko developerzy i zaawansowani +użytkownicy powinni używać innych metod. + +Kroki szybkiego sposobu: + +1- Uruchom skrypt ./install.sh. Poprowadzi Cie on przez proces + instalacji. + +2- Skrypt zainstaluje wszystko do katalogu /var/openarmor oraz + spróbuje stworzyć w systemie skrypt inicjujący (w katalogu + /etc/rc.local lub /etc/rc.d/init.d/openarmor). Jeśli skrypt nie + zostanie utworzony, można postępując zgodnie z instrukcjami + z install.sh spowodować uruchamianie openarmor HIDS podczas + startu systemu. Aby wystartować ręcznie wystarczy uruchomić + /var/openarmor/bin/openarmor-control start + +3- Jeśli zamierzasz używać kilku klientów, powinieneś najpierw + zainstalowac serwer. Do stworzenia odpowiednich kluczy użyj + narzędzia manage_agents. + +4- Miłego użytkowania. + + += Instalacja i uruchmienie (99,99% powinieneś przeczytać POWYŻEJ) = + + +Kroki ręcznej instalacji: + +1- Utwórz potrzebne katalogi (domyślnie /var/openarmor). +2- Przenieś odpowiednie pliki do katalogu openarmor. +3- Skompiluj wszystko. +4- Przenieś binaria do katalodu domyślnego. +5- Dodaj odpowiednich użytkowników. +6- Ustaw odpowiednie prawa dla plików. + + +Powyższe 5 (bez 5) kroków jest wykonywane w Makefile (zobasz make server). + +Makefile czyta opcje z pliku LOCATION. Możesz w nim zmienić +wszystko co potrzebujesz. + +Aby skompilować wszystko samemu: + + % make clean + % make all (step 3) + % su + # make server (odpowiada za kroki 1,2,4 oraz 6) + +*Przed uruchomieniem make server, upewnij się, że masz utworzonych +odpowiednich użytkowników. Makefile nie utworzy ich. diff --git a/doc/pl/README.config b/doc/pl/README.config new file mode 100644 index 000000000..89830e547 --- /dev/null +++ b/doc/pl/README.config @@ -0,0 +1,3 @@ +Opcje konfiguracyjne: + +http://www.theopenarmor.org/docs/ diff --git a/doc/pl/TRANSLATION b/doc/pl/TRANSLATION new file mode 100644 index 000000000..ebc7de6cf --- /dev/null +++ b/doc/pl/TRANSLATION @@ -0,0 +1,2 @@ +** Tłumaczenie Krzysztof Dziankowski +** Translated by Krzysztof Dziankowski diff --git a/doc/pl/active-response-internal.txt b/doc/pl/active-response-internal.txt new file mode 100644 index 000000000..beb8f383e --- /dev/null +++ b/doc/pl/active-response-internal.txt @@ -0,0 +1,27 @@ +openarmor HIDS 0.6 +Copyright (c) 2004-2006 Daniel B. Cid + + + +Jak działa aktywa ochrona (od środka): + +- Przeczytaj active-respose-doc.txt aby dowiedzieć się więcej + o konfiguracji + +1 - Zdarzenie które pasuje do polityki aktywnej ochrony jest + wysyłane do serwera analizującego. + +2 - Serwer weryfikuje czy wszystkie wymagane pola są są + dostarczone w zdarzeniu. Oznacza to, że serwer zdekodował + zdarzenie i odczytał wszystkie pożądane informacje. Np. + musi odczytac adres IP aby podjąć akcję o zablokwaniu go + na firewall-u. + +3 - Jeśli aktywna ochrona jest skonfigurowana aby akcje były + wykonywane lokalnie, widomość zostaje bezpośrednio wysyłana + do execd. + +4 - Jeśli aktywna ochrona jest skonfigurowana aby akcje były + wykonywane zdalnie, wiadomość jest wysyłana do remoted + (forwarder aktywnej ochrony), który przekazuje ją dalej + do odpowiedniego agenta. \ No newline at end of file diff --git a/doc/pl/active-response.txt b/doc/pl/active-response.txt new file mode 100644 index 000000000..ec0aa48d9 --- /dev/null +++ b/doc/pl/active-response.txt @@ -0,0 +1,6 @@ +openarmor HIDS v0.7 +Copyright (c) 2004-2006 Daniel B. Cid + + + +http://www.theopenarmor.org/docs/docs/manual/ar/index.html diff --git a/doc/pl/logs.txt b/doc/pl/logs.txt new file mode 100644 index 000000000..e313db682 --- /dev/null +++ b/doc/pl/logs.txt @@ -0,0 +1,52 @@ +openarmor HIDS 0.5 +Copyright (c) 2004,2005 Daniel B. Cid + + + +Logi openarmor Hids + + +== Wprowadzenie == + +System wspiera dwa typy logowania. Logowanie alarmów i zdarzeń lub +logowanie z archiwizacją. + +Każda otrzymana wiadomość jest traktowana jako zdarzenie. +Raporty integralności systemu, informacje systemowe lub zwykłe +wiadomości logów są traktowane jako zdarzenia. Logowanie zdarzeń bardzo +obciąża system, ponieważ archiwizuje każde zdarzenie. Mimo to, jest +przydatne, ponieważ może dać nam dokładny obraz wydarzeń po włamaniu. + +Logowanie alarmów jest najbardziej użyteczne. Alarm jest generowany +kiedy zdarzenie zostaje dopasowane do jednej z reguł wykrywania. Poza +logowaniem openarmor hids posiada powiadomnienie poprzez e-mail oraz +zewnętrzne wykonywanie komend jako metodę alarmu. + + +== Logowanie zdarzeń == + +W domyślnym katalogu logów openarmor (/var/openarmor/logs) jeden jest +przezaczony na archiwa (/var/openarmor/logs/archives). W tym +katalogu wszystkie zdarzenia są przechowywane według daty. +Np. wszystkie zdarzenia otrzymane 22.05.2005, będą przechowywane w: + +/var/openarmor/logs/archives/2004/May/events-22.log + +Na koniec każdego dnia, jest tworzony hash i przechowywany w: + +/var/openarmor/logs/archives/2004/May/events-22.log.md5 + +Jest to hash z pliku z dnia 22 plus hash z dnia 21. + +Hash z dnia pierwszego, jest hashem z dnia 31 (30 lub 28) poprzedniego +miesiąca. + +Hash jest tworzony aby mieć pewność, że logi nie były modyfikowane. +Dodatkowo zabezpiecza wszystkie poprzednie logi począwszy od pierwszego. + +== Logowanie alarmów == + +W domyślnym katalogu logów openarmor jest katalogo alarmów +(/var/openarmor/logs/alerts). Zorganizowany w taki sam sposób jak +katalog zdarzeń. Przeczytaj powyżej aby zrozumieć. + diff --git a/doc/pl/manager.txt b/doc/pl/manager.txt new file mode 100644 index 000000000..691e39e0a --- /dev/null +++ b/doc/pl/manager.txt @@ -0,0 +1,19 @@ +openarmor HIDS 0.5 +Copyright (c) 2004,2005 Daniel B. Cid + + + +Jak serwer zarządza agentami. + +-Klient otwiera port 1514 (domyślnie) i nasłuchuje na wiadomości od + serwera. Wyłącznie IP serwera jest akceptowane. + +-Co 10 minut, klient wysyła powiadomienie o stanie do serwera. + Powiadomienie zawiera niektóre informacje o systemie klienckim oraz + informacje o plikach które posiada w katalogu shared. + +-Serwer otrzymuje wiadomości statusu, aktualizuje plik statusu agenta + oraz sprawdza czy posiada jakiś plik do wysłania dla agenta. Jeśli ma, + to łączy się z klientem i wysyła go. + +-Każda wiadomość jest szyfrowana. diff --git a/doc/pl/rootcheck.txt b/doc/pl/rootcheck.txt new file mode 100644 index 000000000..18a46f8e7 --- /dev/null +++ b/doc/pl/rootcheck.txt @@ -0,0 +1,67 @@ +Rootkit detection techniques used by the openarmor HIDS +by Daniel B. Cid, daniel.cid@gmail.com + +Zaczynając od wersji 0.4, openarmor HIDS dokonuje wykrywania rootkitów na +każdym systemnie na którym jest zainstalowany agent. Mechanizm +wykrywania rootkitów (rootcheck) jest wykonywany co X minut +(wyspecyfikowane przez użytkownika - domyśnie co dwie godziny) w celu +wykrycia zinstalowanych rootkitów. Używany razem z analizatorem logów +oraz mechanizmem sprawdzania integralności, staje się bardzo wydajnym +systemem monitorowania (openarmor HIDS dokonuje analizy logów i sprawdzania +integralności od wersji 0.1). + +Inną właściwością dołączoną do wersji 0.4 jest automatyczne rozsyłanie +sygnatur wykrywania rootkitów do wszystkich agentów przez serwer. +Redukuje to ilość obowiązków administratora. Serwer z agentami utrzymuje +kontakt co 10 minut. Dodatkowo jeśli serwer zostanie zaktualizowany +nowymi sygnaturami, przekazuje je wszystkim skonfigurowanym agentom. +Aby uzyskać więcej informacji zajżyj do dokumentacji zarządzania. + + +Kroki wykonywane przez rootcheck w celu wykrycia rootkitów: + +1- Czyta plik rootkit_files.txt, który zawiera sporą baze danych o + rootkitach i używanych przez nie plików. Próbuje wykonać: stats, + fopen i opendir na każdym z takich plików. Używa wszystkich tych + wywołań systemowych, ponieważ istnieją rootkity pracujące na poziomie + jądra, które ukrywają pliki przed niektórymi wywołaniami. Im więcej + użyjemy wywołań, tym lepsza będzie detekcja. Metoda jest podobna do + reguły anty-virusa, potrzebuje nieustanntgo uaktualniania. Szanse + detekcji rootkita którego nie ma (false-positive) są małe, za to już + szanse nie wykrycie rootkita (false-negative) rosną wraz z + modyfikacjami rootkitów. + +2- Czyta plik rootkit_trojans.txt który zawiera baze danych sygnatur + plików modyfikowanych na trojany przez rootkity. Technika modyfikacji + binariów na wersje z trojanami jest powszechnie używana przez + większość dostępnych rootkitów. Nastepująca metoda nie wykrywa + rootkitów poziomu jądra ani żadnych jeszcze nie znanych. + +3- Skanuje katalog /dev wyszukując anomali. /dev powinien tylko zawierać + pliki urządzeń oraz skrypt Makedev. Duża część rootkitów używa + katalogu /dev w celu ukrycia plików. Ta metoda może wykryć nieznane + dotąd rootkity. + +4- Skanuje cały system plików szukając niespotykanych plików oraz + tych z podejrzanymi uprawnieiami. Pliki użytkownika root z + możliwością zapisu dla innych są bardzo niebezpieczne, dlatego + rootkit wyszukuje takie. Pliki z ustawionym suid oraz ukryte katalogi + również są sprawdane. + +5- Szuja ukrytych procesów. Używa getsid() oraz kill() do sprawdzenia + czy dany pid jest używany. Jeśli dany pid jest używany, a "ps" nie + widzi go, wskazuje to na obecność rootkita poziomu jądra lub + zmodyfikowaną wersję "ps". Weryfikuje także wyniki kill i getsid, + które powinny być identyczne. + +6- Wyszukuje ukrytych portów. Używa bind() do sprawdzenia każdego portu + tcp i udp w systemie. Jeśli nie możemy wykonać bind na danym porcie + (czyli jest używany), a "netstat" go nie pokazuje, to prawdopodobnie + mamy zainstalowanego rootkita. + +7- Skanuje wszystkie interfejsy w systemnie i wyszukuje te z włączonym + trybem "promisc". Jeśli interfejs jest w trybie "promisc", "ifconfig" + tego powinien pokazać to, jeśli nie prawdopodobnie mamy + zainstalowanego rootkita. + +EOF diff --git a/doc/pl/rule_ids.txt b/doc/pl/rule_ids.txt new file mode 100644 index 000000000..3ff8975d9 --- /dev/null +++ b/doc/pl/rule_ids.txt @@ -0,0 +1,35 @@ +0100 - 0199 Wiadomości błędów Syslog +0200 - 0299 Wiadomości NFS +0300 - 0399 Wiadomości Xinetd +0400 - 0499 Wiadomości kontroli dostępu +0500 - 0599 Wiadomości Sendmail +0600 - 0699 Wiadomości Ftp +0700 - 0799 Wiadomości Smartd +0800 - 0899 Wiadomości Kernel +0900 - 0949 Wiadomości Crond +0950 - 0999 Wiadomości Automount +1000 - 1099 Wiadomości Squid syslog +1100 - 1199 Wiadomości Su +1200 - 1299 Wiadomości Tripwire +1300 - 1399 Wiadomości Adduser +1400 - 1499 Wiadomości Sudo +1500 - 1599 Wiadomości sshd +1600 - 1699 Wzorce ataków +1700 - 1799 Wzorce przejmowania uprawnień +1800 - 1899 Wzorce skanowań +1900 - 1999 Reguły DNS +2000 - 2499 Reguły PIX +2500 - 2599 Reguły Proftpd +2600 - 2699 Wiadomości PPTP +2700 - 2799 Reguły Reguły FTS +2800 - 2899 Reguły Pure-FTPD +2900 - 2999 Reguły Spamd +3000 - 3099 Reguły błędów dla Apache'a (dla logów) +3100 - 3199 Reguły dostępu dla Apache'a (dla logów) +4000 - 4999 Reguły IDS +5000 - 5999 Reguły Squid +6000 - 6199 Reguły Postfix +6200 - 6499 Reguły Sendmail +7000 - 7499 Reguły Firewall +8000 - 8999 Reguły Windows +100000 - 199999 Reguły zdefiniowane przez użytkownika diff --git a/doc/pl/rules.txt b/doc/pl/rules.txt new file mode 100644 index 000000000..7b8e17379 --- /dev/null +++ b/doc/pl/rules.txt @@ -0,0 +1,85 @@ +openarmor HIDS v0.7 +Copyright (c) 2004-2006 Daniel B. Cid + + + + +--- Klasyfikacja reguł --- + + +-- Klasyfikacja -- + +Reguły są podzielone na 16 poziomów. Niektóre poziomy są aktualnie nie używane. +Inne mogą być dodane pomiędzy nimi lub za. + +**Reguły są czytane od najwyższego do najniższego poziomu. ** + +00 - Ignorowane - Nie jest podejmowana żadna akcja. Używane aby uniknąć + fałszywych ataków. Te reguły są przetwarzane przed wszystkimi pozostałymi. + Zawierają zdarzenia nie związane z bezpieczeństwem. +01 - Brak - +02 - Niski priorytet powiadomień systemowych - Powiadomienia systemowe lub + wiadomości statusu. Nie związane z bezpieczeństwem. +03 - Pomyślne/Autoryzowane akcje - Zawiera pomyślne próby logowania, dozwolone + akcje firewall'a, itd. +04 - Niski priorytet błędów systemowych - Błędy związane ze złą konfiguracją lub + nieużywanymi urządzeniami/aplikacjami. Nie są związane z bezpieczeństwem, + zazwyczaj są powodowane poprzez instalacje lub testowanie aplikacji. +05 - Błędy wygenerowane przez użytkownika - Zawierają błędne logowania, + zabronione akcje, itp. Nie mają wpływu na bezpieczeństwo, ponieważ już są + blokowane. +06 - Atak o niskim znaczeniu - Powodowane przez robaki lub wirusy które nie mają + wpływu na system (takie jak code red dla serwera apache, itp). Zawierają + także często akcje IDS oraz błędy. +07 - Dopasowanie *bad word* - Zawierają słowa "bad', "error", itp. W większości + niesklasyfikowane akcje, które mogą mieć wpływ na bezpieczeństwo. +08 - Widziane poraz pierwszy - Zawierają akcje widziane poraz pierwszy. Np. + pierwszy raz jest generowana akcja IDS albo pierwsze logowanie użytkownika. + Jeśli dopiero zacząłeś używać openarmor HIDS, takie akcje najprawsopodobniej + będą występować często. Lecz po jakimś czasie znikną. Zawierają także akcje + związane z bezpieczeństwem (takie jak uruchomienie sniffera lub podobnego + narzędzia). +09 - Błędy z nieznanego źródła - Zawierają próby logowania jako nieznany + użytkownik lub z niepoprawnego źródła. Mogą mieć wpływ na bezpieczeństwo + (szczególnie gdy powtarzane). Obejmują także błędy związane z kontem + "administratora", root'a. +10 - Powtarzalne błędy generowane przez użytkownika - Zawierają wielokrotne + nieudane próby logowania, błędy autoryzacji itp. Mogą oznaczać atak lub + poprostu użytkownik zapomiał swoich danych autoryzujących. +11 - Ostrzeżenie, sprawdzanie spójności - Zawiera wiadomości oznaczające + modyfikacje plików binarnych lub obecność rootkit'ów (generowane przez + rootcheck). Jeśli aktualizowałeś system nie powinieneś się przejmować tymi + ostrzeżeniami. Mogą oznaczać udany atak. +12 - Wysoce istotne zdarzenia - Zawierają wiadomości błądów lub ostrzeżeń od + systemu, jądra, itp. Moga oznaczać atak na konkretną aplikacje. +13 - Niespotykane błędy (wysoce istotne) - W większości dopasowane do wzorców + znanych ataków. +14 - Wysoce istotne zdarzenia bezpieczeństwa - Akcje wykrywane poprzez związki + ze sobą, zazwyczaj oznaczają atak. +15 - Poważny atak - Natychmiastowa reakcja jest potrzebna (nie może być mowy tu + o fałszywym ataku). + + +== Grupa reguł == + +-Możemy wyspecyfikować grupy dla specyficznych reguł. Jest to używane do + aktywnej ochrony oraz do relacji. +-Aktualnie używamy następujących grup: + +- invalid_login +- authentication_success +- authentication_failed +- connection_attempt +- attacks +- adduser +- sshd +- ids +- firewall +- squid +- apache +- syslog + + +== Konfiguracja reguł == + +http://www.theopenarmor.org/docs/docs/manual/rules-decoders/index.html \ No newline at end of file diff --git a/doc/rootcheck.txt b/doc/rootcheck.txt new file mode 100644 index 000000000..03ff28472 --- /dev/null +++ b/doc/rootcheck.txt @@ -0,0 +1,74 @@ +Rootkit detection techniques used by the openarmor HIDS +by Daniel B. Cid, daniel.cid@gmail.com + + +Starting on version 0.4, the openarmor HIDS will perform +rootkit detection on every system where the agent is +installed. The rootcheck (rootkit detection engine) will +be executed every X minutes (user specified --by default +every 2 hours) to detect any possible rootkit installed. +Used witht the log analysis and the integrity checking +engine, it will become a very powerful monitoring solution +(the openarmor HIDS performs log analysis and integrity +checking since version 0.1). + +Other feature included on version 0.4 is that the analysis +server will automatically forward the rootkit detection +signatures to the agents, reducing the administration +overhead for the system admin. The agents and server will +keep contact every 10 minutes and if the server is +updated with a new signature file, it will forward them +to all configured agents. Take a look at the management +documentation for more information. + +The rootcheck will perform the following steps on the +system trying to find rootkits: + + +1- Read the rootkit_files.txt which contains a big database + of rootkits and files used by them. It will try to stats, + fopen and opendir each specified file. We use all these + system calls, because some kernel-level rootkits, hide + files from some system calls. The more system calls we + try, the better the detection. This method is more like + an anti-virus rule that needs to be updated constantly. + The chances of false-positives are small, but false + negatives can be produced by modifying the rootkits. + +2- Read the rootkit_trojans.txt which contains a database + of signatures of files trojaned by rootkits. This + technique of modifying binaries with trojaned versions + was commonly used by most of the popular rootkits + available. This detection method will not find any + kernel level rootkit or any unknown rootkit. + +3- Scan the /dev directory looking for anomalies. The /dev + should only have device files and the Makedev script. + A lot of rootkits use the /dev to hide files. This + technique can detect even non-public rootkits. + +4- Scan the whole filesystem looking for unusual files and + permission problems. Files owned by root, with written + permission to others are very dangerous and the rootkit + detection will look for them. Suid files, hidden directories + and files will also be inspected. + +5- Look for the presence of hidden processes. We use getsid() + and kill() to check if any pid is being used or not. If + the pid is being used, but "ps" can't see it, it is the + indication of kernel-level rootkit or a trojaned version + of "ps". We also verify the output of kill and getsid that + should be the same. + +6- Look for the presence of hidden ports. We use bind() to + check every tcp and udp port on the system. If we can't + bind to the port (it's being used), but netstat does not + show it, we probably have a rootkit installed. + +7- Scan all interfaces on the system and look for the ones + with "promisc" mode enabled. If the interface is in promiscuous + mode, the output of "ifconfig" should show that. If not, + we probably have a rootkit installed. + + +EOF diff --git a/doc/rule_ids.txt b/doc/rule_ids.txt new file mode 100644 index 000000000..d21c3cc23 --- /dev/null +++ b/doc/rule_ids.txt @@ -0,0 +1,104 @@ +# openarmor Rules ids. +# +# openarmor official rules should be under some of these +# assignments. +# +# Local rules should go from 100000 to 120000. +# +# Every rule will also have a revision attribute (if modified). +# *default revision is 0 (when first added). + +00000 - 00999 Internally reserved for openarmor +01000 - 01999 General syslog +02100 - 02299 NFS +02300 - 02499 Xinetd +02500 - 02699 Access control +02700 - 02729 Mail/procmail +02800 - 02829 Smartd +02830 - 02859 Crond +02860 - 02899 Mount/Automount + +03100 - 03299 Sendmail +03300 - 03499 Postfix +03500 - 03599 Spamd +03600 - 03699 Imapd +03700 - 03799 MailScanner + +04100 - 04299 Generic Firewall +04300 - 04499 Cisco PIX Firewall +04500 - 04699 Netscreen Firewall + +05100 - 05299 Kernels (Linux, Unix, etc) +05300 - 05399 Su +05400 - 05499 sudo +05500 - 05599 Pam unix +05600 - 05699 Telnetd +05700 - 05899 sshd +05900 - 05999 Adduser or user deletion. + +07100 - 07199 Tripwire +07200 - 07299 Arpwatch +07300 - 07399 Symantec Anti Virus + +09100 - 09199 PPTP +09200 - 09299 Squid syslog +09300 - 09399 Horde IMP + +10100 - 10199 FTS + +11100 - 11199 FTPd +11200 - 11299 ProFTPD +11300 - 11399 Pure-FTPD +11400 - 11499 vs-FTPD + +12100 - 12299 Named (bind DNS) + +13100 - 13299 Samba (smbd) + +14100 - 14199 Racoon SSL +14200 - 14299 Cisco VPN Concentrator + +17100 - 17399 Policy + +18100 - 18499 Windows system +18500 - 18650 Sysmon rules +18651 - 18750 MS IPSec rules +20100 - 20299 IDS +20300 - 20499 IDS (Snort specific) +20500 - 20509 Windows PowerShell + +30100 - 30999 Apache error log +31100 - 31199 Web access log + +31501 - 32000 Web Appsec rules + +35000 - 35999 Squid + +40100 - 40499 Attack patterns +40500 - 40599 Privilege escalation + +40600 - 40699 Scan patterns +40700 - 40899 Systemd +40900 - 40999 Firewalld + +51500 - 51999 OpenBSD rules +52000 - 52499 Apparmor rules +52500 - 53199 clam av rules +53200 - 53499 nsd rules +53500 - 53299 opensmtpd rules +53300 - 53399 owncloud rules +53400 - 53500 proxmox ve rules +53501 - 53550 OpenSMTPd rules +53551 - 53599 dnsmasq +53600 - 53625 linux usb detection rules +53626 - 53630 ms usb detection rules +53631 - 53699 ms firewall rules +53700 - 53749 PSAD rules +53750 - 53799 unbound rules +53800 - 53825 Kaspersky Endpoint Security 10 for Linux rules +53826 - 53829 MHN - Dionaea +53830 - 53840 MHN - Cowrie +56000 - 56200 FreeBSD rules + +100000 - 109999 User defined rules + diff --git a/doc/rules.txt b/doc/rules.txt new file mode 100644 index 000000000..80870c701 --- /dev/null +++ b/doc/rules.txt @@ -0,0 +1,90 @@ +openarmor HIDS v0.9 +Copyright (C) 2009 Trend Micro Inc. + + + +--- Rules Classification --- + + +-- Classification -- + +The rules are classified in multiple levels. From the lowest (00) to the maximum +level 16. Some levels are not used right now. Other levels can be added between +them or after them. + +**The rules will be read from the highest to the lowest level. ** + +00 - Ignored - No action taken. Used to avoid false positives. These rules + are scanned before all the others. They include events with no + security relevance. +01 - None - +02 - System low priority notification - System notification or + status messages. They have no security relevance. +03 - Successful/Authorized events - They include successful login attempts, + firewall allow events, etc. +04 - System low priority error - Errors related to bad configurations or + unused devices/applications. They have no security relevance and + are usually caused by default installations or software testing. +05 - User generated error - They include missed passwords, denied + actions, etc. By itself they have no security relevance. +06 - Low relevance attack - They indicate a worm or a virus that have + no affect to the system (like code red for apache servers, etc). + They also include frequently IDS events and frequently errors. +07 - "Bad word" matching. They include words like "bad", "error", etc. + These events are most of the time unclassified and may have + some security relevance. +08 - First time seen - Include first time seen events. First time + an IDS event is fired or the first time an user logged in. + If you just started using openarmor HIDS these messages will + probably be frequently. After a while they should go away. + It also includes security relevant actions (like the starting + of a sniffer or something like that). +09 - Error from invalid source - Include attempts to login as + an unknown user or from an invalid source. May have security + relevance (specially if repeated). They also include errors + regarding the "admin" (root) account. +10 - Multiple user generated errors - They include multiple bad + passwords, multiple failed logins, etc. They may indicate an + attack or may just be that a user just forgot his credentials. +11 - Integrity checking warning - They include messages regarding + the modification of binaries or the presence of rootkits (by + rootcheck). If you just modified your system configuration + you should be fine regarding the "syscheck" messages. They + may indicate a successful attack. Also included IDS events + that will be ignored (high number of repetitions). +12 - High importancy event - They include error or warning messages + from the system, kernel, etc. They may indicate an attack against + a specific application. +13 - Unusual error (high importance) - Most of the times it matches a + common attack pattern. +14 - High importance security event. Most of the times done with + correlation and it indicates an attack. +15 - Severe attack - No chances of false positives. Immediate + attention is necessary. + + +== Rules Group == + +-We can specify groups for specific rules. It's used for active +response reasons and for correlation. +- We currently use the following groups: + +- invalid_login +- authentication_success +- authentication_failed +- connection_attempt +- attacks +- adduser +- sshd +- ids +- firewall +- squid +- apache +- syslog + + + +== Rules Config == + +http://www.theopenarmor.org/docs/docs/manual/rules-decoders/index.html + diff --git a/etc/decoder.xml b/etc/decoder.xml new file mode 100644 index 000000000..7d932ffff --- /dev/null +++ b/etc/decoder.xml @@ -0,0 +1,3367 @@ + + + + + + + + + \(pam_unix\)$ + + + + + .* + ^pam_unix|^\(pam_unix\)|^pam_succeed_if + + + + pam + ^session \w+ + ^for user (\S+) + user + + + + + + pam + rhost=\S+[ ]+user=\S+ + rhost=(\S+)[ ]+?user=(\S+) + srcip, user + + + + pam + ruser + ^=(\S+) + user + + + + pam + rhost=(\S+) + srcip + + + + pam + rhost + ^=(\S+) + srcip + + + + + + + ^sshd + + + + sshd + ^Accepted + ^ \S+ for (\S+) from (\S+) port + user, srcip + name, user, location + + + + sshd + ^User \S+ from + ^User (\S+) from (\S+) + user, srcip + + + + sshd + ^User + ^(\S+), coming from (\S+), + user, srcip + name, user, location + + + + sshd + ^Postponed keyboard-interactive|^Failed keyboard-interactive + user (\S+) from (\S+) port (\d+) + user, srcip, srcport + + + + sshd + ^Failed \S+ for invalid user|^Failed \S+ for illegal user + from (\S+) port \d+ \w+$ + srcip + + + + sshd + ^Failed \S+ + ^for (\S+) from (\S+) port \d+ + user, srcip + + + + sshd + ^error: PAM: Authentication \w+ + ^for (\S+) from (\S+)$ + user, srcip + + + + sshd + ^error: PAM: + user (\S+) from (\S+) + user, srcip + + + + sshd + ^reverse mapping checking + ^\w+ for \S+ \[(\S+)\] |^\w+ for (\S+) + srcip + + + + sshd + ^Invalid user|^Illegal user + from (\S+) + srcip + + + + sshd + ^scanned from + (\S+) + srcip + + + + sshd + ^Received disconnect + ^from (\S+): |^from (\S+) + srcip + + + + sshd + ^Disconnected from invalid user + \S+ (\S+) + srcip + + + + sshd + ^Connection closed by + user (\S+) (\S+) + user, srcip + + + + sshd + ^Unable to negotiate with + ^(\S+) port (\d+) + srcip, srcport + + + + sshd + ^Protocol major versions differ for + ^(\S+) + srcip + + + + + + sshd + ^Did not receive identification |^Bad protocol version + from (\S+)$| from (\S+) port (\d+?)$ + srcip,srcport + + + + sshd + ^refused connect + ^from (\S+)$|^from \S+ \((\S+[A-Za-z0-9@_-]+?)\)$|^from \S+ \((\S+::)\)$ + srcip + + + + sshd + ^Connection closed + ^by (\S+)$ + srcip + + + + sshd + ^Received disconnect + ^from (\S+): + srcip + + + + + + sshd + ^pam_ldap: + user "uid=(\S+),ou=[A-Za-z0-9@_-]+?,dc=[A-Za-z0-9@_-]+?,dc=[A-Za-z0-9@_-]+" + user + + + + sshd + fatal: Unable to negotiate with + ^(\S+) port (\d+?): |^(\S+): + srcip, srcport + + + + sshd + rhost=\S+[ ]+?user=\S+ + rhost=(\S+)[ ]+?user=(\S+) + srcip, user + + + + + + sshd + exceeded for + (\S+) from (\S+) port (\d+) + user, srcip, srcport + + + + + + ^dropbear + + + + + + dropbear + password + for '(\S+)' from (\S+):\d+$ + dstuser, srcip + + + + + + dropbear + nonexistent + from (\S+):\d+$ + srcip + + + + + + dropbear + (\S+) for '(\S+)' with key \S+ (\S+) from (\S+):\d+$ + status,dstuser,extra_data,srcip + + + + + ^telnetd|^in\.telnetd + + + + telnetd + from (\S+)$ + srcip + + + + + + + ^rshd$ + + + + rshd + ^Connection from (\S+) on illegal port$ + srcip + + + + + + + ^cimserver$ + + + + cimserver + ^[A-Za-z0-9@_-]+: Authentication failed for user + ^(\S+)\.$ + user + + + + + + + + ^smbd + + + + smbd + User name: + ^ (\S+)\. + user + + + + smbd + from \((\S+)\) + srcip + + + + smbd + from (\S+)$ + from (\S+)$ + srcip + + + + smbd + to client \S+\. + to client (\S+)\. + srcip + + + + ^nmbd + + + + + + ^sudo + ^[ ]*?(\S+)[ ]:[ ]TTY=\S+[ ];[ ]PWD=(\S+)[ ];[ ]USER=(\S+)[ ];[ ]COMMAND=(.+)$| + ^[ ]*?(\S+)[ ]:[ ]TTY=\S+[ ];[ ]PWD=(\S+)[ ];[ ]USER=(\S+)[ ];[ ]TSID=\S+[ ];[ ]COMMAND=(.+)$ + dstuser,url,srcuser,status + name,dstuser,location + First time user executed the sudo command + + + + + ^su$ + + + + su + ^'su + ^'su (\S+)' \S+ for (\S+) on \S+$ + dstuser, srcuser + name, srcuser, location + + + + su + pam_ldap + user "uid=(\S+), + user + + + + ^SU \S+ \S+ + ^\S \S+ (\S+)-(\S+)$ + srcuser, dstuser + name, srcuser, location + + + + su + ^FAILED SU + ^\(to (\S+) (\S+) on + dstuser, srcuser + + + + su + + ^BAD SU (\S+) to (\S+) on| + ^failed: \S+ changing from (\S+) to (\S+)| + ^\S \S+ (\S+)[()*+,.:;\<=>?\[\]!"'#%&$|{}-](\S+)$|^(\S+) to (\S+) on + srcuser, dstuser + name, srcuser, location + + + + + + + ^proftpd + + + + proftpd + : Login successful + ^\S+ \(\S+\[(\S+)\]\)[ ]*?\S [A-Za-z0-9@_-]+? (\S+): + Login successful + srcip, user + name, user, srcip, location + + + + proftpd + ^\S+ \(\S+\[(\S+)\]\) + srcip + + + + + + + ^pure-ftpd + + + + pure-ftpd + ^\S+ \[INFO\] \S+ is now logged in + ^\(\?@(\S+)\) \[INFO\] (\S+) is now logged in + srcip, user + name, user, srcip, location + + + + pure-ftpd + ^\((\S+)@(\S+)\) \[ + user,srcip + + + + + + ^\S+ - \S+ \[\d{2}/\S{3}/\d{4}:\d{2}:\d{2}:\d{2} \S\d{4}\] "[A-Za-z0-9@_-]+? \S+" + ^(\S+) - (\S+) \[\d{2}/\S{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4}\] "(\S+) (.+) (\d+) \d+$ + extra_data,dstuser,action,url,status + + + + + + + + + + + ^[A-Za-z0-9@_-]{3} [A-Za-z0-9@_-]{3}[ ]+?\d+? \S+ \d+? \[pid \d+?\] + + + + ^vsftpd + ^[A-Za-z0-9@_-]{3} [A-Za-z0-9@_-]{3}[ ]+?\d+? \S+ \d+? \[pid \d+?\] + + + + vsftpd + LOGIN: + \[(\S+)\] (\S+ LOGIN): Client "(\S+[A-Za-z0-9@_-])"$ + user,status,srcip + + + + vsftpd + ^CONNECT: + (CONNECT): Client "(\S+[A-Za-z0-9@_-]+?)"$ + action,srcip + + + + vsftpd + \[(\S+)\] (OK \S+): Client "(\S+)", "(.+)".* + user,status,srcip,url + + + + vsftpd + Client "(\S+[A-Za-z0-9@_-])"$ + srcip + + + + + + ^ftpd|^in\.ftpd + + + + ftpd + ^Failed authentication from: \S+ | + ^repeated login failures from + + ^\S+ \[(\S+)\]$|^(\S+) + srcip + + + + ftpd + ^FTP LOGIN REFUSED + \[(\S+)\]$ + srcip + + + + ftpd + from (\S+)$ + srcip + + + + ftpd + ^login \S+ from \S+ failed\. + ^login (\S+) from (\S+) failed\.$ + user, srcip + + + + + + + ^arpwatch + + + + arpwatch + ^new station |^bogon + ^(\S+) (\S+) + srcip, extra_data + name, srcip, extra_data + + + + + + + ^MySQL log: + + + + + + + ^\[\d{4}-\d{2}-\d{2} \S+ [A-Za-z0-9@_-]+?\] + ^\S+ ([A-Za-z0-9@_-]+?): + status + + + + + + + ^imapd + user=(\S+) .+ \[(\S+)\]$ + user,srcip + + + + + + + ^vpopmail + + + + vpopmail + ^vchkpw-\S+: password fail + (\S+)@\S+:(\S+)$ + user, srcip + + + + vpopmail + ^vchkpw-\S+: vpopmail user not + ^found (\S+):(\S+)$ + user, srcip + + + + vpopmail + ^vchkpw-\S+: null password + ^given (\S+):(\S+)$ + user, srcip + + + + vpopmail + ^vchkpw-\S+: \(\S+\) login + ^success (\S+):(\S+)$ + user, srcip + + + + + + + ^vm-pop3d + + + + vm-pop3d + ^User ' + ^(\S+)' - [A-Za-z0-9@_-]+? auth, + from=(\S+)$ + user, srcip + + + + + + + ^pop3d|^courierpop3login|^imaplogin|^courier-pop3|^courier-imap + + + + courier + ^LOGIN, + ^user=(\S+), ip=\[(\S+)\]$ + user, srcip + + + + courier + , ip=\[(\S+)\]$ + srcip + + + + + + + + ^dovecot + + + + dovecot + ^\w{4}-login: Login: + ^user=\<(\S+)\>, method=\S+, rip=(\S+), lip=(\S+), mpid=\S+, (\S*?)$ + user, srcip, dstip, protocol + + + + dovecot + ^\w{4}-login: Aborted login + : user=\<(\S+)\>, method=\S+, rip=(\S+), lip=(\S+), (\S*)$ + user, srcip, dstip, protocol + + + + dovecot + ^auth\(default\)|auth-worker\(default\) + ^: \S+\((\S+),(\S+)\) + user, srcip + + + + dovecot + ^\w{4}-login: + \(auth failed, \d+? attempts in \d+? secs\): user=\<(\S+)\>, method=\S+, rip=(\S+), lip=(\S+) + user,srcip,dstip + + + + dovecot + ^\w{4}-login: Disconnected: + ^rip=(\S+), lip=(\S+) + srcip, dstip + + + + ^Info$|^Warn$ + + + + dovecot-info + imap-login + Login: user=(\S+), method=.+, rip=(\S+), lip=(\S+) + user, srcip, dstip + + + + dovecot-info + auth\(.+\): \S+\((\S+),(\S+)\): + user, srcip + + + + + + ^named + + + + named + : query:? + client @\S+ (\S+)#\d+[ ]*?\S*: + srcip,url + + + + named + query: (\S+) IN|query \S+ '(\S+)/ + url + + + + named + ^client + ^(\S+)# + srcip + + + + named + from \[(\S+)\] + srcip + + + + named + for master + for master (\S+):(\d+) \S+ \(source (\S+)#d\+\)$ + dstip,dstport,srcip + + + + + + + ^postfix + + + + true + postfix + ^NOQUEUE: reject: \w{4} from + \[(\S+)\]:\d+?: (\d+?) |\[(\S+)\]:(\d+?): |\[(\S+)\]: (\d+?) |\[(\S+)\]:(\d+?): + srcip,id + + + + postfix + ^warning: \S+: SASL + ^warning: \S+\[(\S+)\]: + srcip + + + + + + ^sendmail|^sm-mta|^sm-msp-queue + + + + sendmail-reject + ^\S+: rejecting commands from + ^ \S+ \[(\S+)\] + srcip + + + + sendmail-reject + relay=\[ + ^(\S+)\] + srcip + + + + sendmail-reject + relay=\S+ \[ + ^(\S+)\] + srcip + + + + + + + + ^smf-sav + ^sender check failed| + ^sender check tempfailed + ^ \(cached\): \S+, (\S+),| + ^: \S+, (\S+), + srcip + + + + + + + ^MailScanner + + + + mailscanner + ^Message \S+ from + ^(\S+) \S+ to \S+ is (\w+) + srcip, action + + + + + + + ^smtpd + + + + smtpd + ^client + ^client (\S+) + srcip + + + + smtpd + relay= + relay=\S+ \[(\S+)\], + srcip + + + + smtpd + ^smtp-in: + ^(\S+) + status + + + + smtpd + => (\d+) + action + + + + + + ^kernel + + + + iptables + firewall + ^\[\d+\.\d+\] \S+ IN= + + ^\[\d+\.\d+\] (\S+) .+ SRC=(\S+) DST=(\S+) + .+ PROTO=(\w+) + action,srcip,dstip,protocol + + + + iptables + firewall + ^SPT=(\d+) DPT=(\d+) + srcport,dstport + + + + iptables + firewall + ^\S+ IN= + + ^(\S+) .+ SRC=(\S+) DST=(\S+) .+ + PROTO=(\w+) + action,srcip,dstip,protocol + + + + iptables + firewall + ^SPT=(\d+?) DPT=(\d+?) + srcport,dstport + + + + iptables + firewall + ^Shorewall:\S+: + + ^(\S+):.+ SRC=(\S+) DST=(\S+) .+ + PROTO=(\w+) + action,srcip,dstip,protocol + + + + iptables + firewall + ^SPT=(\d+) DPT=(\d+) + srcport,dstport + + + + iptables + firewall + ^[()*+,.:;\<=>?\[\]!"'#%&$|{}-]\S+[()*+,.:;\<=>?\[\]!"'#%&$|{}-] Shorewall:\S+: + ^(\S+):.+ SRC=(\S+) DST=(\S+) .+ + PROTO=(\w+) + action,srcip,dstip,protocol + + + + + + firewall + ^ipmon + (\w) (\S+),(\d+?) -> (\S+),(\d+?) PR (\w+) + action,srcip,srcport,dstip,dstport,protocol + + + + + + firewall + ^ipsec_logd + R:(\w) \w:\S+ S:(\S+) + D:(\S+) P:(\S+) SP:(\d+) DP:(\d+) + action,srcip,dstip,protocol,srcport,dstport + + + + + + + firewall + ^pf$ + PF_Decoder + + + + + + + firewall + ^id=[A-Za-z0-9@_-]+? sn=[A-Za-z0-9@_-]+? time=\S+ \S+ fw=\S+ pri=\d + SonicWall_Decoder + + + + + + + + ^NetScreen device_id + + + + netscreenfw + firewall + + system-notification-00257 + \(traffic\): + + proto=(\w+) .+action=(\w+) + .+src=(\S+) dst=(\S+) src_port=(\d+) dst_port=(\d+) + protocol, action, srcip, dstip, srcport, dstport + + + + netscreenfw + system-critical-.+ from | + system-alert-.+ from | + system-emergency-.+ From + + system-(\w+?)-(\d+): .+ + from.+(\S+) + action, id, srcip + + + + netscreenfw + system-(\w+?)-(\d+): + action, id + + + + + + ^%PIX-|^[A-Za-z0-9@_-]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}: %PIX-| + ^%ASA-|^[A-Za-z0-9@_-]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}: %ASA-| + ^%FWSM-|^[A-Za-z0-9@_-]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}: %FWSM- + + + + pix + firewall + ^2-106001 + ^(\S+): [A-Za-z0-9@_-]+ ([A-Za-z0-9@_-]+) \S+ (\S+) from + (\S+)/(\S+) to (\S+)/(\S+) + id, protocol, action, srcip, srcport, dstip, dstport + + + + pix + firewall + ^3-710003|^7-710002|^7-710005 + ^(\S+): (\S+) [A-Za-z0-9@_-]+ ([A-Za-z0-9@_-]+) .+from + (\S+)/(\S+) to [A-Za-z0-9@_-]+:(\S+)/(\S+) + id, protocol, action, srcip, srcport, dstip, dstport + + + + pix + firewall + ^4-106023 + ^(\S+): ([A-Za-z0-9@_-]+) ([A-Za-z0-9@_-]+) src [A-Za-z0-9@_-]+: + (\S+)/(\S+) dst [A-Za-z0-9@_-]+?:(\S+)/(\S+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^4-106019 + ^(\S+): IP packet from (\S+) to + (\S+), protocol ([A-Za-z0-9@_-]+) ([A-Za-z0-9@_-]+) + id, srcip, dstip, protocol, action + + + + pix + firewall + ^2-106006|^2-106007 + ^(\S+): ([A-Za-z0-9@_-]+) \S+ ([A-Za-z0-9@_-]+) from + (\S+)/(\d+?) to (\S+)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^6-106015 + ^(\S+): ([A-Za-z0-9@_-]+) ([A-Za-z0-9@_-]+) \(no connection\) from (\S+)/ + (\d+) to (\S+)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^6-305012 + ^(\S+): ([A-Za-z0-9@_-]+) [A-Za-z0-9@_-]+ ([A-Za-z0-9@_-]+) translation + from [A-Za-z0-9@_-]+:(\S+)/(\d+) to [A-Za-z0-9@_-]+:(\S)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^3-106011|^3-106010 + ^(\S+): ([A-Za-z0-9@_-]+) .+ ([A-Za-z0-9@_-]+) src + [A-Za-z0-9@_-]+?:(\S+)/(\d+?) dst [A-Za-z0-9@_-]+?:(\S+)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + ^5-304001: + ^(\S+): (\S+) Accessed URL + (\S+):(http[A-Za-z0-9@_-]*://.+)| + ^(\S+): (\S+) Accessed URL (\S+): + id, srcip, dstip, url + + + + pix + ^5-304002: + ^(\S+): Access (denied) URL (http[A-Za-z0-9@_-]*://.+) + SRC (\S+) DEST (\S+) on interface + id, action, url, srcip, dstip + + + + pix + ^2-106012: |^2-106017: | + ^2-106020|^1-106021|^1-106022| + ^4-4000 + ^(\S+): .+ from (\S+) + id, srcip + + + + pix + ^6-308001 + ^(\S+): .+ (\S+) + id, srcip + + + + pix + ^6-605004|^6-605005 + ^(\S+): Login (\S+) from (\S+)/(\d+?) .+user "([A-Za-z0-9@_-]+?)" + id, action, srcip, srcport, user + + + + pix + ^(\S+): + id + + + + + + + ^\d+? \d{2}/\d{2}/\d{4} \S+ SEV=\d + ^(\S+) RPT=\d+? (\S+) + id, srcip + + + + + + + + ^snort + + + + ids + ^\[\*\*\] \[\d+:\d+:\d+\] + + + + snort + ids + ^\[\*\*\] \[|^\[Drop\] \[\*\*\] \[|^\[ + (\d+:\d+:\d+)\] .+ (\S+?):?\d* -> ([^:]+) + id,srcip,dstip + name,id,srcip,dstip + + + + + + + ^isakmpd + + + + isakmpd + message from + from (\S+) port (\d+) + srcip,srcport + + + + isakmpd + from peer + from peer (\S+):(\d+?)$ + srcip,srcport + + + + + + + ^suhosin + ids + ^ALERT - (.+) \(attacker '(\S+)', + id, srcip + name, location, id + + + + + + + ids + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\| + ^\S+\|(\S+)\| + (\S+)\|(\S+)\| + id, srcip, dstip + name, id, srcip, dstip + + + + + + + ^\[[A-Za-z0-9@_-]+\] \[imp\] |^\[[A-Za-z0-9@_-]+\] \[horde\] + + + + horde_imp + ^Login success + ^for (\S+) \[(\S+)\] + user, srcip + + + + horde_imp + ^FAILED LOGIN + ^ (\S+) to \S+ as (\S+) + srcip, user + + + + + + + ^WPsyslog|^wpcore + ^\[ + ^(\S+) + srcip + + + + + + + + ^roundcube + + + + ^\[\d{2}-[\w]{3}-\d{4} \d{2}:\d{2}:\d{2} \S+\] + + + + roundcube + Successful login for + ^(\S+) \(id \d+\) from (\S+)$|^(\S+) \(ID: \d+\) from (\S+) + user, srcip + + + + roundcube + \] \w+ Error: Authentication + ^for (\S+) failed + user + + + + roundcube + > \w+ Error: Login failed |> Failed login + ^for (\S+) from (\S+). |^for (\S+) from (\S+) in session + user, srcip + + + + + + + + ^httpd + + + + ^\[warn\] |^\[notice\] |^\[error\] + + + + ^\[\w+ \w+ \d+ \d+:\d+:\d+\.\d+ \d+\] (?:\[\S+:warn\]|\[\S+:notice\]|\[\S*:error\]|\[\S+:info\]) + + + + apache-errorlog + \[client \S+:\d+?\] \S+: + \[client (\S+):(\d+?)\] (\S+): + srcip,srcport,id + + + + apache-errorlog + \[client \S+\] \S+: + \[client (\S+)\] (\S+): + srcip,id + + + + + apache-errorlog + \[client + ^ (\S+):(\d+?)\] |^ (\S+)\] + srcip,srcport + + + + + + + ^20\d{2}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[ + + + + nginx-errorlog + , client: \S+, server: \S+, request: "\S+ + , client: (\S+), + srcip + + + + + + + + web-log + ^\S+ \S+ \S+ \[\S+ \S\d+\] "\w+ \S+ HTTP\S+" + ^(\S+) \S+ (\S+) \[\S+ \S\d+\] + "(\w+) (\S+) HTTP\S+" (\d+) + srcip, srcuser, action, url, id + + + + + + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} + + + + + + + windows-date-format + firewall + true + ^OPEN|^CLOSE|^DROP + ^(\w+) (\w+) + (\S+) (\S+) (\d+) (\d+) + action, protocol, srcip, dstip, srcport, dstport + + + + + + windows-date-format + web-log + true + ^\S+ \S+ W3SVC + ^(\S+) \S+ \S+ \S+ \S+ + \d+ \S+ (\S+ \S+) (\d+) + srcip,url,id + + + + + + windows-date-format + web-log + true + ^W3SVC\d+ \S+ \S+ \S+ + ^(\S+ \S+) \d+ \S+ (\S+) + \S+ \S+ \S+ \S+ \S+ (\d+) + url, srcip, id + + + + + + windows-date-format + web-log + true + ^\S+ GET |^\S+ POST + (\S+ \S*) .* (\S+) \S*.* (\d{3}) \S+ \S+ \S+ + url,srcip,id + + + + + + windows-date-format + true + ^\S+ \S+ MSFTPSVC + ^(\S+) (\S+) \S+ \S+ \S+ + \d+ \[\d+\](\S+) \S+ \S+ (\d+) + srcip,user,action,id + + + + + + + windows-date-format + true + ^\S+ \S+ SMTPSVC + ^(\S+) \S+ \S+ \S+ \S+ + \d+ (\S+) \S+ \S+ (\d+) + srcip, action, id + + + + + ^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d: \( + + + + + + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}: + + + + racoon + true + ^ERROR: couldn't find the pskey + ^for (\S+) + srcip + + + + racoon + ^([A-Za-z0-9@_-]+?): + action + + + + + + + windows + ^WinEvtLog + + + + windows + windows + ^.+: ([A-Za-z0-9@_-]+?)\((\d+?)\): (.+): + (.+): .+: (\S+): + status, id, extra_data, user, system_name + name, location, system_name + + + + windows + windows + Source Network Address: (\S+) + srcip + + + + windows + windows + Account Name:[ ]+?([A-Za-z0-9@_-]+?)[ ]+?Account + user + + + + windows + windows + Account Domain:[ ]+?([A-Za-z0-9@_-]+?)[ ]+?Logon ID: + extra_data + + + + + windows + ^security\[[A-Za-z0-9@_-]+?\] \d+? + ^([A-Za-z0-9@_-]+?)\[([A-Za-z0-9@_-]+?)\] (\d+?) + extra_data, status, id + + + + + + windows + ^MSWinEventLog\t\d\t.+\t\d+?\t[A-Za-z0-9@_-]{3}\S+ [A-Za-z0-9@_-]{3} \d{2} \d{2} + ^:\d{2}:\d{2} \d{4}\t(\d+?)\t(.+) + \t(.+)\t.+\t(.+)\t(.+)\t + id, extra_data, user, status, system_name + name, id, location, user, system_name + + + + + + ^[A-Za-z0-9@_-]{12}, + ^(\d+?),\d+?,\d+?,(\S+),(.+), + id, system_name, extra_data + name, location, id, system_name, extra_data + + + + + + ^\d{8},\d{3,}, + SymantecWS_Decoder + + + + + + + ^20\d{6}\<;> + ^\d+?\<;>\S+\<;>(\d+?)\<; + id + + + + + + + ^openarmor: + openarmor + + + + openarmor + ^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} openarmor-logcollector + ^\(\d+?\): (.) + extra_data + + + + openarmor + openarmor + ^Agent started: + ^ '(\S+\S)' + extra_data + name, location, extra_data + + + + openarmor + ^openarmor: Alert Level: + openarmorAlert_Decoder + + + + ^openarmor$ + openarmorAlert_Decoder + + + + + + ^[A-Za-z0-9@_-]{3} [A-Za-z0-9@_-]+?[ ]+?\d+? \d{2}:\d{2}:\d{2} [A-Za-z0-9@_-]+? \d+? /\S+/active-response + /bin/(\S+) (\S+) - (\S+) (\d+?\.\d+?) (\d+) + action, status, srcip, id, extra_data + + + + + ^\[\d{2}/[A-Za-z0-9@_-][A-Za-z0-9@_-][A-Za-z0-9@_-]/\d{4}:\d{2}:\d{2}:\d{2} \S+\] + host=(\S+), + srcip + + + + + + + ^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} '\S+' \d+? + + + + vmware + ^([A-Za-z0-9@_-]+?)\] \S+ \S+ + status + + + + vmware + ^: User ([A-Za-z0-9@_-]+?)@(\S+) + logged |^: Failed login \w+ for ([A-Za-z0-9_-]+)@(\S+) + user, srcip + + + + vmware + + + + vmware-syslog + ^Accepted|^Rejected + ^ \S+ for user (\S+) from (\S+)$ + user, srcip + + + + vmware-syslog + ^login from + ^(\S+) as + srcip + + + + + + + ^audit$ + + + + solaris_bsm + [A-Za-z0-9@_-]+? session \d+? by + ([A-Za-z0-9@_-]+) session \d+ by + status + + + + solaris_bsm + ^ \S+ as \S+:\S+ from (\S+) + srcip + + + + + + + ^asterisk + + + + asterisk + ^WARNING\[\d+?\]: \S+ in \S+: Don't know + ^\S+ how to respond via '([A-Za-z0-9@_-]+/\d\.\d/[A-Za-z0-9@_-]+)' + user + + + + asterisk + ^NOTICE\[\d+?\]: \S+ in \S+: Registration from + ^'.+' failed for '(\S+):(\d+?)'|^'.+' failed for '(\S+)' + srcip,srcport + + + + asterisk + Registration from + failed for '(\S+):(\d+?)'|failed for '(\S+)' + srcip,srcport + + + + asterisk + ^NOTICE\[\d+?\]\[[A-Za-z0-9@_-]+?\]: \S+ in \S+: Call from + ^'\S*' \((\S+):(\d+?)\) to extension '(\S+)' rejected because extension not found in context '(\S+)'\.$ + srcip, srcport, extra_data, extra_data + + + + asterisk + ^NOTICE\[\d+\]: \S+ in \S+: Host + ^(\S+) failed MD5 authentication for (\S+) + srcip, user + + + + + ^%\w+-\d-\w+: + + + + + ^%\w+-\d-\w+: + + + + + + cisco-ios + firewall + ^%SEC-6-IPACCESSLOGP: + ^list \S+ (\w+) (\w+) + (\S+)\((\d+)\) -> (\S+)\((\d+)\), + action, protocol, srcip, srcport, dstip, dstport + + + + + + cisco-ios + ids + ^%IPS-4-SIGNATURE: + ^Sig:(\d+) .+\[(\S+):(\d+) -> + (\S+):(\d+)\] + id, srcip, srcport, dstip, dstport + name, id, srcip, dstip + First time Cisco IOS IDS/IPS module rule fired. + + + + + + cisco-ios + ^(%\w+-\d-\w+): + id + + + + + + + + + ^Checkpoint + ^[ ]+?\S+ \d{2}:\d{2}:\d{2} + + + + checkpoint-syslog + firewall + ^drop|^accept|^reject + ^([A-Za-z0-9@_-]+)[ ]+\S+ >\S+ rule:.+ + src: (\S+); dst: (\S+); proto: (\S+); + action,srcip,dstip,protocol + + + + checkpoint-syslog + firewall + service: (\d+); s_port: (\d+); + dstport,srcport + + + + checkpoint-syslog + ids + ^monitor|^drop + attack: (.+); + src: (\S+); dst: (\S+); + proto: (\S+); + extra_data, srcip, dstip, protocol + name, extra_data, srcip, dstip + First time Checkpoint rule fired. + + + + + + + + + + ^\d{2},\d+?/\d+?/\d{4},\d+?:\d+?:\d+?,| + ^\d{2},\d+?/\d+?/\d{2},\d+?:\d+?:\d+?, + ^(\d{2}),\d+?/\d+?/\d{2,},\d+?:\d+?:\d+?,([A-Za-z0-9@_-]+?),(\S+) + id,extra_data,srcip + + + + + ^\d{5},\d{2}/\d{2}/\d{2},\d{2}:\d{2}:\d{2}, + ^(\d{5}), + id + + + + + + ^/bsd + + + + bsd_kernel + ^arp + for (\S+) by (\S+) on \S+ + dstip, extra_data + + + + + + userdel + user removed: name=(\S+)$ + srcuser + + + + + + + + ^mountd + + + + mountd + from host + (\S+) port \d+?$ + srcip + + + + + + + + + + + groupdel + ^group deleted: name=(\S+)$ + extra_data + + + + + + ^portsentry + + + + portsentry + attackalert: Connect from host: + (\S+)/\S+ to (\S+) port: (\d+?)$ + srcip,protocol,dstport + + + + portsentry + is already blocked\. Ignoring$ + Host: (\S+) is + srcip + + + + + + ^clamd + + + + ^freshclam + + + + + + ^slapd + + + + + openldap + ACCEPT + ^conn=(\d+) fd=\d+ ACCEPT from IP=(\S+): + id, srcip + + + + + openldap + BIND + ^conn=(\d+) op=\d+ BIND dn="[A-Za-z0-9@_-]+=([A-Za-z0-9@_-]+), + id, dstuser + + + + + + openldap + RESULT + ^conn=(\d+) op=\d+ RESULT + id + + + + + ^ntpd + + + + ntpd + ^bad peer + ^bad peer \S+ \((\S+)\)$|^bad peer from pool \S+ \((\S+)\)$ + srcip + + + + ntpd + ^recvmsg (\S+): + dstip + + + +type=USER_ACCT msg=audit(1310592861.936:1222): user pid=24675 uid=0 auid=501 ses=188 subj=system_u:system_r:unconfined_t:s0 msg='op=PAM:accounting acct="username" exe="/usr/bin/sudo" (hostname=?, addr=?, terminal=pts/5 res=success)' +type=CRED_ACQ msg=audit(1305666154.831:51859): user pid=21250 uid=0 auid=4294967295 subj=system_u:system_r:unconfined_t:s0-s0:c0.c1023 msg='PAM: setcred acct="username" : exe="/usr/sbin/sshd" (hostname=lala.example.com, addr=172.16.0.1, terminal=ssh res=success)' +type=CRED_ACQ msg=audit(1273182001.226:148635): user pid=29770 uid=0 auid=4294967295 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: setcred acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron +type=USER_AUTH msg=audit(1305666163.690:51871): user pid=21269 uid=0 auid=500 subj=user_u:system_r:unconfined_t:s0 msg='PAM: authentication acct="root" : exe="/bin/su" (hostname=?, addr=?, terminal=pts/0 res=success)' +type=USER_ACCT msg=audit(1306939201.750:67934): user pid=4401 uid=0 auid=4294967295 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: accounting acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron res=success)' +type=CRED_ACQ msg=audit(1306939201.751:67935): user pid=4401 uid=0 auid=4294967295 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: setcred acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron res=success)' +type=USER_START msg=audit(1306939201.756:67937): user pid=4401 uid=0 auid=0 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: session open acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron res=success)' +type=USER_CHAUTHTOK msg=audit(1304523288.952:37394): user pid=7258 uid=0 auid=500 subj=user_u:system_r:unconfined_t:s0 msg='op=change password id=505 exe="/usr/bin/passwd" (hostname=?, addr=?, terminal=pts/1 res=success)' + + +type=USER_ACCT msg=audit(1310592861.936:1222): user pid=24675 uid=0 auid=501 ses=188 subj=system_u:system_r:unconfined_t:s0 msg='op=PAM:accounting acct="username" exe="/usr/bin/sudo" (hostname=?, addr=?, terminal=pts/5 res=success)' + + +type=SYSCALL msg=audit(1307045440.943:148): arch=c000003e syscall=59 success=yes exit=0 a0=de1fa8 a1=de23a8 a2=dc3008 a3=7fff1db3cc60 items=2 ppid=11719 pid=12140 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="wget" exe="/tmp/wget" key="webserver-watch-tmp" +type=SYSCALL msg=audit(1307045820.403:151): arch=c000003e syscall=59 success=no exit=-13 a0=de24c8 a1=de2408 a2=dc3008 a3=7fff1db3cc60 items=1 ppid=11719 pid=12347 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="bash" exe="/bin/bash" key=(null) +type=SYSCALL msg=audit(1306939143.715:67933): arch=40000003 syscall=94 success=yes exit=0 a0=5 a1=180 a2=8ebd360 a3=8ec4978 items=1 ppid=4383 pid=4388 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=8038 comm="less" exe="/usr/bin/less" subj=user_u:system_r:unconfined_t:s0 key="perm_mod" +type=USER_ROLE_CHANGE msg=audit(1280266360.845:51): user pid=1978 uid=0 auid=500 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='pam: default-context=user_u:system_r:unconfined_t:s0 selected-context=user_u:system_r:unconfined_t:s0: exe="/bin/login" (hostname=?, addr=?, terminal=tty1 res=success)' +type=PATH msg=audit(1306967989.163:119): item=0 name="./ls" inode=261813 dev=fb:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 + + +type=PATH msg=audit(1273924468.947:179534): item=0 name=(null) inode=424783 dev=fd:07 mode=0100640 ouid=0 ogid=502 rdev=00:00 obj=user_u:object_r:file_t:s0 + +--> + + + ^type= + + + + + auditd + ^AVC + ^(AVC) msg=audit\(\d{10}\.\d{3}:(\d+?)\): avc: (\S+) \{ .+ \} for pid=\d+? comm="(\S+)" path="\S+" dev=\S+ ino=\d+? scontext=\S+ tcontext=\S+ tclass=\S+$ + action,id,status,extra_data + + + + + auditd + ^SYSCALL + ^(SYSCALL) msg=audit\(\d{10}\.\d{3}:(\d+?)\): arch=\w+ syscall=\d+ success=(\S+) exit=\S+ a0=\w+ a1=\w+ a2=\w+ a3=\w+ items=\d+ ppid=\d+ pid=\d+ auid=\d+ uid=\d+ gid=\d+ euid=\d+ suid=\d+ fsuid=\d+ egid=\d+ sgid=\d+ fsgid=\d+ tty=\S+ ses=\d+ comm="\S+" exe="(.+?)" + action,id,status,extra_data + + + + + auditd + ^CONFIG_CHANGE + ^(CONFIG_CHANGE) msg=audit\(\d{10}\.\d{3}:(\d+?)\): auid=\d+? ses=\d+? op=".+" path="(.+)" key="\S+" list=\d+? res=\d+?$ + action,id,extra_data + + + + + auditd + ^PATH + ^(PATH) msg=audit\(\d{10}\.\d{2}:(\d+?)\): item=\d+? name="(.+)" inode=\d+? dev=\S+ mode=\d+? ouid=\d+? ogid=\d+? rdev=\S+ + action,id,extra_data + + + + + auditd + ^(USER_\S+) msg=audit\(\d{10}\.\d{3}:(\d+?)\): user pid=\d+? uid=\d+? auid=\d+| + ^(CRED_\S+) msg=audit\(\d{10}\.\d{3}:(\d+?)\): user pid=\d+? uid=\d+? auid=\d+ + action,id + + + + auditd + acct="(.+)" : exe="(.+)" \(hostname=\S+, addr=(\S+), terminal=\S+$ + user,extra_data,srcip + + + + auditd + ses=\d+? subj=\S+ msg='.+ acct="(.+)" exe="(.+)" hostname=\S+ addr=(\S+) terminal=\S+ res=(\S+)$ + user,extra_data,srcip,status + + + + auditd + subj=\S+ msg='.+ acct="(.+)" :*[ ]*?exe="(.+)" \(hostname=\S+, addr=(\S+), terminal=\S+ res=(\S+)\)'$ + user,extra_data,srcip,status + + + + auditd + subj=\S+ msg='.+ exe="(.+)" \(hostname=\S+, addr=(\S+), terminal=\S+ res=(\S+)\)'$ + extra_data,srcip,status + + + + + iptables + ^\[ \d+\.\d+\] mptscsih: + ^\[ \d+\.\d+\] (\w+): (\w+): task abort: (\w+) + id,data,status + + + + iptables + ^\[ \d+\.\d+\] mptbase: + ^\[ \d+\.\d+\] (\w+): (\w+):[ ]+[A-Za-z0-9@_-]+ is now (\w+), (\D+)$ + id,data,action,status + + + + + + + + ^HT286: \[\w\w:\w\w:\w\w:\w\w:\w\w:\w\w\][()*+,.:;\<=>?\[\]!"'#%&$|{}-]*?.+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]* | + ^HT502: \[\w\w:\w\w:\w\w:\w\w:\w\w:\w\w\][()*+,.:;\<=>?\[\]!"'#%&$|{}-]*?.+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]* | + ^HT503: \[\w\w:\w\w:\w\w:\w\w:\w\w:\w\w\][()*+,.:;\<=>?\[\]!"'#%&$|{}-]*?.+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]* + + + + grandstream-ata + Received + ^(\d+) response for transaction (\d+?)\(([A-Za-z0-9@_-]+)\)$ + status, id, action + + + + grandstream-ata + Account + ^(\d+) (registered), tried \d+; Next registration in \d+ seconds \(\d+/\d+\) on (.+)$ + id, status, extra_data + name, location, extra_data + + + + grandstream-ata + Vinetic:: + ^(startRing) with CID, Attempting to deliver CID (\d+) on port \d+$ + action, id + + + + grandstream-ata + ^(Dialing) (\d+)$ + action, id + + + + + + + iptables + apparmor= + apparmor="(\S+)" operation="(\S+)" + status, extra_data + + + + + ^unix_chkpwd + + + + + unix_chkpwd + user \(([A-Za-z0-9@_-]+)\)$ + srcuser + + + + + + ^inbound/pass|^scan|^outbound/smtp + + + + barracuda-svf-email + ^\S+\[\S+\]| + ^\S+ + ^\S+\[(\S+)\] (\d+-[A-Za-z0-9@_-]+?-[A-Za-z0-9@_-]+) \d+ \d+ | + ^(\S+) (\d+-[A-Za-z0-9@_-]+?-[A-Za-z0-9@_-]+) \d+ \d+ + srcip, id + + + + + barracuda-svf-email + (SCAN) (\S+ \S+ \S+ \S+ \d+ \d+ .+ SUBJ:.+)$ + action, extra_data + + + + + barracuda-svf-email + (RECV) (\S+ \S+ \d+ \d+ .+)$ + action, extra_data + + + + + barracuda-svf-email + (SEND) (\S+ \d+ \S+ .+)$ + action, extra_data + + + + + + ^web + + + + barracuda-svf-admin + ^\[\S+\] global\[\] CHANGE + ^\[(\S+)\] global\[\] (CHANGE) (\S+ \(\S*)\)$ + srcip,action,extra_data + + + + barracuda-svf-admin + ^\[\S+\] LOGIN| + ^\[\S+\] FAILED_LOGIN| + ^\[\S+\] LOGOUT + ^\[(\S+)\] (\S+) \((\S+)\)[()*+,.:;\<=>?\[\]!"'#%&$|{}-]*$ + srcip,action,user + + + + + + +windows +INFORMATION\(1\) +Image: (.*?) [ ]*?CommandLine: .*? [ ]*?User: (.*?) [ ]*?LogonGuid: \S*? [ ]*?LogonId: \S*? [ ]*?TerminalSessionId: \S*? [ ]*?IntegrityLevel: .*?HashType: \S*? [ ]*?Hash: (\S*?) [ ]*?ParentProcessGuid: \S*? [ ]*?ParentProcessID: \S*? [ ]*?ParentImage: (.*?) [ ]*?ParentCommandLine: +status,user,url,data + + + + + squid + ^\d+? \S+ + ^\d+? (\S+) ([A-Za-z0-9@_-]+?)/(\d+?) \d+? [A-Za-z0-9@_-]+? (\S+) + srcip,action,id,url + + + + + + + ^unbound + + + + unbound + info: (\S+) (\S+)\. A IN$| info: (\S+) (\S+) AAAA IN$ + srcip,url + + + + + ^doas + + + + doas + ^(\S+) ran| for (\S+): + srcuser + + + + doas + as (\S+): + dstuser + + + + + + windows-date-format + authenticator failed + \[(\S+)\]:\d+: \d+ Incorrect authentication data \(set_id=([A-Za-z0-9@_-]+?)\) + srcip,user + + + + windows-date-format + ^SMTP connection from + \[(\S+)\]:\d+ \(TCP/IP connection count + srcip + + + + windows-date-format + ^SMTP connection from + \[(\S+)\]:\d+ lost + srcip + + + + windows-date-format + ^SMTP call from + \[(\S+)\]:\d+ dropped: too many syntax or protocol errors + srcip + + + + + + ^nsd + + + + nsd + from (\S+)@| from (\S+) + srcip + + + + + + ^\{"reqId":"\S+","message":".+","level":\d,"time":".+"\}$|^\{"app":"\S+","message":".+","level":\d,"time":".+"\}$|^\{"reqId":"\S+","level":\d,"time":"\S+","message":".+"\}$ + + + + + ^ownCloud + + + + owncloud + Login failed: user + ^'([A-Za-z0-9@_-]+)' , wrong password, IP:(\S+) + + user, srcip + + + + owncloud + + Login failed: + ^'([A-Za-z0-9@_-]+)' \(Remote IP: '(\S+)'|^'([A-Za-z0-9@_-]+)' \(Remote IP: '(\S+)\) + user, srcip + + + + owncloud + + Passed filename is not valid, might be malicious + ;ip:"(\S+)"|;ip:\\"(\S+)\\" + + srcip + + + + owncloud + ","level": + ^(\d)," + status + + + + + + psad + + + + psad + ^scan detected + (\S+) -> (\S+) .+ DL: (\d) + srcip,dstip,status + + + + psad + ^message repeated + (\S+) -> (\S+) .+ DL: (\d) + srcip,dstip,status + + + + psad + signature match: + src: (\S+) signature match: .+ port: (\d+) + srcip,dstport + + + + + + ^pvedaemon + + + + ^pvestatd + + + + ^pveproxy + + + + ^pvepw-logger + + + + pvedaemon + authentication failure; + ^rhost=(\S+) user=(\S+)@pam msg=|^rhost=(\S+) user=(\S+)@pve msg= + srcip, user + + + + pvedaemon + successful auth for user ' + ^(\S+)@pam'$|^(\S+)@pve'$ + user + + + + ^dhcpd$ + + + + dhcpd + ^(\S+) \S+ (\S+) \S+ (\S+) via (\S+)$ + action, srcip, extra_data, extra_data + + + + dhcpd + acking + already acking lease (\S+) + srcip + + + + dhcpd + ^IP address + ^IP address (\S+) + srcip + + + + + \[\d+/[A-Za-z0-9@_-]+/\d+:\d+:\d+:\d+ -\d+\] " + ^(\S+) (\S+) \S+ \S+ \[\d+/[A-Za-z0-9@_-]+/\d+:\d+:\d+:\d+ -\d+\] "(\S+) (\S+) HTTP/\d\.\d" (\d+?) \d$ + url, srcip, protocol, url, status + web-log + + + + + + ^dnsmasq + + + + dnsmasq + ^\[\d+\]: \d+ (\S+)/\d+ (\S+) (\S+) to (\S+)| + ^\[\d+\]: \d+ (\S+)/\d+ (\S+) (\S+) from (\S+)| + ^\[\d+\]: \d+ (\S+)/\d+ (\S+) (\S+) is (\S+) + srcip, action, url, extra_data + + + + + + + + + + + + + + + + ^kesl + + + + kesl + ^""EventType": "\S+","EventId": "\d+?","TaskName": "\S+","TaskId": "\d+?","AVBasesDate": "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"" + ^""EventType": "(\S+)","EventId": "(\d+?)","TaskName": "(\S+)","TaskId": "\d+?","AVBasesDate": "(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})"" + status, id, action, extra_data + + + + kesl + ^""EventType": "\S+","EventID": "\d+","DetectName": "\S+","DetectType": "\S+","DetectCertainty": "\S+","DetectSource": "\S+","FileName": "\S+,"ObjectName": "\S+","TaskId": "\d+?","RuntimeTaskId": "\d+","TaskName": "\S+","TaskType": "\S+","AccessUser": "\S+","AccessUserId": "\d+","FileOwner": "\S+","FileOwnerId": "\d+"" + ^""EventType": "(\S+)","EventID": "(\d+)","DetectName": "\S+","DetectType": "\S+","DetectCertainty": "(\S+)","DetectSource": "\S+","FileName": \S+,"ObjectName": "\S+","TaskId": "\d+","RuntimeTaskId": "\d+?","TaskName": "\S+","TaskType": "(\S+)","AccessUser": "\S+","AccessUserId": "\d+?","FileOwner": "\S+","FileOwnerId": "\d+"" + status, id, extra_data, action + + + + kesl + ^""EventType": "\S+","EventId": "\d+","TaskName": "\S+","TaskType": "\S+","TaskId": "\d+","TaskState": "\S+","PrevTaskState": "\S+","TaskRequestInitiator": "\S+","RuntimeTaskId": "\d+"" + ^""EventType": "(\S+)","EventId": "(\d+)","TaskName": "\S+","TaskType": "(\S+)","TaskId": "\d+","TaskState": "(\S+)","PrevTaskState": "\S+","TaskRequestInitiator": "(\S+)","RuntimeTaskId": "\d+"" + action, id, extra_data, status, srcuser + + + + + + + dionaea\.connections + ^\{"direction": "(\S+)", "protocol": "(\S+)", "ids_type": "\S+", "timestamp": "\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}.\d+", "dionaea_action": "(\S+)", "type": "dionaea\.connections", "app": "dionaea", "src_ip": "(\S+)", "vendor_product": "Dionaea", "dest_port": (\d+), "signature": ".+", "src_port": (\d+?), "dest_ip": "(\S+)", "sensor": \S+, "transport": "\S+", "severity": "\S+"\} + extra_data, protocol, action, srcip, dstport, srcport, dstip + + + + + + + + + + cowrie\.sessions + + + + cowrie + "SSH login attempted + ^\{"direction": "\S+", "protocol": "(\S+)", "ids_type": "(\S+)", "ssh_username": "(\S+)", "app": "cowrie", "transport": "\S+", "dest_port": (\d+), "src_port": (\d+), "severity": "\S+", "timestamp": "\d{4}-\d{2}-\d{2}", "vendor_product": "Cowrie", "sensor": \S+, "src_ip": "(\S+)", "ssh_password": "\S+", "signature": "(.+)", "ssh_version": .+, "type": "cowrie\.sessions", "dest_ip": "(\S+)"\} + protocol, extra_data, user, dstport, srcport, srcip, action, dstip + + + + cowrie + "SSH session on cowrie honeypot + ^\{"direction": "\S+", "protocol": "(\S+)", "ids_type": "(\S+)", "timestamp": "\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}.\d+", "vendor_product": "Cowrie", "type": "cowrie\.sessions", "app": "cowrie", "src_ip": "(\S+)", "dest_port": (\d+?), "signature": "(.+)", "ssh_version": .+, "src_port": (\d+?), "dest_ip": "(\S+)", "sensor": \S+, "transport": "\S+", "severity": "\S+"\} + protocol, extra_data, srcip, dstport, action, srcport, dstip + + + + cowrie + "command attempted on cowrie honeypot + ^\{"direction": "\S+", "protocol": "(\S+)", "ids_type": "(\S+)", "timestamp": "\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}.\d+", "app": "cowrie", "transport": "\S+", "dest_port": (\d+?), "src_port": (\d+?), "severity": "\S+", "vendor_product": "Cowrie", "sensor": \S+, "src_ip": "(\S+)", "command": "\S+", "signature": "(.+)", "ssh_version": .+, "type": "cowrie\.sessions", "dest_ip": "(\S+)"\} + protocol, extra_data, dstport, srcport, srcip, action, dstip + + + diff --git a/etc/internal_options.conf b/etc/internal_options.conf new file mode 100644 index 000000000..009debdb9 --- /dev/null +++ b/etc/internal_options.conf @@ -0,0 +1,130 @@ +# internal_options.conf, Daniel B. Cid (dcid @ theopenarmor.org). +# +# DO NOT TOUCH THIS FILE. The default configuration +# is at openarmor.conf. More information at: +# http://www.theopenarmor.org/docs/ +# +# This file should be handled with care. It contain +# run time modifications that can affect the use +# of openarmor. Only change it if you know what you +# are doing. Again, look first at openarmor.conf +# for most of the things you want to change. + + +# Analysisd default rule timeframe. +analysisd.default_timeframe=360 +# Analysisd stats maximum diff. +analysisd.stats_maxdiff=999000 +# Analysisd stats minimum diff. +analysisd.stats_mindiff=1250 +# Analysisd stats percentage (how much to differ from average) +analysisd.stats_percent_diff=150 +# Analysisd FTS list size. +analysisd.fts_list_size=32 +# Analysisd FTS minimum string size. +analysisd.fts_min_size_for_str=14 +# Analysisd Enable the firewall log (at logs/firewall/firewall.log) +# 1 to enable, 0 to disable. +analysisd.log_fw=1 +# Maximum number of fields in a decoder (order tag) +analysisd.decoder_order_size=10 + + +# Output GeoIP data at JSON alerts +analysisd.geoip_jsonout=0 + +# Logcollector file loop timeout (check every 2 seconds for file changes) +logcollector.loop_timeout=2 + +# Logcollector number of attempts to open a log file. +logcollector.open_attempts=8 + +# Logcollector - If it should accept remote commands from the manager +logcollector.remote_commands=0 + + + +# Remoted counter io flush. +remoted.recv_counter_flush=128 + +# Remoted compression averages printout. +remoted.comp_average_printout=19999 + +# Verify msg id (set to 0 to disable it) +remoted.verify_msg_id=1 + +# Don't exit when client.keys empty +remoted.pass_empty_keyfile=0 + +# Maild strict checking (0=disabled, 1=enabled) +maild.strict_checking=1 + +# Maild grouping (0=disabled, 1=enabled) +# Groups alerts within the same e-mail. +maild.groupping=1 + +# Maild full subject (0=disabled, 1=enabled) +maild.full_subject=0 + +# Maild display GeoIP data (0=disabled, 1=enabled) +maild.geoip=1 + + +# Monitord day_wait. Amount of seconds to wait before compressing/signing +# the files. +monitord.day_wait=10 + +# Monitord compress. (0=do not compress, 1=compress) +monitord.compress=1 + +# Monitord sign. (0=do not sign, 1=sign) +monitord.sign=1 + +# Monitord monitor_agents. (0=do not monitor, 1=monitor) +monitord.monitor_agents=1 + +# Monitord notify_time. Frequency of which the clients' availability needs +# to be checked. (60-3600) +monitord.notify_time=600 + +# Syscheck checking/usage speed. To avoid large cpu/memory +# usage, you can specify how much to sleep after generating +# the checksum of X files. The default is to sleep 2 seconds +# after reading 15 files. +syscheck.sleep=2 +syscheck.sleep_after=15 + +# Rootcheck checking/usage speed. Rootcheck will pause for this +# duration after scanning a PID or port. +rootcheck.sleep=2 + + +# Database - maximum number of reconnect attempts +dbd.reconnect_attempts=10 + + +# Debug options. +# Debug 0 -> no debug +# Debug 1 -> first level of debug +# Debug 2 -> full debugging + +# Windows debug (used by the windows agent) +windows.debug=0 + +# Syscheck (local, server and unix agent) +syscheck.debug=0 + +# Remoted (server debug) +remoted.debug=0 + +# Analysisd (server or local) +analysisd.debug=0 + +# Log collector (server, local or unix agent) +logcollector.debug=0 + +# Unix agentd +agent.debug=0 + + +# EOF diff --git a/etc/local_internal_options-win.conf b/etc/local_internal_options-win.conf new file mode 100644 index 000000000..4b90d0e19 --- /dev/null +++ b/etc/local_internal_options-win.conf @@ -0,0 +1,10 @@ +# local_internal_options.conf +# +# This file should be handled with care. It contains +# run time modifications that can affect the use +# of openarmor. Only change it if you know what you +# are doing. Look first at openarmor.conf +# for most of the things you want to change. +# +# This file will not be overwritten during upgrades +# but will be removed when the agent is un-installed. diff --git a/etc/local_internal_options.conf b/etc/local_internal_options.conf new file mode 100644 index 000000000..48c2f3320 --- /dev/null +++ b/etc/local_internal_options.conf @@ -0,0 +1,9 @@ +# local_internal_options.conf +# +# This file should be handled with care. It contains +# run time modifications that can affect the use +# of openarmor. Only change it if you know what you +# are doing. Look first at openarmor.conf +# for most of the things you want to change. +# +# This file will not be overwritten during upgrades. diff --git a/etc/openarmor-agent.conf b/etc/openarmor-agent.conf new file mode 100644 index 000000000..5dc68c25c --- /dev/null +++ b/etc/openarmor-agent.conf @@ -0,0 +1,73 @@ + + + + + 192.168.10.100 + + + + + 7200 + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/random.seed + /etc/adjtime + /etc/httpd/logs + + + /etc/ssl/private.key + + + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt + + + + syslog + /var/log/messages + + + + syslog + /var/log/authlog + + + + syslog + /var/log/auth.log + + + + syslog + /var/log/secure + + + + syslog + /var/log/xferlog + + + + syslog + /var/log/maillog + + + + apache + /var/www/logs/access_log + + + + apache + /var/www/logs/error_log + + diff --git a/etc/openarmor-local.conf b/etc/openarmor-local.conf new file mode 100644 index 000000000..4bb990b2c --- /dev/null +++ b/etc/openarmor-local.conf @@ -0,0 +1,208 @@ + + + + + yes + daniel.cid@example.com + smtp.example.com. + openarmorm@openarmor.example.com. + + + + rules_config.xml + pam_rules.xml + sshd_rules.xml + telnetd_rules.xml + syslog_rules.xml + arpwatch_rules.xml + symantec-av_rules.xml + symantec-ws_rules.xml + pix_rules.xml + named_rules.xml + smbd_rules.xml + vsftpd_rules.xml + pure-ftpd_rules.xml + proftpd_rules.xml + ms_ftpd_rules.xml + ftpd_rules.xml + hordeimp_rules.xml + roundcube_rules.xml + wordpress_rules.xml + cimserver_rules.xml + vpopmail_rules.xml + vmpop3d_rules.xml + courier_rules.xml + web_rules.xml + web_appsec_rules.xml + apache_rules.xml + nginx_rules.xml + php_rules.xml + mysql_rules.xml + postgresql_rules.xml + ids_rules.xml + squid_rules.xml + firewall_rules.xml + apparmor_rules.xml + cisco-ios_rules.xml + netscreenfw_rules.xml + sonicwall_rules.xml + postfix_rules.xml + sendmail_rules.xml + imapd_rules.xml + mailscanner_rules.xml + dovecot_rules.xml + ms-exchange_rules.xml + racoon_rules.xml + vpn_concentrator_rules.xml + spamd_rules.xml + msauth_rules.xml + mcafee_av_rules.xml + trend-osce_rules.xml + ms-se_rules.xml + + zeus_rules.xml + solaris_bsm_rules.xml + vmware_rules.xml + ms_dhcp_rules.xml + asterisk_rules.xml + openarmor_rules.xml + attack_rules.xml + systemd_rules.xml + firewalld_rules.xml + dropbear_rules.xml + unbound_rules.xml + sysmon_rules.xml + opensmtpd_rules.xml + exim_rules.xml + openbsd-dhcpd_rules.xml + dnsmasq_rules.xml + local_rules.xml + + + + + 17200 + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/random.seed + /etc/adjtime + /etc/httpd/logs + + + /etc/ssl/private.key + + + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt + + + + 127.0.0.1 + 192.168.2.1 + 192.168.2.190 + 192.168.2.32 + 192.168.2.10 + + + + 1 + 7 + + + + host-deny + host-deny.sh + srcip + yes + + + + firewall-drop + firewall-drop.sh + srcip + yes + + + + disable-account + disable-account.sh + user + yes + + + + + + + host-deny + local + 7 + 600 + + + + + firewall-drop + local + 7 + 600 + + + + + + syslog + /var/log/messages + + + + syslog + /var/log/authlog + + + + syslog + /var/log/auth.log + + + + syslog + /var/log/secure + + + + syslog + /var/log/xferlog + + + + syslog + /var/log/maillog + + + + apache + /var/www/logs/access_log + + + + apache + /var/www/logs/error_log + + diff --git a/etc/openarmor-server.conf b/etc/openarmor-server.conf new file mode 100644 index 000000000..e22151572 --- /dev/null +++ b/etc/openarmor-server.conf @@ -0,0 +1,218 @@ + + + + + yes + daniel.cid@example.com + smtp.example.com. + openarmorm@openarmor.example.com. + + + + rules_config.xml + pam_rules.xml + sshd_rules.xml + telnetd_rules.xml + syslog_rules.xml + arpwatch_rules.xml + symantec-av_rules.xml + symantec-ws_rules.xml + pix_rules.xml + named_rules.xml + smbd_rules.xml + vsftpd_rules.xml + pure-ftpd_rules.xml + proftpd_rules.xml + ms_ftpd_rules.xml + ftpd_rules.xml + hordeimp_rules.xml + roundcube_rules.xml + wordpress_rules.xml + cimserver_rules.xml + vpopmail_rules.xml + vmpop3d_rules.xml + courier_rules.xml + web_rules.xml + web_appsec_rules.xml + apache_rules.xml + nginx_rules.xml + php_rules.xml + mysql_rules.xml + postgresql_rules.xml + ids_rules.xml + squid_rules.xml + firewall_rules.xml + apparmor_rules.xml + cisco-ios_rules.xml + netscreenfw_rules.xml + sonicwall_rules.xml + postfix_rules.xml + sendmail_rules.xml + imapd_rules.xml + mailscanner_rules.xml + dovecot_rules.xml + ms-exchange_rules.xml + racoon_rules.xml + vpn_concentrator_rules.xml + spamd_rules.xml + msauth_rules.xml + mcafee_av_rules.xml + trend-osce_rules.xml + ms-se_rules.xml + + zeus_rules.xml + solaris_bsm_rules.xml + vmware_rules.xml + ms_dhcp_rules.xml + asterisk_rules.xml + openarmor_rules.xml + attack_rules.xml + dropbear_rules.xml + unbound_rules.xml + sysmon_rules.xml + opensmtpd_rules.xml + exim_rules.xml + openbsd-dhcpd_rules.xml + dnsmasq_rules.xml + local_rules.xml + + + + + + 72000 + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/random.seed + /etc/adjtime + /etc/httpd/logs + + + /etc/ssl/private.key + + + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt + + + + 127.0.0.1 + ::1 + 192.168.2.1 + 192.168.2.190 + 192.168.2.32 + 192.168.2.10 + + + + secure + + + + 1 + 7 + + + + host-deny + host-deny.sh + srcip + yes + + + + firewall-drop + firewall-drop.sh + srcip + yes + + + + disable-account + disable-account.sh + user + yes + + + + + + + host-deny + local + 7 + 600 + + + + + firewall-drop + local + 7 + 600 + + + + + + syslog + /var/log/messages + + + + syslog + /var/log/authlog + + + + syslog + /var/log/auth.log + + + + syslog + /var/log/secure + + + + syslog + /var/log/xferlog + + + + syslog + /var/log/maillog + + + + apache + /var/www/logs/access_log + + + + apache + /var/www/logs/error_log + + + + syslog + /var/log/exim_mainlog + + + diff --git a/etc/openarmor.conf b/etc/openarmor.conf new file mode 100644 index 000000000..3a38d413e --- /dev/null +++ b/etc/openarmor.conf @@ -0,0 +1,189 @@ + + + + + yes + daniel.cid@example.com + smtp.example.com. + openarmorm@openarmor.example.com. + + + + + rules_config.xml + sshd_rules.xml + syslog_rules.xml + pix_rules.xml + named_rules.xml + pure-ftpd_rules.xml + proftpd_rules.xml + web_rules.xml + web_appsec_rules.xml + apache_rules.xml + ids_rules.xml + squid_rules.xml + firewall_rules.xml + postfix_rules.xml + sendmail_rules.xml + spamd_rules.xml + msauth_rules.xml + attack_rules.xml + dropbear_rules.xml + sysmon_rules.xml + opensmtpd_rules.xml + openbsd-dhcpd_rules.xml + nsd_rules.xml + unbound_rules.xml + + + + + 7200 + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/random.seed + /etc/adjtime + /etc/httpd/logs + + + /etc/ssl/private.key + + + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt + + + + 127.0.0.1 + ::1 + 192.168.2.1 + 192.168.2.190 + 192.168.2.32 + 192.168.2.10 + + + + secure + + + + 1 + 7 + + + + host-deny + host-deny.sh + srcip + yes + + + + firewall-drop + firewall-drop.sh + srcip + yes + + + + disable-account + disable-account.sh + user + yes + + + + + + + host-deny + local + 6 + 600 + + + + + firewall-drop + local + 6 + 600 + + + + + + + + + + syslog + /var/log/messages + + + + syslog + /var/log/authlog + + + + syslog + /var/log/auth.log + + + + syslog + /var/log/secure + + + + syslog + /var/log/xferlog + + + + syslog + /var/log/maillog + + + + apache + /var/www/logs/access_log + + + + apache + /var/www/logs/error_log + + diff --git a/etc/preloaded-vars.conf.example b/etc/preloaded-vars.conf.example new file mode 100644 index 000000000..31fddeffd --- /dev/null +++ b/etc/preloaded-vars.conf.example @@ -0,0 +1,127 @@ +# preloaded-vars.conf, Daniel B. Cid (dcid @ theopenarmor.org). +# +# Use this file to customize your installations. +# It will make the install.sh script pre-load some +# specific options to make it run automatically +# or with less questions. + +# PLEASE NOTE: +# When we use "n" or "y" in here, it should be changed +# to "n" or "y" in the language your are doing the +# installation. For example, in portuguese it would +# be "s" or "n". + + +# USER_LANGUAGE defines to language to be used. +# It can be "en", "br", "tr", "it", "de" or "pl". +# In case of an invalid language, it will default +# to English "en" +#USER_LANGUAGE="en" # For english +#USER_LANGUAGE="br" # For portuguese + + +# If USER_NO_STOP is set to anything, the confirmation +# messages are not going to be asked. +#USER_NO_STOP="y" + + +# USER_INSTALL_TYPE defines the installation type to +# be used during install. It can only be "local", +# "agent" or "server". +#USER_INSTALL_TYPE="local" +#USER_INSTALL_TYPE="agent" +#USER_INSTALL_TYPE="server" + + +# USER_DIR defines the location to install openarmor +#USER_DIR="/var/openarmor" + + +# If USER_DELETE_DIR is set to "y", the directory +# to install openarmor will be removed if present. +#USER_DELETE_DIR="y" + + +# If USER_ENABLE_ACTIVE_RESPONSE is set to "n", +# active response will be disabled. +#USER_ENABLE_ACTIVE_RESPONSE="y" + + +# If USER_ENABLE_SYSCHECK is set to "y", +# syscheck will be enabled. Set to "n" to +# disable it. +#USER_ENABLE_SYSCHECK="y" + + +# If USER_ENABLE_ROOTCHECK is set to "y", +# rootcheck will be enabled. Set to "n" to +# disable it. +#USER_ENABLE_ROOTCHECK="y" + + +# If USER_UPDATE is set to anything, the update +# installation will be done. +#USER_UPDATE="y" + +# If USER_UPDATE_RULES is set to anything, the +# rules will also be updated. +#USER_UPDATE_RULES="y" + +# If USER_BINARYINSTALL is set, the installation +# is not going to compile the code, but use the +# binaries from ./bin/ +#USER_BINARYINSTALL="x" + + +### Agent Installation variables. ### + +# Specifies the IP address or hostname of the +# openarmor server. Only used on agent installations. +# Choose only one, not both. +# USER_AGENT_SERVER_IP="1.2.3.4" +# USER_AGENT_SERVER_NAME + + +# USER_AGENT_CONFIG_PROFILE specifies the agent's config profile +# name. This is used to create agent.conf configuration profiles +# for this particular profile name. Only used on agent installations. +# Can be any string. E.g. LinuxDBServer or WindowsDomainController +#USER_AGENT_CONFIG_PROFILE="generic" + + + +### Server/Local Installation variables. ### + +# USER_ENABLE_EMAIL enables or disables email alerting. +#USER_ENABLE_EMAIL="y" + +# USER_EMAIL_ADDRESS defines the destination e-mail of the alerts. +#USER_EMAIL_ADDRESS="dcid@test.theopenarmor.org" + +# USER_EMAIL_SMTP defines the SMTP server to send the e-mails. +#USER_EMAIL_SMTP="test.theopenarmor.org" + + +# USER_ENABLE_SYSLOG enables or disables remote syslog. +#USER_ENABLE_SYSLOG="y" + + +# USER_ENABLE_FIREWALL_RESPONSE enables or disables +# the firewall response. +#USER_ENABLE_FIREWALL_RESPONSE="y" + + +# Enable PF firewall (OpenBSD, FreeBSD and Darwin only) +#USER_ENABLE_PF="y" + + +# PF table to use (OpenBSD, FreeBSD and Darwin only). +#USER_PF_TABLE="openarmor_fwtable" + + +# USER_WHITE_LIST is a list of IPs or networks +# that are going to be set to never be blocked. +#USER_WHITE_LIST="192.168.2.1 192.168.1.0/24" + + +#### exit ? ### diff --git a/etc/rules/apache_rules.xml b/etc/rules/apache_rules.xml new file mode 100644 index 000000000..0d0fadaf4 --- /dev/null +++ b/etc/rules/apache_rules.xml @@ -0,0 +1,325 @@ + + + + + + apache-errorlog + Apache messages grouped. + + + + 30100 + ^\[error\] + Apache error messages grouped. + + + + 30100 + ^\[warn\] + Apache warn messages grouped. + + + + 30100 + ^\[notice\] + Apache notice messages grouped. + + + + 30103 + exit signal Segmentation Fault + Apache segmentation fault. + http://www.securityfocus.com/infocus/1633 + service_availability, + + + + 30101 + denied by server configuration + Attempt to access forbidden file or directory. + access_denied, + + + + 30101 + Directory index forbidden by rule + Attempt to access forbidden directory index. + access_denied, + + + + 30101 + Client sent malformed Host header + Code Red attack. + http://www.cert.org/advisories/CA-2001-19.html + CERT: Advisory CA-2001-19 "Code Red" Worm Exploiting Buffer Overflow In IIS Indexing Service DLL + automatic_attack, + + + + 30102 + authentication failed + User authentication failed. + authentication_failed, + + + + 30101 + user \S+ not found|user \S+ in realm .* not found + Attempt to login using a non-existent user. + invalid_login, + + + + 30101 + authentication failure + User authentication failed. + authentication_failed, + + + + 30101 + File does not exist: | + failed to open stream: No such file or directory| + Failed opening + Attempt to access an non-existent file (those are reported on the access.log). + unknown_resource, + + + + + 30101 + Invalid URI in request + Invalid URI (bad client request). + invalid_request, + + + + 30115 + + Multiple Invalid URI requests from + same source. + invalid_request, + + + + 30101 + File name too long|request failed: URI too long + Invalid URI, file name too long. + invalid_request, + + + + + 30101 + mod_security: Access denied|ModSecurity: Access denied + Access attempt blocked by Mod Security. + access_denied, + + + + 30118 + + Multiple attempts blocked by Mod Security. + access_denied, + + + + 30101 + Resource temporarily unavailable: + Apache without resources to run. + service_availability, + + + + ^mod_security-message: + Modsecurity alert. + + + + 30200 + ^mod_security-message: Access denied + Modsecurity access denied. + access_denied, + + + + 30201 + Multiple attempts blocked by Mod Security. + access_denied, + + + + + 30100 + \[\S*:error\] + Apache error messages grouped. + + + + 30100 + \[\S+:warn\] + Apache warn messages grouped. + + + + 30100 + \[\S+:notice\] + Apache notice messages grouped. + + + + 30303 + exit signal Segmentation Fault + Apache segmentation fault. + http://www.securityfocus.com/infocus/1633 + service_availability, + + + + 30301 + AH01630 + Attempt to access forbidden file or directory. + access_denied, + + + + 30301 + AH01276 + Attempt to access forbidden directory index. + access_denied, + + + + 30301 + AH00550 + Client sent malformed Host header. Possible Code Red attack. + http://www.cert.org/advisories/CA-2001-19.html + CERT: Advisory CA-2001-19 "Code Red" Worm Exploiting Buffer Overflow In IIS Indexing Service DLL + automatic_attack, + + + + 30301 + AH01617|AH01807|AH01694|AH01695|AH02009|AH02010 + User authentication failed. + authentication_failed, + + + + 30301 + AH01618|AH01808|AH01790 + Attempt to login using a non-existent user. + invalid_login, + + + + 30309 + + Multiple authentication failures with invalid user. + authentication_failures, + + + + 30301 + File does not exist: | + failed to open stream: No such file or directory| + Failed opening + Attempt to access an non-existent file (those are reported on the access.log). + unknown_resource, + + + + 30301 + AH00126 + Invalid URI (bad client request). + invalid_request, + + + + 30315 + + Multiple Invalid URI requests from + same source. + invalid_request, + + + + 30301 + AH00565 + Invalid URI, file name too long. + invalid_request, + + + + 30301 + PHP Notice: + PHP Notice in Apache log + + + + 30301 + AH00036 + File name too long: + File name too long. + + + + 30301 + Permission denied: | client denied by server configuration: + Permission denied. + + + + 30301 + AH02811 + script not found + A script cannot be accessed. + + + + + 30301 + ModSecurity: Warning + ModSecurity Warning messages grouped + + + + 30301 + ModSecurity: Access denied + ModSecurity Access denied messages grouped + + + + 30301 + ModSecurity: Audit log: + ModSecurity Audit log messages grouped + + + + 30402 + with code 403 + ModSecurity rejected a query + + + + + diff --git a/etc/rules/apparmor_rules.xml b/etc/rules/apparmor_rules.xml new file mode 100644 index 000000000..3e4722195 --- /dev/null +++ b/etc/rules/apparmor_rules.xml @@ -0,0 +1,51 @@ + + + + + + + + + + 5100 + iptables + apparmor= + Apparmor grouping + + + + 52000 + ALLOWED|STATUS + Ignore ALLOWED or STATUS + + + + 52000 + DENIED + apparmor= + Apparmor DENIED + + + + 52002 + exec + Apparmor DENIED exec operation. + + + + 52002 + mknod + Apparmor DENIED mknod operation. + + + + + + diff --git a/etc/rules/arpwatch_rules.xml b/etc/rules/arpwatch_rules.xml new file mode 100644 index 000000000..6a2bb0687 --- /dev/null +++ b/etc/rules/arpwatch_rules.xml @@ -0,0 +1,89 @@ + + + + + + arpwatch + Grouping of the arpwatch rules. + + + + 7200 + alert_by_email + + Arpwatch new host detected. + new_host, + + + + 7200 + flip flop + Arpwatch "flip flop" message. + IP address/MAC relation changing too often. + ip_spoof, + + + + 7200 + reaper: pid + Arpwatch exiting. + service_availability, + + + + 7200 + changed ethernet address + Changed network interface for ip address. + ip_spoof, + + + + 7200 + bad interface eth0|exiting|Running as + Arpwatch startup/exiting messages. + + + + 7200 + sent bad addr len + Arpwatch detected bad address len (ignored). + + + + 7200 + /dev/bpf0: Permission denied + arpwatch probably run with wrong permissions + + + + 7200 + reused old ethernet address + An IP has reverted to an old ethernet address. + + + + 7200 + ethernet mismatch + Possible arpspoofing attempt. + ip_spoof, + + + + + + + + diff --git a/etc/rules/asterisk_rules.xml b/etc/rules/asterisk_rules.xml new file mode 100644 index 000000000..abcf9a3a7 --- /dev/null +++ b/etc/rules/asterisk_rules.xml @@ -0,0 +1,129 @@ + + + + + + + asterisk + Asterisk messages grouped. + + + + 6200 + ^NOTICE + Asterisk notice messages grouped. + + + + 6200 + ^WARN + Asterisk warning message. + + + + 6200 + ^ERROR + Asterisk error message. + + + + 6201 + Wrong password + Login session failed. + authentication_failed, + + + + 6201 + Username/auth name mismatch + Login session failed (invalid user). + invalid_login, + + + + 6201 + No matching peer found + Login session failed (invalid extension). + invalid_login, + + + + 6211 + + Multiple failed logins (user enumeration in process). + + + + 6210 + + Multiple failed logins. + + + + 6212 + + Extension enumeration. + + + + + + 6201 + No registration for peer + Login session failed (invalid iax user). + invalid_login, + + + + + 6253 + + Extension IAX Enumeration. + + + + + 6202 + Don't know how to respond via + Possible Registration Hijacking. + invalid_login, + + + + + 6201 + failed MD5 authentication + IAX peer Wrong Password. + invalid_login, + + + + + 6256 + + Multiple failed logins. + + + + 6201 + No matching peer found|extension not found in context + Login session failed (invalid extension). + invalid_login, + + + + + diff --git a/etc/rules/attack_rules.xml b/etc/rules/attack_rules.xml new file mode 100644 index 000000000..9d97230e4 --- /dev/null +++ b/etc/rules/attack_rules.xml @@ -0,0 +1,122 @@ + + + + +^apache$|^mysql$|^www$|^nobody$|^nogroup$|^portmap$|^named$|^rpc$|^mail$|^ftp$|^shutdown$|^halt$|^daemon$|^bin$|^postfix$|^shell$|^info$|^guest$|^psql$|^user$|^users$|^console$|^uucp$|^lp$|^sync$|^sshd$|^cdrom$|^openarmor$ + + + + + + authentication_success + $SYS_USERS + System user successfully logged to the system. + invalid_login, + + + + ^rpc\.statd\[\d+\]: gethostbyname error for [^A-Za-z0-9@_-]+ + Buffer overflow attack on rpc.statd + exploit_attempt, + + + + ftpd\[\d+\]: \S+ FTP LOGIN FROM .+ 0bin0sh + Buffer overflow on WU-FTPD versions prior to 2.6 + exploit_attempt, + + + + \?{21} + Possible buffer overflow attempt. + exploit_attempt, + + + + changed by \(\(null\) + "Null" user changed some information. + exploit_attempt, + + + + @{25} + Buffer overflow attempt (probably on yppasswd). + exploit_attempt, + + + + cachefsd: Segmentation Fault - core dumped + Heap overflow in the Solaris cachefsd service. + 2002-0033 + exploit_attempt, + + + + attempt to execute code on stack by + Stack overflow attempt or program exiting + with SEGV (Solaris). + http://snap.nlc.dcccd.edu/reference/sysadmin/julian/ch18/389-392.html + exploit_attempt, + + + + authentication_failed + Multiple authentication failures. + authentication_failures, + + + + authentication_success + authentication_failures + + Multiple authentication failures followed + by a success. + + + + virus + Multiple viruses detected - Possible outbreak. + virus, + + + + + + + + + + adduser + attacks + Attacks followed by the addition + of an user. + + + + + + + + + connection_attempt + Network scan from same source ip. + + http://project.honeynet.org/papers/enemy2/ + + + + + diff --git a/etc/rules/cimserver_rules.xml b/etc/rules/cimserver_rules.xml new file mode 100644 index 000000000..54d8ee2eb --- /dev/null +++ b/etc/rules/cimserver_rules.xml @@ -0,0 +1,36 @@ + + + + + cimserver + cimserver messages grouped. + + + + 9600 + Authentication failed + Compaq Insight Manager authentication failure. + authentication_failed, + + + + 9600 + Server stopped + Compaq Insight Manager stopped. + service_availability, + + + + diff --git a/etc/rules/cisco-ios_rules.xml b/etc/rules/cisco-ios_rules.xml new file mode 100644 index 000000000..a70c08d05 --- /dev/null +++ b/etc/rules/cisco-ios_rules.xml @@ -0,0 +1,96 @@ + + + + + + cisco-ios + Grouping of Cisco IOS rules. + + + + 4700 + -0- + Cisco IOS emergency message. + + + + + 4700 + -1- + Cisco IOS alert message. + + + + 4700 + -2- + Cisco IOS critical message. + + + + 4700 + -3- + Cisco IOS error message. + + + + 4700 + -4- + Cisco IOS warning message. + + + + 4700 + -5- + Cisco IOS notification message. + + + + 4700 + -6- + Cisco IOS informational message. + + + + 4700 + -7- + Cisco IOS debug message. + + + + 4715 + ^%SYS-5-CONFIG + Cisco IOS router configuration changed. + config_changed, + + + + 4715 + ^%SEC_LOGIN-5-LOGIN_SUCCESS + Successful login to the router. + authentication_success, + + + + 4714 + ^%SEC_LOGIN-4-LOGIN_FAILED + Failed login to the router. + authentication_failed, + + + + + + diff --git a/etc/rules/clam_av_rules.xml b/etc/rules/clam_av_rules.xml new file mode 100644 index 000000000..ebc8da8f8 --- /dev/null +++ b/etc/rules/clam_av_rules.xml @@ -0,0 +1,69 @@ + + + + + clamd + Grouping of the clamd rules. + + + + freshclam + ClamAV database update + + + + 52500 + FOUND + Virus detected + virus + + + + 52500 + ^ERROR: + Clamd error + virus + + + + 52500 + ^WARNING: + Clamd warning + virus + + + + 52500 + clamd daemon + Clamd restarted + virus + + + + 52500 + Database modification detected + Clamd database updated + virus + + + + 52501 + ClamAV update process started + ClamAV database update + virus + + + + 52501 + Database updated + ClamAV database updated + virus + + + + 52501 + Incremental update failed|Error while reading database from|Update failed\. + Could not download the incremental virus definition updates. + + + diff --git a/etc/rules/courier_rules.xml b/etc/rules/courier_rules.xml new file mode 100644 index 000000000..faed2c505 --- /dev/null +++ b/etc/rules/courier_rules.xml @@ -0,0 +1,67 @@ + + + + + + + courier + Grouping for the courier rules. + + + + 3900 + ^Connection, + New courier (imap/pop3) connection. + connection_attempt, + + + + 3900 + ^LOGIN FAILED,| FAILED: + Courier (imap/pop3) authentication failed. + authentication_failed, + + + + 3900 + ^LOGOUT,|^DISCONNECTED + Courier logout/timeout. + + + + 3900 + ^LOGIN, + Courier (imap/pop3) authentication success. + authentication_success, + + + + 3902 + Courier brute force (multiple failed logins). + authentication_failures, + + + + + 3901 + + Multiple connection attempts from same source. + recon, + + + + + diff --git a/etc/rules/dnsmasq_rules.xml b/etc/rules/dnsmasq_rules.xml new file mode 100644 index 000000000..cf9419572 --- /dev/null +++ b/etc/rules/dnsmasq_rules.xml @@ -0,0 +1,12 @@ + + + + dnsmasq + dnsmasq grouping rule. + + + + + + + diff --git a/etc/rules/dovecot_rules.xml b/etc/rules/dovecot_rules.xml new file mode 100644 index 000000000..a7c44a1ea --- /dev/null +++ b/etc/rules/dovecot_rules.xml @@ -0,0 +1,91 @@ + + + + + + dovecot + Dovecot Messages Grouped. + + + + 9700 + login: Login: + Dovecot Authentication Success. + authentication_success, + + + + 9700 + Password mismatch$ + Dovecot Authentication Failed. + authentication_failed, + + + + 9700 + starting up + Dovecot is Starting Up. + + + + 9700 + ^Fatal: + alert_by_email + Dovecot Fatal Failure. + + + + 9700 + user not found|User not known|unknown user|auth failed + Dovecot Invalid User Login Attempt. + invalid_login,authentication_failed, + + + + 9700 + : Disconnected: + Dovecot Session Disconnected. + + + + 9700 + : Aborted login + Dovecot Aborted Login. + invalid_login, + + + + + + 9702 + + Dovecot Multiple Authentication Failures. + authentication_failures, + + + + 9705 + + Dovecot brute force attack (multiple auth failures). + authentication_failures, + + + + dovecot-info + dovecot-info grouping. + + + + 9770 + user not found|User not known|unknown user|auth failed + Dovecot Invalid User Login Attempt. + invalid_login,authentication_failed, + + + + diff --git a/etc/rules/dropbear_rules.xml b/etc/rules/dropbear_rules.xml new file mode 100644 index 000000000..159ebf019 --- /dev/null +++ b/etc/rules/dropbear_rules.xml @@ -0,0 +1,108 @@ + + + + + + + + + + dropbear + Grouping for dropbear rules. + + + + 51000 + Failed to get kex value + Failed to get key exchange value + + + + 51000 + Premature kexdh_init message received + Premature kexdh_init message + + + + 51000 + bad password attempt for + Bad password attempt. + authentication_failed, + + + + 51000 + attempt for nonexistent user + Bad password attempt for non existent user. + authentication_failed, + + + + authentication_failed + + dropbear + dropbear brute force attempt. + authentication_failures, + + + + 51000 + exit after auth \(\S+\): Disconnect received + User disconnected. + + + + 51000 + exit before auth + Client exited before authentication. + recon, + + + + 51000 + + dropbear brute force attempt. + authentication_failures, + + + + + 51000 + Incompatible remote version + Incompatible remote version. + recon, + + + + 51000 + password auth succeeded for + User successfully logged in using a password. + authentication_success, + + + + 51000 + Pubkey auth succeeded + User successfully logged in using a public key. + authentication_success, + + + + dropbear + 1002 + Error listening: Address already in use + Dropbear cannot listen on port. + + + + + + + diff --git a/etc/rules/exim_rules.xml b/etc/rules/exim_rules.xml new file mode 100644 index 000000000..dfb7028a1 --- /dev/null +++ b/etc/rules/exim_rules.xml @@ -0,0 +1,55 @@ + + + + + windows-date-format + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} SMTP + Exim SMTP Messages Grouped. + + + + windows-date-format + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} dovecot + dovecot messages grouped. + + + + 13001 + authenticator failed + Exim Auth failed + invalid_login,authentication_failed, + + + + 13006 + + Exim brute force attack (multiple auth failures). + authentication_failures, + + + + 13000 + connection count = + Exim connection + + + + 13000 + lost$ + Exim connection lost + + + + 13000 + dropped: too many syntax or protocol errors + Exim syntax or protocol errors + + + diff --git a/etc/rules/firewall_rules.xml b/etc/rules/firewall_rules.xml new file mode 100644 index 000000000..c398f25d1 --- /dev/null +++ b/etc/rules/firewall_rules.xml @@ -0,0 +1,48 @@ + + + + + + firewall + Firewall rules grouped. + + + + + 4100 + DROP + no_log + Firewall drop event. + firewall_drop, + + + + 4100 + Deny + no_log + Firewall drop event. + firewall_drop, + + + + 4101 + + Multiple Firewall drop events from same source. + multiple_drops, + + diff --git a/etc/rules/firewalld_rules.xml b/etc/rules/firewalld_rules.xml new file mode 100644 index 000000000..792752c64 --- /dev/null +++ b/etc/rules/firewalld_rules.xml @@ -0,0 +1,25 @@ + + + ^firewalld + firewalld grouping + + + + 40900 + ERROR: + firewalld error + + + + 40901 + No chain/target/match by that name\.$ + Incorrect chain/target/match. + + + + 40901 + ZONE_ALREADY_SET$ + firewalld: zone already set. + + + diff --git a/etc/rules/ftpd_rules.xml b/etc/rules/ftpd_rules.xml new file mode 100644 index 000000000..c7bb99134 --- /dev/null +++ b/etc/rules/ftpd_rules.xml @@ -0,0 +1,103 @@ + + + + + + ftpd + Grouping for the ftpd rules. + + + + 11100 + FTP LOGIN REFUSED + FTP connection refused. + authentication_failed,access_denied, + + + + 11100 + created + File created via FTP + + + + 11100 + deleted + File deleted via FTP + + + + 11100 + FTPD: IMPORT file + User uploaded a file to server. + + + + 11100 + FTPD: EXPORT file + User downloaded a file to server. + + + + 11100 + FTP LOGIN FROM|connection from|connect from + connection_attempt + Remote host connected to FTP server. + + + + 11100 + refused connect from + access_denied, + Connection blocked by Tcp Wrappers. + + + + 11100 + warning: can't verify hostname: |gethostbyaddr: + Reverse lookup error (bad ISP config). + client_misconfig, + + + + 11100 + repeated login failures + Multiple FTP failed login attempts. + authentication_failures, + + + + 11100 + timed out after + User disconnected due to time out. + + + + 11100 + PAM_ERROR_MSG: Account is disabled + Attempt to login with disabled account. + authentication_failed, + + + + 11100 + ^Failed authentication from + FTP authentication failure. + authentication_failed, + + + + 11100 + ^login \S+ from \S+ failed + FTP authentication failure. + authentication_failed, + + + + + diff --git a/etc/rules/hordeimp_rules.xml b/etc/rules/hordeimp_rules.xml new file mode 100644 index 000000000..a4a43d35e --- /dev/null +++ b/etc/rules/hordeimp_rules.xml @@ -0,0 +1,78 @@ + + + + + + horde_imp + Grouping for the Horde imp rules. + + + + 9300 + ^\[info\] + Horde IMP informational message. + + + + 9300 + ^\[notice\] + Horde IMP notice message. + + + + 9300 + ^\[error\] + Horde IMP error message. + + + + 9300 + ^\[emergency\] + Horde IMP emergency message. + service_availability, + + + + 9302 + Login success for + Horde IMP successful login. + authentication_success, + + + + 9303 + FAILED LOGIN + Horde IMP Failed login. + authentication_failed, + + + + 9306 + + Horde brute force (multiple failed logins). + authentication_failures, + + + + 9304 + Multiple Horde emergency messages. + service_availability, + + + + + + diff --git a/etc/rules/ids_rules.xml b/etc/rules/ids_rules.xml new file mode 100644 index 000000000..8d6fb18cb --- /dev/null +++ b/etc/rules/ids_rules.xml @@ -0,0 +1,104 @@ + + + +8 + + + + ids + + First time this IDS alert is generated. + fts, + + + + ids + srcip, id + IDS event. + + + + + 20100, 20101 + snort + + ^1:1852:|^1:368:|^1:384:|^1:366:|^1:402:|^1:408:|^1:1365:| + ^1:480:|^1:399:|^1:2925: + Ignored snort ids. + + + + + 20100, 20101 + dragon-nids + + ^EOL$|^SOF$|^HEARTBEAT$|^DYNAMIC-TCP$|^DYNAMIC-UDP$ + Ignored snort ids. + + + + 20101 + + id + Multiple IDS alerts for same id. + + + + 20101 + + srcip, id + Multiple IDS events from same source ip. + + + + + + 20151 + + + srcip, id + Multiple IDS events from same source ip + (ignoring now this srcip and id). + + + + 20152 + + id + Multiple IDS alerts for same id + (ignoring now this id). + + diff --git a/etc/rules/imapd_rules.xml b/etc/rules/imapd_rules.xml new file mode 100644 index 000000000..88c42e645 --- /dev/null +++ b/etc/rules/imapd_rules.xml @@ -0,0 +1,52 @@ + + + +6 + + + + imapd + Grouping of the imapd rules. + + + + 3600 + Login failed user=|AUTHENTICATE LOGIN failure + Imapd user login failed. + authentication_failed, + + + + 3600 + Authenticated user= + Imapd user login. + authentication_success, + + + + 3600 + Logout user= + Imapd user logout. + + + + 3601 + + Multiple failed logins from same source ip. + authentication_failures, + + + diff --git a/etc/rules/kesl_rules.xml b/etc/rules/kesl_rules.xml new file mode 100644 index 000000000..e2ec81760 --- /dev/null +++ b/etc/rules/kesl_rules.xml @@ -0,0 +1,122 @@ + + + + + kesl + kesl messages grouped + + + + 53801 + UpdateError + An error occurred during an Update Task. + + + + 53801 + AVBasesAreOutOfDate + AVBasesAreOutOfDate (kesl Task: update) + + + + 53801 + AVBasesAreTotallyOutOfDate + AVBasesAreTotallyOutOfDate (kesl Task: update) + + + + 53801 + TaskStateChanged + Started|Stopped + ^Rollback + An Update Rollback Task has been started / stopped + + + + 53801 + AVBasesRollbackError + An error occurred during AVBases Update Rollback Task + + + + 53801 + TaskStateChanged + Started|Stopped + ^Retranslate + An update distribution (Retranslate) Task has been started / stopped + + + + 53801 + RetranslationError + An error occurred during an update distribution (Retranslate) Task + + + + 53801 + TaskStateChanged + Started + A kesl Task has been started. + + + + 53801 + TaskStateChanged + Suspended + A kesl Task has been suspended. + + + + 53801 + TaskStateChanged + Stopped + ^Backup|^License|^OAS + A kesl Task has been stopped. + + + + 53801 + TaskStateChanged + Stopped + ^ODS|^BootScan|^MemoryScan|^Update + A kesl Task has been stopped. + + + + 53801 + ThreatDetected + Kesl detected a Threat (kesl Task: File_Monitoring) + + + + 53801 + ObjectSavedToBackup + Threat Object was saved to Backup (kesl Task: File_Monitoring) + + + + 53801 + ObjectNotDisinfected + Threat Object could not be disinfected (kesl Task: File_Monitoring) + + + + 53801 + ObjectDeleted + Threat Object was deleted (kesl Task: File_Monitoring) + + + + 53801 + ObjectProcessingError + An error occurred during kesl scan + + + diff --git a/etc/rules/last_rootlogin_rules.xml b/etc/rules/last_rootlogin_rules.xml new file mode 100644 index 000000000..f3d38d894 --- /dev/null +++ b/etc/rules/last_rootlogin_rules.xml @@ -0,0 +1,13 @@ + + + + + + + + 535 + root|reboot|admin|superuser|administrator|supervisor|toor + sensitive login detected + + + diff --git a/etc/rules/lighttpd_rules.xml b/etc/rules/lighttpd_rules.xml new file mode 100644 index 000000000..5eedc7af3 --- /dev/null +++ b/etc/rules/lighttpd_rules.xml @@ -0,0 +1,7 @@ + + + lighttpd + fastcgi + FastCGI error message. + + diff --git a/etc/rules/linux_usbdetect_rules.xml b/etc/rules/linux_usbdetect_rules.xml new file mode 100644 index 000000000..933e16255 --- /dev/null +++ b/etc/rules/linux_usbdetect_rules.xml @@ -0,0 +1,43 @@ + + + + + + kernel + usb + Linux USB detection messages grouped + + + + + 53600 + New USB device found + A new USB device was found by the system + linux, + + + + + 53600 + new low-speed USB device + New Low-Speed USB Device was connected. + linux, + + + + + 53600 + new high-speed USB device + New High-Speed USB Device was connected + linux, + + + + + 53600 + USB disconnect + USB device was disconnected + linux, + + + diff --git a/etc/rules/local_rules.xml b/etc/rules/local_rules.xml new file mode 100644 index 000000000..c30ec2962 --- /dev/null +++ b/etc/rules/local_rules.xml @@ -0,0 +1,57 @@ + + + + + + + + + + 5711 + 192.0.2.1 + Example of rule that will ignore sshd + failed logins from IP 1.1.1.1. + + + + + + + + + + + + + + diff --git a/etc/rules/log-entries/101 b/etc/rules/log-entries/101 new file mode 100644 index 000000000..b383a5854 --- /dev/null +++ b/etc/rules/log-entries/101 @@ -0,0 +1,6 @@ +#unknown system +Feb 15 16:08:14 triumph PAM-securetty[741]: Couldn't open /etc/securetty +Jan 26 21:01:23 test100 PAM-securetty[284]: Couldn't open /etc/securetty +#Red hat +Nov 7 21:01:17 enigma PAM-securetty[975]: Couldn't open /etc/securetty +Apr 19 17:06:03 ecos2 PAM-securetty[1203]: Couldn't open /etc/securetty diff --git a/etc/rules/log-entries/1101 b/etc/rules/log-entries/1101 new file mode 100644 index 000000000..c1b844702 --- /dev/null +++ b/etc/rules/log-entries/1101 @@ -0,0 +1,18 @@ +su[2921936]: succeeded: ttyq4 changing from root to ldap +su[2921936]: failed: ttyq4 changing from root to ldap +su: failed: ttyq# changing from to root +su[234]: BAD SU ger to fwmaster on /dev/ttyp0 +Sep 11 01:40:59 bogus.com su: ericx to root on /dev/ttyu0 +Sep 12 18:40:02 bogus.com su: BAD su rachel on /dev/ttyp1 + +Feb 14 17:20:27 niban su(pam_unix)[23164]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=osaudit +May 4 11:17:42 niban su(pam_unix)[2298]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=root +May 4 11:18:52 niban su(pam_unix)[2307]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=test + +Jun 8 09:01:01 niban su(pam_unix)[1313]: session opened for user root by (uid=1342) +Jun 9 13:32:14 niban su(pam_unix)[1338]: session opened for user root by (uid=1342) +#Slack: +Jul 5 00:30:21 lili su[2190]: + pts/4 dcid-root +Jul 5 12:13:15 lili su[2614]: Authentication failed for root +Jul 5 12:13:15 lili su[2614]: - pts/6 dcid-root + diff --git a/etc/rules/log-entries/1301_1302_1303 b/etc/rules/log-entries/1301_1302_1303 new file mode 100644 index 000000000..a6e936f04 --- /dev/null +++ b/etc/rules/log-entries/1301_1302_1303 @@ -0,0 +1,34 @@ +May 21 10:24:54 niban useradd[6070]: new group: name=test, gid=5006 +May 28 10:48:29 niban useradd[32421]: new group: name=logr, gid=12000 +Jun 16 09:53:44 niban useradd[5721]: new group: name=test2, gid=12001 +Aug 4 15:11:23 niban groupadd[26459]: new group: name=osaudit, gid=12002 +Aug 4 15:14:14 niban groupadd[26477]: new group: name=osaudit, gid=12002 +Aug 5 08:57:10 niban groupadd[30279]: new group: name=osaudit, gid=12002 +Aug 5 09:44:53 niban groupadd[32676]: new group: name=osaudit, gid=12002 +Aug 5 09:47:52 niban groupadd[642]: new group: name=osaudit, gid=12002 +Feb 4 14:21:45 niban adduser[26287]: new group: name=test123, gid=12003 +Apr 5 16:06:49 niban adduser[16143]: new group: name=port, gid=12003 +Apr 5 16:20:28 niban groupadd[16193]: new group: name=port1, gid=12004 +Apr 5 16:20:29 niban groupadd[16194]: new group: name=port2, gid=12005 + +May 28 10:48:29 niban useradd[32421]: new user: name=logr, uid=12000, gid=12000, home=/home/logr, shell=/bin/bash +Jun 16 09:53:44 niban useradd[5721]: new user: name=test2, uid=12001, gid=12001, home=/home/test2, shell=/bin/bash +Aug 5 09:33:06 niban useradd[32213]: new user: name=osaudit, uid=12002, gid=12002, home=/var/osaudit, shell=/sbin/nologin +Aug 5 09:47:52 niban useradd[643]: new user: name=osaudit, uid=12002, gid=12002, home=/var/osaudit, shell=/sbin/nologin +Feb 4 14:21:45 niban adduser[26287]: new user: name=test123, uid=12003, gid=12003, home=/home/test123, shell=/bin/bash +Apr 5 16:06:49 niban adduser[16143]: new user: name=port, uid=12003, gid=12003, home=/home/port, shell=/bin/bash +Apr 5 16:17:35 niban adduser[16164]: new user: name=port2, uid=12004, gid=0, home=/home/port2, shell=/bin/bash +Apr 5 16:18:25 niban adduser[16166]: new user: name=port3, uid=12005, gid=1336, home=/home/port3, shell=/bin/bash +Apr 5 16:19:49 niban adduser[16188]: new user: name=port4, uid=12006, gid=0, home=/home/port4, shell=/bin/bash + +May 28 10:48:07 niban userdel[32416]: delete user `logr' +Aug 5 09:43:27 niban userdel[32657]: delete user `osaudit' +Feb 4 14:27:13 niban userdel[26300]: delete user `test123' + +May 28 10:48:13 niban groupdel[32417]: remove group `logr' +Aug 4 15:13:08 niban groupdel[26461]: remove group `osaudit' +Aug 4 15:15:31 niban groupdel[26821]: remove group `osaudit' +Aug 5 09:43:27 niban userdel[32657]: remove group `osaudit' +Aug 5 09:47:08 niban groupdel[631]: remove group `osaudit' +Feb 4 14:27:13 niban userdel[26300]: remove group `test123' + diff --git a/etc/rules/log-entries/1401 b/etc/rules/log-entries/1401 new file mode 100644 index 000000000..d8f33edb4 --- /dev/null +++ b/etc/rules/log-entries/1401 @@ -0,0 +1,6 @@ +#Red Hat box +Feb 1 14:39:16 nogan sudo: test2 : 3 incorrect password attempts ; TTY=pts/4 ; PWD=/home/test2 ; USER=root ; COMMAND=/bin/ls +#OpenBSD +Jan 28 20:36:33 enigma sudo: dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls +May 26 19:40:25 enigma sudo: dcid : 3 incorrect password attempts ; TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/bin/ls + diff --git a/etc/rules/log-entries/1402 b/etc/rules/log-entries/1402 new file mode 100644 index 000000000..b9b348f66 --- /dev/null +++ b/etc/rules/log-entries/1402 @@ -0,0 +1,8 @@ +#Red Hat +Feb 4 10:43:02 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/ls +Feb 4 10:44:00 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/bin/chmod 777 /home/dcid/test1 +Feb 4 10:46:37 niban sudo: dcid : TTY=pts/26 ; PWD=/home/dcid/dev/pr/osaudit/osaudit-0.1/src ; USER=root ; COMMAND=/bin/cp -pr ../bin/logreader ../bin/logremote ../bin/logremote-client /var/osaudit/bin +#OpenBSD +May 26 19:40:41 enigma sudo: dcid : TTY=ttyp0 ; PWD=/var/www/htdocs ; USER=root ; COMMAND=/usr/bin/tail /var/log/secure +#Slackware +May 26 20:16:17 lili sudo: dcid : TTY=pts/1 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/vi /etc/sudoers diff --git a/etc/rules/log-entries/1602 b/etc/rules/log-entries/1602 new file mode 100644 index 000000000..98e24d4a5 --- /dev/null +++ b/etc/rules/log-entries/1602 @@ -0,0 +1,24 @@ +# From incidents mailing list +Oct 26 18:07:45 ccs rpc.statd[189]: gethostbyname error for ^X^X^Z^Z%8x%8x%8x%8x%8x%8x%8x%8x%8x%62716x%hn%51859x%hn\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220 + +Jul 9 01:21:11 blue /sbin/rpc.statd[166]: gethostbyname error for +^X^X^Y^Y^Z^Z +^[^[%8x%8x%8x%8x%8x%8x%8x%8x%8x%236x +%n%137x%n%10x%n%192x%n\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\2 +20\220\220\220\220\220\220 +Jul 9 01:21:11 blue +^F/binF^D/shA0\210F^G\211v^L\215V^P\215N^L\211^K +\200^A\200\177 + +May 16 19:38:33 server rpc.statd[353]: gethostbyname error for ^Y...^Y...^[??[ diff --git a/etc/rules/log-entries/1603 b/etc/rules/log-entries/1603 new file mode 100644 index 000000000..99e5033c5 --- /dev/null +++ b/etc/rules/log-entries/1603 @@ -0,0 +1,3 @@ +May 17 01:01:19 server ftpd[746]: ANONYMOUS FTP LOGIN FROM emaca.here.com +[192.168.3.236], 1.1.1.F.1.1.C.A.?..k^1.1.^^AF^Df..^A.'.1.^^A.=.1.1.^^HC^B1...1 +.^^H.^L...u.1.F^I^^H.=..^N.0..F^D1.F^Gv^HF^L.N^HV^L.^K.1.1.^A.....0bin0sh1..11 diff --git a/etc/rules/log-entries/1607 b/etc/rules/log-entries/1607 new file mode 100644 index 000000000..5b5c2b95c --- /dev/null +++ b/etc/rules/log-entries/1607 @@ -0,0 +1,11 @@ +# From log analysis web site +May 16 22:46:08 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped +May 16 22:46:21 victim-host last message repeated 7 times +May 16 22:46:22 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Bus Error - core dumped +May 16 22:46:24 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped +May 16 22:46:56 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Bus Error - core dumped +May 16 22:46:59 victim-host last message repeated 1 time +May 16 22:47:02 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped +May 16 22:47:07 victim-host last message repeated 3 times +May 16 22:47:09 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Hangup +May 16 22:47:11 victim-host inetd[600]: /usr/lib/fs/cachefs/cachefsd: Segmentation Fault - core dumped diff --git a/etc/rules/log-entries/1609 b/etc/rules/log-entries/1609 new file mode 100644 index 000000000..4614f3d5c --- /dev/null +++ b/etc/rules/log-entries/1609 @@ -0,0 +1,7 @@ +a.out[347] attempt to execute code on stack by uid 555 +Nov 12 18:47:01 foo.bar.baz /usr/dt/bin/rpc.ttdbserverd[646]: _Tt_file_system::findBestMountPoint -- max_match_entry is null, aborting... +Nov 12 18:47:01 foo.bar.baz inetd[143]: /usr/dt/bin/rpc.ttdbserverd: Segmentation Fault - core dumped +Nov 12 18:47:02 foo.bar.baz unix: rpc.ttdbserverd[1932] attempt to execute code on stack by uid 0 +Nov 12 18:47:02 foo.bar.baz inetd[143]: /usr/dt/bin/rpc.ttdbserverd: Segmentation Fault - core dumped +Nov 12 18:47:03 foo.bar.baz unix: rpc.ttdbserverd[1934] attempt to execute code on stack by uid 0 +Nov 12 18:47:03 foo.bar.baz inetd[143]: /usr/dt/bin/rpc.ttdbserverd: Segmentation Fault - core dumped diff --git a/etc/rules/log-entries/1901 b/etc/rules/log-entries/1901 new file mode 100644 index 000000000..9f57e9d3c --- /dev/null +++ b/etc/rules/log-entries/1901 @@ -0,0 +1,9 @@ +Apr 17 22:20:21 hostj named[312]: [ID 295310 daemon.notice] security: notice: dropping source port zero packet from [64.211.251.254].0 +Apr 17 22:20:21 hostj named[312]: [ID 295310 daemon.notice] security: notice: dropping source port zero packet from [64.211.251.254].0 +Apr 17 22:20:29 hostj named[312]: [ID 295310 daemon.notice] security: notice: dropping source port zero packet from [64.211.251.254].0 +Jan 6 13:39:19 drew named[128838]: dropping source port zero packet from [216.161.67.226].0 +Jan 6 13:39:23 drew named[128838]: dropping source port zero packet from [63.224.229.252].0 +Jan 6 13:39:25 drew named[128838]: dropping source port zero packet from [63.227.214.187].0 +named[3430]: dropping source port zero packet from [209.191.188.93].0 +named[3534]: dropping source port zero packet from [63.226.179.7].0 +named[20627]: dropping source port zero packet from [206.252.159.146].0 diff --git a/etc/rules/log-entries/1902 b/etc/rules/log-entries/1902 new file mode 100644 index 000000000..51929ce17 --- /dev/null +++ b/etc/rules/log-entries/1902 @@ -0,0 +1,3 @@ +Apr 20 09:14:45 hostname named[98]: denied AXFR from [1.2.3.4].1329 for +"xxxxx.com" (not master/slave) +Mar 1 13:52:03 arcane named[15025]: denied AXFR from [205.166.226.38].1421 for "atfantasy.com" (acl) diff --git a/etc/rules/log-entries/1903 b/etc/rules/log-entries/1903 new file mode 100644 index 000000000..d064bdeca --- /dev/null +++ b/etc/rules/log-entries/1903 @@ -0,0 +1,4 @@ +Jan 6 13:40:28 drew named[128838]: denied update from [24.64.63.195].41151 for in-addr.arpa +Jan 6 13:40:47 drew named[128838]: denied update from [24.64.63.195].41858 for in-addr.arpa +unapproved update from [132.174.25.169].1848 for 174.132.in-addr.arpa +Dec 31 00:01:31 valhalla named[7885]: client 192.168.1.231#1142: update 'hayaletgemi.edu/IN' denied diff --git a/etc/rules/log-entries/1905 b/etc/rules/log-entries/1905 new file mode 100644 index 000000000..8405803fd --- /dev/null +++ b/etc/rules/log-entries/1905 @@ -0,0 +1,3 @@ +named[8020]: unexpected RCODE (REFUSED) resolving 'inteligentes.cjb.net/AAAA/IN': 200.206.159.96#53 + +named[8020]: unexpected RCODE (REFUSED) resolving 'inteligentes.cjb.net/A/IN': 200.206.159.96#53 diff --git a/etc/rules/log-entries/201 b/etc/rules/log-entries/201 new file mode 100644 index 000000000..d05692dae --- /dev/null +++ b/etc/rules/log-entries/201 @@ -0,0 +1,4 @@ +#Unknown +May 26 12:53:57 atlas kernel: svc: unknown program 100227 (me 100003) +Feb 28 07:46:15 bs11 kernel: svc: unknown program 100227 (me 100003) +Jun 28 09:58:14 poseidon kernel: svc: unknown program 100227 (me 100003) diff --git a/etc/rules/log-entries/202 b/etc/rules/log-entries/202 new file mode 100644 index 000000000..ec3425ceb --- /dev/null +++ b/etc/rules/log-entries/202 @@ -0,0 +1,6 @@ +Mar 30 12:01:25 compute-0-0.local automount[6447]: mount(nfs): nfs: mount failure cares.local:/export/home/jfiske on /home/jfiske +Mar 30 12:01:25 compute-0-0.local automount[6449]: mount(nfs): nfs: mount failure cares.local:/export/home/jfiske on /home/jfiske +Aug 4 12:35:30 localhost automount[7203]: mount(nfs): nfs: mount failure 192.168.1.100:/compile/nfs/107 on /test/107 +Jul 2 22:37:52 gkar automount[2344]: mount(nfs): nfs: mount failure sunray:/exp +Aug 4 12:31:56 localhost automount[5252]: mount(nfs): nfs: mount +failure 192.168.1.100:/compile/nfs/16 diff --git a/etc/rules/log-entries/204 b/etc/rules/log-entries/204 new file mode 100644 index 000000000..0cba4c0c9 --- /dev/null +++ b/etc/rules/log-entries/204 @@ -0,0 +1,4 @@ +rpc.mountd: refused mount request from 10.0.0.12 for /home2/files (/): no export entry +Jan 12 08:20:00 gateway rpc.mountd: refused mount request from test.bscnet.com for /mnt (/): no export entry +Jul 5 12:00:53 lili rpc.mountd: refused mount request from enigma for /bin (/): no export entry +Jul 5 12:01:03 lili rpc.mountd: refused mount request from enigma for /etc (/): no export entry diff --git a/etc/rules/log-entries/2501 b/etc/rules/log-entries/2501 new file mode 100644 index 000000000..397dfd57b --- /dev/null +++ b/etc/rules/log-entries/2501 @@ -0,0 +1,28 @@ +Nov 9 05:00:07 ensim +proftpd[21141]: ensim.domain.com +(p50832E46.dip.t-dialin.net[80.131 +.46.70]) - FTP session opened. +Nov 9 05:00:09 ensim +proftpd[21141]: ensim.domain.com +(p50832E46.dip.t-dialin.net[80.131 +.46.70]) - no such user +'anonymous' +Nov 9 05:00:14 ensim +proftpd[21141]: ensim.domain.com +(p50832E46.dip.t-dialin.net[80.131 +.46.70]) - FTP session closed. +Nov 9 06:12:41 ensim +proftpd[24994]: ensim.domain.com +(ool-18bba13b.dyn.optonline.net[24 +.187.161.59]) - FTP session +opened. +Nov 9 06:12:41 ensim +proftpd[24994]: ensim.domain.com +(ool-18bba13b.dyn.optonline.net[24 +.187.161.59]) - no such user +'vgodz' +Nov 9 06:12:41 ensim +proftpd[24994]: ensim.domain.com +(ool-18bba13b.dyn.optonline.net[24 +.187.161.59]) - FTP session +closed. diff --git a/etc/rules/log-entries/2601 b/etc/rules/log-entries/2601 new file mode 100644 index 000000000..12c5ba436 --- /dev/null +++ b/etc/rules/log-entries/2601 @@ -0,0 +1,4 @@ +pptpd[7282]: GRE: read(fd=7,buffer=80567c0,len=8260) from network failed: status = -1 error = Protocol not available +pptpd[7293]: GRE: read(fd=7,buffer=80567c0,len=8260) from network failed: status = -1 error = Protocol not available +pptpd[7510]: GRE: read(fd=7,buffer=80567c0,len=8260) from network failed: status = -1 error = Protocol not available +pptpd[8916]: GRE: read(fd=7,buffer=80567c0,len=8260) from network failed: status = -1 error = Protocol not available diff --git a/etc/rules/log-entries/301 b/etc/rules/log-entries/301 new file mode 100644 index 000000000..58f0941ac --- /dev/null +++ b/etc/rules/log-entries/301 @@ -0,0 +1,2 @@ +Jan 25 21:05:40 horus xinetd[4479]: Deactivating service ftp due to excessive incoming connections. Restarting in 30 seconds. +Feb 20 14:54:32 localhost xinetd[717]: Deactivating service nsca due to excessive incoming connections. Restarting in 30 seconds. diff --git a/etc/rules/log-entries/401 b/etc/rules/log-entries/401 new file mode 100644 index 000000000..c35122ac0 --- /dev/null +++ b/etc/rules/log-entries/401 @@ -0,0 +1,10 @@ +# freebsd invalid physical login +login: 1 LOGIN FAILURE ON ttyv0 +login: 1 LOGIN FAILURE ON ttyv0, root + +# saslauthd +saslauthd[113]: do_auth : auth failure: [user=SERVERWEB\Administrador] [service=smtp] [realm=] [mech=shadow] [reason=Unknown] + +# Strange sshd logs +sshd[7386]: error: Bad prime description in line 73 +sshd[8143]: error: Bad prime description in line 73 diff --git a/etc/rules/log-entries/403 b/etc/rules/log-entries/403 new file mode 100644 index 000000000..9c3b5fc44 --- /dev/null +++ b/etc/rules/log-entries/403 @@ -0,0 +1,29 @@ +Dec 7 13:52:12 casal in.telnetd[27798]: refused connect from unknown +Dec 7 13:52:12 casal in.telnetd[27798]: refused connect from unknown +Jan 22 10:37:41 frontend-0 ypserv[832]: refused connect from +127.0.0.1:868 +Feb 21 15:14:29 my_ftp_host in.ftpd[32374]: refused connect from +XX.XX.XX.67 +Feb 21 15:14:36 my_ftp_host in.ftpd[32375]: refused connect from +XX.XX.XX.67 +Jan 12 20:48:29 elrond sshd[19734]: refused connect from accsys.elink.net.au (203.31.101.11) + +Jan 14 18:29:26 elrond sshd[26895]: refused connect from pD952714D.dip.t-dialin.net (217.82.113.77) + +Jan 18 21:46:26 elrond sshd[9370]: refused connect from root@cops2.inf.ethz.ch (129.132.134.179) + +Jan 19 19:34:06 elrond sshd[12580]: refused connect from r88m211.cybercable.tm.fr (195.132.88.211) + +Jan 23 13:13:49 elrond sshd[25980]: refused connect from pD9527D56.dip.t-dialin.net (217.82.125.86) + +Jan 24 19:26:26 elrond sshd[30479]: refused connect from pD95279BD.dip.t-dialin.net (217.82.121.189) + +Jan 27 07:33:48 elrond sshd[7899]: refused connect from root@194.213.255.84 (194.213.255.84) + +Jan 31 20:48:07 elrond sshd[26946]: refused connect from wwwstud.hsk.no (158.36.81.145) + +Feb 1 01:30:49 elrond sshd[27872]: refused connect from co101359-a.olden1.ov.nl.home.com (213.51.84.16) + +Feb 4 07:06:59 elrond sshd[7766]: refused connect from moosrose.onlineunit.de (195.254.38.131) + +Feb 10 22:22:49 elrond sshd[2592]: refused connect from root@62.138.38.142 (62.138.38.142) diff --git a/etc/rules/log-entries/408 b/etc/rules/log-entries/408 new file mode 100644 index 000000000..d11f1a737 --- /dev/null +++ b/etc/rules/log-entries/408 @@ -0,0 +1,2 @@ +#Red Hat +Feb 4 16:54:28 niban login[1074]: FAILED LOGIN 1 FROM (null) FOR dcid, Authentication failure diff --git a/etc/rules/log-entries/409 b/etc/rules/log-entries/409 new file mode 100644 index 000000000..753d169e2 --- /dev/null +++ b/etc/rules/log-entries/409 @@ -0,0 +1,7 @@ +#FreeBSD +Feb 15 14:32:20 freebsd-1 sshd[1374]: Illegal user dcid from 192.168.1.2 +Feb 15 16:11:56 freebsd-1 sshd[2690]: Illegal user dcid from 192.168.10.153 +Aug 1 15:44:10 enigma sshd[13752]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2 +Aug 1 15:44:10 enigma sshd[6682]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2 +Aug 1 15:44:11 enigma sshd[6682]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2 +Aug 1 15:44:11 enigma sshd[13752]: Failed password for invalid user ss7 from 65.202.215.2 port 18546 ssh2 diff --git a/etc/rules/log-entries/access-control b/etc/rules/log-entries/access-control new file mode 100644 index 000000000..a3cef5893 --- /dev/null +++ b/etc/rules/log-entries/access-control @@ -0,0 +1,13 @@ +# Terminal failure +Apr 27 17:27:19 niban login(pam_unix)[1059]: authentication failure; logname=LOGIN uid=0 euid=0 tty=tty2 ruser= rhost= user=root +Apr 27 17:27:21 niban login[1059]: FAILED LOGIN 1 FROM (null) FOR root, Authentication failure +# ssh (pam) failure +Apr 27 17:33:59 niban sshd(pam_unix)[9420]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=niban.sfeng.sourcefire.com user=dcid +Apr 27 17:34:04 niban sshd(pam_unix)[9420]: 1 more authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=niban.sfeng.sourcefire.com user=dcid +# ssh failure root +Apr 27 17:34:26 niban sshd(pam_unix)[9425]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=niban.sfeng.sourcefire.com user=root + +# SSHD failed password +Apr 27 17:34:04 niban sshd[9420]: Failed password for dcid from 10.4.12.26 port 40137 ssh2 +Apr 27 17:34:28 niban sshd[9425]: Failed password for root from 10.4.12.26 port 40138 ssh2 + diff --git a/etc/rules/log-entries/apache-error.logs b/etc/rules/log-entries/apache-error.logs new file mode 100644 index 000000000..79db71477 --- /dev/null +++ b/etc/rules/log-entries/apache-error.logs @@ -0,0 +1,39 @@ +[Thu Dec 15 23:49:07 2005] [error] [client 85.107.239.37] client denied by server configuration: /home/myuser/wwwhome/.htm, referer: http://www.example.com/~user7/laodikeiaproject.htm?pswd=hhh +[Mon Dec 19 18:04:14 2005] [error] [client 85.107.239.37] client denied by server configuration: /home/johndoe/wwwhome/index2.html, referer: http://www.server.com/~refuser/gatekeep.html +[Mon Dec 19 18:46:05 2005] [error] [client 81.213.203.103] client denied by server configuration: /apache/web-data/htdocs/home/wwwrd/rcilo/announce/, referer: http://webmail.academia.edu/0/_top + + +[Fri Dec 16 01:46:23 2005] [error] [client 80.230.208.105] Directory index forbidden by rule: /home/inst1/wwwhome/courses/es301/ +[Fri Dec 16 01:54:34 2005] [error] [client 131.193.170.106] Directory index forbidden by rule: /apache/web-data/hteng/home/ker/16imfiles/photos/1999cn/ +[Fri Dec 16 02:05:46 2005] [error] [client 195.229.242.53] Directory index forbidden by rule: /apache/web-data/htdocs/home/tuniv/assets/damascus3/ +[Fri Dec 16 11:02:09 2005] [error] [client 139.177.32.34] Directory index forbidden by rule: /apache/web-data/htdocs/home/maiam/research/groups, referer: http://www.akademi.edu.tr/research/groups/index.html + + +[Fri Dec 16 02:25:55 2005] [error] [client 64.94.163.159] Client sent malformed Host header +[Fri Dec 16 03:10:11 2005] [error] [client 64.94.163.159] Client sent malformed Host header +[Fri Dec 16 04:04:36 2005] [error] [client 64.94.163.159] Client sent malformed Host header +[Fri Dec 16 05:26:09 2005] [error] [client 64.94.163.137] Client sent malformed Host header + + +[Mon Dec 19 19:29:17 2005] [warn] [client 85.98.37.115] [315546] auth_ldap authenticate: user administrator authentication failed; URI /exam/inter/Announce.htm [User not found][No such object], referer: http://www.akademi.edu.tr/ +[Mon Dec 19 20:35:25 2005] [warn] [client 213.139.197.178] [307420] auth_ldap authenticate: user user7 authentication failed; URI /exam/inter/Announce.htm [User not found][No such object], referer: http://www.akademi.edu.tr/ +[Mon Dec 19 22:06:34 2005] [warn] [client 85.101.143.252] [360448] auth_ldap authenticate: user user9 authentication failed; URI /files/pg/app_web/index.php [User not found][No such object], referer: http://www.example.com/index.php?sub=list + + +[Mon Dec 19 23:01:11 2005] [error] [client 85.105.120.139] user qwerty not found: /~oahmet/gunce/ss.txt +[Mon Dec 19 23:01:13 2005] [error] [client 85.105.120.139] user qwerty not found: /~oahmet/gunce/ss.txt +[Mon Dec 19 23:01:14 2005] [error] [client 85.105.120.139] user qwerty not found: /~oahmet/gunce/ss.txt + + +[Mon Dec 19 23:02:01 2005] [error] [client 85.105.120.139] user oahmet: authentication failure for "/~oahmet/gunce/ss.txt": Password Mismatch +[Mon Dec 19 23:02:05 2005] [error] [client 85.105.120.139] user oahmet: authentication failure for "/~oahmet/gunce/ss.txt": Password Mismatch + + +Sun Aug 5 16:23:04 2001] [error] [client 66.31.142.16] File does not exist: /var/www/html/default.ida +[Sun Aug 5 16:26:02 2001] [error] [client 66.31.68.147] File does not exist: /var/www/html/default.ida +[Sun Aug 5 16:32:01 2001] [error] [client 66.31.101.12] File does not exist: /var/www/html/default.ida + +[Tue Sep 12 10:38:15 2006] [error] [client 127.0.0.1] request failed: URI too long (longer than 8190) +[Tue Sep 12 10:39:38 2006] [error] [client 127.0.0.1] request failed: URI too long (longer than 8190) +[Tue Sep 12 10:40:17 2006] [error] [client 127.0.0.1] request failed: URI too long (longer than 8190) +[Mon Sep 11 16:55:08 2006] [error] [client 127.0.0.1] (36)File name too long: access to /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm failed diff --git a/etc/rules/log-entries/cisco-ios-ids b/etc/rules/log-entries/cisco-ios-ids new file mode 100644 index 000000000..7e109ff54 --- /dev/null +++ b/etc/rules/log-entries/cisco-ios-ids @@ -0,0 +1,25 @@ +Sep 1 10:24:59 10.10.10.1 %SYS-5-CONFIG_I: Configured from console by console +Sep 1 10:25:18 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:49871 -> 10.10.10.10:80] +Sep 1 10:25:18 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:59591 -> 10.10.10.10:80] +Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:51654 -> 10.10.10.10:4444] +Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:60797 -> 10.10.10.10:80] +Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:5123 Subsig:2 Sev:5 WWW IIS Internet Printing Overflow [192.168.100.11:60797 -> 10.10.10.10:80] +Sep 1 10:25:30 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:59816 -> 10.10.10.10:4444] +Sep 1 10:26:52 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1232 -> 192.168.100.1:443] +Sep 1 10:29:24 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1233 -> 192.168.100.1:443] +Sep 1 10:29:33 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1234 -> 192.168.100.1:443] +Sep 1 10:29:37 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1235 -> 192.168.100.1:443] +Sep 1 10:30:33 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1236 -> 192.168.100.1:443] +Sep 1 10:31:44 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1237 -> 192.168.100.1:443] +Sep 1 10:31:55 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1238 -> 192.168.100.1:443] +Sep 1 10:33:30 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1239 -> 192.168.100.1:443] +Sep 1 10:34:27 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1240 -> 192.168.100.1:443] +Sep 1 10:36:09 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1241 -> 192.168.100.1:443] +Sep 1 10:36:12 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1242 -> 192.168.100.1:443] +Sep 1 10:36:14 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1243 -> 192.168.100.1:443] +Sep 1 10:37:28 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1244 -> 192.168.100.1:443] +Sep 1 10:38:08 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.12:1245 -> 192.168.100.1:443] +Sep 1 10:38:36 10.10.10.1 %IPS-4-SIGNATURE: Sig:5123 Subsig:0 Sev:5 WWW IIS Internet Printing Overflow [192.168.100.11:59633 -> 10.10.10.10:80] +%IPS-4-SIGNATURE: Sig:5769 Subsig:0 Sev:4 Malformed HTTP Request [192.168.100.11:59633 -> 10.10.10.10:80] +%IPS-4-SIGNATURE: Sig:5123 Subsig:0 Sev:5 WWW IIS Internet Printing Overflow [192.168.100.11:59633 -> 10.10.10.10:80] +%IPS-4-SIGNATURE: Sig:5769 Subsig:0 Sev:4 Malformed HTTP Request [192.168.100.11:59633 -> 10.10.10.10:80] diff --git a/etc/rules/log-entries/ciscoios b/etc/rules/log-entries/ciscoios new file mode 100644 index 000000000..ce1bd3522 --- /dev/null +++ b/etc/rules/log-entries/ciscoios @@ -0,0 +1,9 @@ +Jul 10 16:07:14 cisco2621 %SEC-6-IPACCESSLOGP: list 102 denied tcp 10.0.6.56(3067) -> 172.36.4.7(139), 1 packet +%SEC-6-IPACCESSLOGP: list 199 permitted tcp 10.0.40.16(3059) -> 10.0.4.101(1060), 2 packets +%SEC-6-IPACCESSLOGP: list 199 permitted tcp 10.0.16.16(2179) -> 10.0.4.101(1060), 1 packet +%SEC-6-IPACCESSLOGP: list 199 permitted tcp 10.0.32.16(4206) -> 10.0.4.101(1060), 2 packets +%SEC-6-IPACCESSLOGP: list 199 denied tcp 10.0.61.108(1477) -> 10.0.127.20(445), 1 packet +Jul 10 16:07:14 1.2.3.4 %SEC-6-IPACCESSLOGP: list 199 denied tcp 10.0.61.108(1469) -> 10.0.127.12(445), 1 packet +%SEC-6-IPACCESSLOGP: list 199 denied tcp 10.0.61.108(1496) -> 10.0.127.39(445), 1 packet +%SEC-6-IPACCESSLOGP: list 100 denied udp 200.174.153.126(1028) -> 66.81.85.65(137), 1 packet +Jul 10 16:07:14 myhost1 %SEC-6-IPACCESSLOGP: list 100 denied udp 195.23.72.148(1026) -> 66.81.85.65(137), 1 packet diff --git a/etc/rules/log-entries/ftpd b/etc/rules/log-entries/ftpd new file mode 100644 index 000000000..757eb3a6f --- /dev/null +++ b/etc/rules/log-entries/ftpd @@ -0,0 +1,15 @@ +May 28 19:38:24 valhalla ftpd[24474]: FTPD: IMPORT file local /mnt/1//ide9/s09099/public_html/tasarim_files/akis.bmp, remote +Jun 1 22:50:26 valhalla ftpd[22898]: FTPD: IMPORT file local oledata.mso, remote +May 28 15:14:02 valhalla ftpd[28616]: FTPD: EXPORT file local , remote Analiz.html +May 28 21:40:31 valhalla ftpd[28432]: FTPD: EXPORT file local , remote arrows_up.gif +May 28 15:50:36 valhalla ftpd[28370]: connection from dsl.static8596180144.ttnet.net.tr at Sun May 28 15:50:36 2006 +May 28 15:50:36 valhalla ftpd[28370]: FTP LOGIN FROM dsl.static8596180144.ttnet.net.tr, user12 +May 29 11:04:16 queen ftpd[417946]: connect from vlh102.tncc.mu.edu +Jun 3 02:32:37 queen ftpd[418042]: refused connect from y-oper.labs.mu.edu +Jun 3 13:37:10 queen ftpd[327802]: refused connect from 85.99.150.230 +Jun 3 11:38:08 queen ftpd[491744]: warning: can't verify hostname: gethostbyname(dsl85-102-24474.ttnet.net.tr) failed +Jun 3 07:46:16 arguvan in.ftpd[18561]: [ID 484914 daemon.notice] gethostbyaddr: nameservices.net. != 216.117.134.168 +Jun 1 16:16:26 valhalla ftpd[39056]: repeated login failures from dsl.dynamic859622181.ttnet.net.tr +Jun 2 16:44:05 valhalla ftpd[28662]: repeated login failures from 192.168.4.5 +May 28 15:52:51 valhalla ftpd[27654]: User oahmet timed out after 900 seconds at Sun May 28 15:52:51 2006 +May 30 00:06:23 valhalla ftpd[11452]: User redsp timed out after 900 seconds at Tue May 30 00:06:23 2006 diff --git a/etc/rules/log-entries/iis6 b/etc/rules/log-entries/iis6 new file mode 100644 index 000000000..95540ecaf --- /dev/null +++ b/etc/rules/log-entries/iis6 @@ -0,0 +1,4 @@ +2007-01-22 05:00:11 W3SVC1 HOSTNAME 1.1.1.1 POST /SimpleAuthWebService/SimpleAuth.asmx - 80 - 2.2.2.2 HTTP/1.1 Windows-Update-Agent - - hostname 200 0 0 1467 841 31 +2007-01-22 05:00:11 W3SVC1 HOSTNAME 1.1.1.1 POST /SimpleAuthWebService/SimpleAuth.asmx - 80 - 2.2.2.2 HTTP/1.1 Windows-Update-Agent - - hostname 400 0 0 1467 841 31 +2007-01-23 05:00:11 W3SVC22 xxx.theopenarmor.org 1.2.3.4 GET / - 80 - 192.168.2.33 HTTP/1.1 Windows-Update-Agent - - myhost.name 500 0 0 1467 841 31 +2005-05-21 05:39:27 W3SVC1 hostname123 192.168.0.101 GET /VirtualServerError/VSWebApp.exe view=1 1024 WEBBROWSER\User 192.168.0.101 HTTP/1.0 Mozilla/4.0+(User-Agent) - - xx.nada.com 200 0 0 diff --git a/etc/rules/log-entries/imapd b/etc/rules/log-entries/imapd new file mode 100644 index 000000000..a77d05ecd --- /dev/null +++ b/etc/rules/log-entries/imapd @@ -0,0 +1,1126 @@ +May 7 13:40:14 gaucha imapd[26772]: imap service init from 200.255.5.8 +May 7 13:40:14 gaucha imapd[26772]: Authenticated user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:14 gaucha imapd[26772]: Logout user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:20 gaucha imapd[26788]: imap service init from 200.255.5.8 +May 7 13:40:20 gaucha imapd[26788]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:21 gaucha imapd[26788]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:25 gaucha imapd[26792]: imap service init from 200.255.5.8 +May 7 13:40:25 gaucha imapd[26792]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:25 gaucha imapd[26792]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:33 gaucha imapd[26801]: imap service init from 200.255.5.8 +May 7 13:40:33 gaucha imapd[26801]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:33 gaucha imapd[26801]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:38 gaucha imapd[26803]: imap service init from 200.255.5.8 +May 7 13:40:38 gaucha imapd[26803]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:39 gaucha imapd[26803]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:45 gaucha imapd[26810]: imap service init from 200.255.5.8 +May 7 13:40:45 gaucha imapd[26810]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:45 gaucha imapd[26810]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:55 gaucha imapd[26820]: imap service init from 200.255.5.8 +May 7 13:40:55 gaucha imapd[26820]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:40:55 gaucha imapd[26820]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:24 gaucha imapd[26906]: imap service init from 200.255.5.8 +May 7 13:41:24 gaucha imapd[26906]: Authenticated user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:25 gaucha imapd[26906]: Logout user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:25 gaucha imapd[26908]: imap service init from 200.255.5.8 +May 7 13:41:25 gaucha imapd[26908]: Authenticated user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:25 gaucha imapd[26908]: Logout user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:39 gaucha imapd[26924]: imap service init from 200.255.5.8 +May 7 13:41:39 gaucha imapd[26924]: Authenticated user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:40 gaucha imapd[26924]: Logout user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:43 gaucha imapd[26932]: imap service init from 200.255.5.8 +May 7 13:41:43 gaucha imapd[26932]: Authenticated user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:44 gaucha imapd[26932]: Logout user=lamafia host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:59 gaucha imapd[26953]: imap service init from 200.255.5.8 +May 7 13:41:59 gaucha imapd[26953]: Authenticated user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:41:59 gaucha imapd[26953]: Logout user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:00 gaucha imapd[26959]: imap service init from 200.255.5.8 +May 7 13:42:00 gaucha imapd[26959]: Authenticated user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:00 gaucha imapd[26959]: Logout user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:19 gaucha imapd[27019]: imap service init from 200.255.5.8 +May 7 13:42:19 gaucha imapd[27019]: Authenticated user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:21 gaucha imapd[27019]: Logout user=joao host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:48 gaucha imapd[27094]: imap service init from 200.255.5.8 +May 7 13:42:48 gaucha imapd[27094]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:48 gaucha imapd[27094]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:48 gaucha imapd[27096]: imap service init from 200.255.5.8 +May 7 13:42:48 gaucha imapd[27096]: Authenticated user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:42:48 gaucha imapd[27096]: Logout user=tiago host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:51:53 gaucha imapd[27832]: imap service init from 200.255.5.8 +May 7 13:51:56 gaucha imapd[27832]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:51:59 gaucha imapd[27832]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:02 gaucha imapd[27832]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:02 gaucha imapd[27832]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:41 gaucha imapd[27991]: imap service init from 200.255.5.8 +May 7 13:52:44 gaucha imapd[27991]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:47 gaucha imapd[27991]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:50 gaucha imapd[27991]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:50 gaucha imapd[27991]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:51 gaucha imapd[27999]: imap service init from 200.255.5.8 +May 7 13:52:54 gaucha imapd[27999]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:52:57 gaucha imapd[27999]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:53:00 gaucha imapd[27999]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:53:00 gaucha imapd[27999]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:53:39 gaucha imapd[28041]: imap service init from 200.255.5.8 +May 7 13:53:42 gaucha imapd[28041]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:53:45 gaucha imapd[28041]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:53:48 gaucha imapd[28041]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:53:48 gaucha imapd[28041]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:10 gaucha imapd[28129]: imap service init from 200.255.5.8 +May 7 13:54:13 gaucha imapd[28129]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:16 gaucha imapd[28129]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:19 gaucha imapd[28129]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:19 gaucha imapd[28129]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:39 gaucha imapd[28170]: imap service init from 200.255.5.8 +May 7 13:54:42 gaucha imapd[28170]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:45 gaucha imapd[28170]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:48 gaucha imapd[28170]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:54:48 gaucha imapd[28170]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:55:37 gaucha imapd[28236]: imap service init from 200.255.5.8 +May 7 13:55:40 gaucha imapd[28236]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:55:43 gaucha imapd[28236]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:55:46 gaucha imapd[28236]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:55:46 gaucha imapd[28236]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:56:23 gaucha imapd[28311]: imap service init from 200.255.5.8 +May 7 13:56:27 gaucha imapd[28311]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:56:30 gaucha imapd[28311]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:56:33 gaucha imapd[28311]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:56:33 gaucha imapd[28311]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:08 gaucha imapd[28414]: imap service init from 200.255.5.8 +May 7 13:57:08 gaucha imapd[28414]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:08 gaucha imapd[28414]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:08 gaucha imapd[28416]: imap service init from 200.255.5.8 +May 7 13:57:08 gaucha imapd[28416]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:10 gaucha imapd[28416]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:16 gaucha imapd[28424]: imap service init from 200.255.5.8 +May 7 13:57:17 gaucha imapd[28424]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:17 gaucha imapd[28424]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:17 gaucha imapd[28425]: imap service init from 200.255.5.8 +May 7 13:57:17 gaucha imapd[28425]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:17 gaucha imapd[28425]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:56 gaucha imapd[28469]: imap service init from 200.255.5.8 +May 7 13:57:56 gaucha imapd[28469]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:57:57 gaucha imapd[28469]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:11 gaucha imapd[28538]: imap service init from 200.255.5.8 +May 7 13:58:11 gaucha imapd[28538]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:11 gaucha imapd[28538]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:12 gaucha imapd[28539]: imap service init from 200.255.5.8 +May 7 13:58:12 gaucha imapd[28539]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:12 gaucha imapd[28539]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:12 gaucha imapd[28541]: imap service init from 200.255.5.8 +May 7 13:58:12 gaucha imapd[28541]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:12 gaucha imapd[28541]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:20 gaucha imapd[28553]: imap service init from 200.255.5.8 +May 7 13:58:20 gaucha imapd[28553]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:20 gaucha imapd[28553]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:24 gaucha imapd[28557]: imap service init from 200.255.5.8 +May 7 13:58:24 gaucha imapd[28557]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:24 gaucha imapd[28557]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:50 gaucha imapd[28646]: imap service init from 200.255.5.8 +May 7 13:58:50 gaucha imapd[28646]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:58:50 gaucha imapd[28646]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:12 gaucha imapd[28691]: imap service init from 200.255.5.8 +May 7 13:59:12 gaucha imapd[28691]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:13 gaucha imapd[28691]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:13 gaucha imapd[28692]: imap service init from 200.255.5.8 +May 7 13:59:13 gaucha imapd[28692]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:13 gaucha imapd[28692]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:39 gaucha imapd[28713]: imap service init from 200.255.5.8 +May 7 13:59:39 gaucha imapd[28713]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:39 gaucha imapd[28713]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:40 gaucha imapd[28714]: imap service init from 200.255.5.8 +May 7 13:59:40 gaucha imapd[28714]: Authenticated user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:40 gaucha imapd[28714]: Logout user=paulomartins host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:43 gaucha imapd[28718]: imap service init from 200.255.5.8 +May 7 13:59:43 gaucha imapd[28718]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 13:59:43 gaucha imapd[28718]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:00:51 gaucha imapd[28821]: imap service init from 200.255.5.8 +May 7 14:00:53 gaucha imapd[28824]: imap service init from 200.255.5.8 +May 7 14:00:53 gaucha imapd[28824]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:00:53 gaucha imapd[28824]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:00:54 gaucha imapd[28821]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:00:57 gaucha imapd[28821]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:00 gaucha imapd[28821]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:00 gaucha imapd[28821]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:04 gaucha imapd[28827]: imap service init from 200.255.5.8 +May 7 14:01:04 gaucha imapd[28827]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:04 gaucha imapd[28827]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:27 gaucha imapd[28910]: imap service init from 200.255.5.8 +May 7 14:01:27 gaucha imapd[28910]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:27 gaucha imapd[28910]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:31 gaucha imapd[28912]: imap service init from 200.255.5.8 +May 7 14:01:34 gaucha imapd[28912]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:37 gaucha imapd[28912]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:40 gaucha imapd[28912]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:40 gaucha imapd[28912]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:50 gaucha imapd[28938]: imap service init from 200.255.5.8 +May 7 14:01:50 gaucha imapd[28938]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:01:50 gaucha imapd[28938]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:07 gaucha imapd[28959]: imap service init from 200.255.5.8 +May 7 14:02:10 gaucha imapd[28959]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:11 gaucha imapd[28968]: imap service init from 200.255.5.8 +May 7 14:02:11 gaucha imapd[28968]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:11 gaucha imapd[28968]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:13 gaucha imapd[28959]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:16 gaucha imapd[28959]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:16 gaucha imapd[28959]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:16 gaucha imapd[28977]: imap service init from 200.255.5.8 +May 7 14:02:18 gaucha imapd[28978]: imap service init from 200.255.5.8 +May 7 14:02:18 gaucha imapd[28978]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:18 gaucha imapd[28978]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:19 gaucha imapd[28977]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:22 gaucha imapd[28977]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:25 gaucha imapd[28977]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:25 gaucha imapd[28977]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:25 gaucha imapd[28988]: imap service init from 200.255.5.8 +May 7 14:02:28 gaucha imapd[28988]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:31 gaucha imapd[28988]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:34 gaucha imapd[28988]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:34 gaucha imapd[28988]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:42 gaucha imapd[29001]: imap service init from 200.255.5.8 +May 7 14:02:42 gaucha imapd[29001]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:02:42 gaucha imapd[29001]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:03:44 gaucha imapd[29105]: imap service init from 200.255.5.8 +May 7 14:03:44 gaucha imapd[29105]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:03:44 gaucha imapd[29105]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:04:25 gaucha imapd[29565]: imap service init from 200.255.5.8 +May 7 14:04:25 gaucha imapd[29565]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:04:25 gaucha imapd[29565]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:05:14 gaucha imapd[29645]: imap service init from 200.255.5.8 +May 7 14:05:14 gaucha imapd[29645]: Authenticated user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:05:14 gaucha imapd[29645]: Logout user=acp host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:34 gaucha imapd[30752]: imap service init from 200.255.5.8 +May 7 14:18:34 gaucha imapd[30752]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:34 gaucha imapd[30752]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:34 gaucha imapd[30754]: imap service init from 200.255.5.8 +May 7 14:18:34 gaucha imapd[30754]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:43 gaucha imapd[30754]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:47 gaucha imapd[30766]: imap service init from 200.255.5.8 +May 7 14:18:47 gaucha imapd[30766]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:48 gaucha imapd[30766]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:55 gaucha imapd[30769]: imap service init from 200.255.5.8 +May 7 14:18:55 gaucha imapd[30769]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:55 gaucha imapd[30769]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:56 gaucha imapd[30772]: imap service init from 200.255.5.8 +May 7 14:18:56 gaucha imapd[30772]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:18:59 gaucha imapd[30772]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:19:03 gaucha imapd[30779]: imap service init from 200.255.5.8 +May 7 14:19:03 gaucha imapd[30779]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:19:04 gaucha imapd[30779]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:19:30 gaucha imapd[30793]: imap service init from 200.255.5.8 +May 7 14:19:30 gaucha imapd[30793]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:19:30 gaucha imapd[30793]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:19:46 gaucha imapd[30813]: imap service init from 200.255.5.8 +May 7 14:19:46 gaucha imapd[30813]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:19:46 gaucha imapd[30813]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:20:04 gaucha imapd[30831]: imap service init from 200.255.5.8 +May 7 14:20:04 gaucha imapd[30831]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:20:04 gaucha imapd[30831]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:21:52 gaucha imapd[31001]: imap service init from 200.255.5.8 +May 7 14:21:52 gaucha imapd[31001]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:21:52 gaucha imapd[31001]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:26:30 gaucha imapd[31461]: imap service init from 200.255.5.8 +May 7 14:26:33 gaucha imapd[31461]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:26:39 gaucha imapd[31461]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:26:45 gaucha imapd[31480]: imap service init from 200.255.5.8 +May 7 14:26:45 gaucha imapd[31480]: Authenticated user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:26:45 gaucha imapd[31480]: Logout user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:26:45 gaucha imapd[31481]: imap service init from 200.255.5.8 +May 7 14:26:45 gaucha imapd[31481]: Authenticated user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:26:45 gaucha imapd[31481]: Logout user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:08 gaucha imapd[31495]: imap service init from 200.255.5.8 +May 7 14:27:08 gaucha imapd[31495]: Authenticated user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:08 gaucha imapd[31495]: Logout user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:11 gaucha imapd[31497]: imap service init from 200.255.5.8 +May 7 14:27:11 gaucha imapd[31497]: Authenticated user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:11 gaucha imapd[31497]: Logout user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:13 gaucha imapd[31500]: imap service init from 200.255.5.8 +May 7 14:27:13 gaucha imapd[31500]: Authenticated user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:13 gaucha imapd[31500]: Logout user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:55 gaucha imapd[31531]: imap service init from 200.255.5.8 +May 7 14:27:55 gaucha imapd[31531]: Authenticated user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:55 gaucha imapd[31531]: Logout user=blowsky host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:59 gaucha imapd[31542]: imap service init from 200.255.5.8 +May 7 14:27:59 gaucha imapd[31542]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:27:59 gaucha imapd[31542]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:00 gaucha imapd[31543]: imap service init from 200.255.5.8 +May 7 14:28:00 gaucha imapd[31543]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:00 gaucha imapd[31543]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:16 gaucha imapd[31574]: imap service init from 200.255.5.8 +May 7 14:28:16 gaucha imapd[31574]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:16 gaucha imapd[31574]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:20 gaucha imapd[31582]: imap service init from 200.255.5.8 +May 7 14:28:20 gaucha imapd[31582]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:20 gaucha imapd[31582]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:23 gaucha imapd[31588]: imap service init from 200.255.5.8 +May 7 14:28:23 gaucha imapd[31588]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:24 gaucha imapd[31588]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:38 gaucha imapd[31599]: imap service init from 200.255.5.8 +May 7 14:28:38 gaucha imapd[31599]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:38 gaucha imapd[31599]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:41 gaucha imapd[31602]: imap service init from 200.255.5.8 +May 7 14:28:41 gaucha imapd[31602]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:41 gaucha imapd[31602]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:46 gaucha imapd[31605]: imap service init from 200.255.5.8 +May 7 14:28:46 gaucha imapd[31605]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:46 gaucha imapd[31605]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:50 gaucha imapd[31611]: imap service init from 200.255.5.8 +May 7 14:28:50 gaucha imapd[31611]: Authenticated user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:28:50 gaucha imapd[31611]: Logout user=andreiaps host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:11 gaucha imapd[31848]: imap service init from 200.255.5.8 +May 7 14:31:11 gaucha imapd[31848]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:11 gaucha imapd[31848]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:11 gaucha imapd[31849]: imap service init from 200.255.5.8 +May 7 14:31:11 gaucha imapd[31849]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:11 gaucha imapd[31849]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:15 gaucha imapd[31858]: imap service init from 200.255.5.8 +May 7 14:31:15 gaucha imapd[31858]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:15 gaucha imapd[31858]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:24 gaucha imapd[31873]: imap service init from 200.255.5.8 +May 7 14:31:24 gaucha imapd[31873]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:24 gaucha imapd[31873]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:26 gaucha imapd[31875]: imap service init from 200.255.5.8 +May 7 14:31:26 gaucha imapd[31875]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:26 gaucha imapd[31875]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:30 gaucha imapd[31879]: imap service init from 200.255.5.8 +May 7 14:31:30 gaucha imapd[31879]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:30 gaucha imapd[31879]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:32 gaucha imapd[31881]: imap service init from 200.255.5.8 +May 7 14:31:32 gaucha imapd[31881]: Authenticated user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:31:32 gaucha imapd[31881]: Logout user=rhsc host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:00 gaucha imapd[32375]: imap service init from 200.255.5.8 +May 7 14:36:00 gaucha imapd[32375]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:00 gaucha imapd[32375]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:04 gaucha imapd[32381]: imap service init from 200.255.5.8 +May 7 14:36:04 gaucha imapd[32381]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:04 gaucha imapd[32381]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:06 gaucha imapd[32385]: imap service init from 200.255.5.8 +May 7 14:36:06 gaucha imapd[32385]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:06 gaucha imapd[32385]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:15 gaucha imapd[32442]: imap service init from 200.255.5.8 +May 7 14:36:15 gaucha imapd[32442]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:15 gaucha imapd[32442]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:21 gaucha imapd[32443]: imap service init from 200.255.5.8 +May 7 14:36:21 gaucha imapd[32443]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:36:21 gaucha imapd[32443]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:14 gaucha imapd[32479]: imap service init from 200.255.5.8 +May 7 14:37:14 gaucha imapd[32479]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:15 gaucha imapd[32479]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:15 gaucha imapd[32485]: imap service init from 200.255.5.8 +May 7 14:37:15 gaucha imapd[32485]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:15 gaucha imapd[32485]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:18 gaucha imapd[32488]: imap service init from 200.255.5.8 +May 7 14:37:18 gaucha imapd[32488]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:18 gaucha imapd[32488]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:19 gaucha imapd[32489]: imap service init from 200.255.5.8 +May 7 14:37:19 gaucha imapd[32489]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:19 gaucha imapd[32489]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:20 gaucha imapd[32493]: imap service init from 200.255.5.8 +May 7 14:37:20 gaucha imapd[32493]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:20 gaucha imapd[32493]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:20 gaucha imapd[32494]: imap service init from 200.255.5.8 +May 7 14:37:20 gaucha imapd[32494]: Authenticated user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:20 gaucha imapd[32494]: Logout user=solaris host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:25 gaucha imapd[32502]: imap service init from 200.255.5.8 +May 7 14:37:25 gaucha imapd[32502]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:25 gaucha imapd[32502]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:25 gaucha imapd[32503]: imap service init from 200.255.5.8 +May 7 14:37:25 gaucha imapd[32503]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:25 gaucha imapd[32503]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:34 gaucha imapd[32508]: imap service init from 200.255.5.8 +May 7 14:37:34 gaucha imapd[32508]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:34 gaucha imapd[32508]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:34 gaucha imapd[32509]: imap service init from 200.255.5.8 +May 7 14:37:34 gaucha imapd[32509]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:34 gaucha imapd[32509]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:45 gaucha imapd[32520]: imap service init from 200.255.5.8 +May 7 14:37:45 gaucha imapd[32520]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:37:45 gaucha imapd[32520]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:22 gaucha imapd[32552]: imap service init from 200.255.5.8 +May 7 14:38:22 gaucha imapd[32552]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:22 gaucha imapd[32552]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:25 gaucha imapd[32555]: imap service init from 200.255.5.8 +May 7 14:38:28 gaucha imapd[32555]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:31 gaucha imapd[32555]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:34 gaucha imapd[32555]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:34 gaucha imapd[32555]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:38 gaucha imapd[32574]: imap service init from 200.255.5.8 +May 7 14:38:38 gaucha imapd[32574]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:38 gaucha imapd[32574]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:47 gaucha imapd[32590]: imap service init from 200.255.5.8 +May 7 14:38:47 gaucha imapd[32590]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:47 gaucha imapd[32590]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:48 gaucha imapd[32591]: imap service init from 200.255.5.8 +May 7 14:38:48 gaucha imapd[32591]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:38:49 gaucha imapd[32591]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:39:20 gaucha imapd[32640]: imap service init from 200.255.5.8 +May 7 14:39:20 gaucha imapd[32640]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:39:21 gaucha imapd[32640]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:39:26 gaucha imapd[32648]: imap service init from 200.255.5.8 +May 7 14:39:26 gaucha imapd[32648]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:39:26 gaucha imapd[32648]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:06 gaucha imapd[32713]: imap service init from 200.255.5.8 +May 7 14:40:06 gaucha imapd[32713]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:06 gaucha imapd[32713]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:07 gaucha imapd[32716]: imap service init from 200.255.5.8 +May 7 14:40:07 gaucha imapd[32716]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:07 gaucha imapd[32716]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:11 gaucha imapd[32717]: imap service init from 200.255.5.8 +May 7 14:40:11 gaucha imapd[32717]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:12 gaucha imapd[32717]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:18 gaucha imapd[32729]: imap service init from 200.255.5.8 +May 7 14:40:18 gaucha imapd[32729]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:18 gaucha imapd[32729]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:24 gaucha imapd[32733]: imap service init from 200.255.5.8 +May 7 14:40:24 gaucha imapd[32733]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:24 gaucha imapd[32733]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:25 gaucha imapd[32734]: imap service init from 200.255.5.8 +May 7 14:40:25 gaucha imapd[32734]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:25 gaucha imapd[32734]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:41 gaucha imapd[32750]: imap service init from 200.255.5.8 +May 7 14:40:41 gaucha imapd[32750]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:41 gaucha imapd[32750]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:54 gaucha imapd[32766]: imap service init from 200.255.5.8 +May 7 14:40:54 gaucha imapd[32766]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:54 gaucha imapd[32766]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:58 gaucha imapd[304]: imap service init from 200.255.5.8 +May 7 14:40:58 gaucha imapd[304]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:59 gaucha imapd[304]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:59 gaucha imapd[309]: imap service init from 200.255.5.8 +May 7 14:40:59 gaucha imapd[309]: Authenticated user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:40:59 gaucha imapd[309]: Logout user=sergiogrl host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:03 gaucha imapd[311]: imap service init from 200.255.5.8 +May 7 14:41:03 gaucha imapd[311]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:03 gaucha imapd[311]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:14 gaucha imapd[341]: imap service init from 200.255.5.8 +May 7 14:41:14 gaucha imapd[341]: Authenticated user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:14 gaucha imapd[341]: Logout user=lhalpern host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:22 gaucha imapd[352]: imap service init from 200.255.5.8 +May 7 14:41:22 gaucha imapd[352]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:22 gaucha imapd[352]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:32 gaucha imapd[367]: imap service init from 200.255.5.8 +May 7 14:41:32 gaucha imapd[367]: Authenticated user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:41:32 gaucha imapd[367]: Logout user=wrs host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:37 gaucha imapd[1357]: imap service init from 200.255.5.8 +May 7 14:50:37 gaucha imapd[1357]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:37 gaucha imapd[1357]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:37 gaucha imapd[1359]: imap service init from 200.255.5.8 +May 7 14:50:37 gaucha imapd[1359]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:38 gaucha imapd[1359]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:49 gaucha imapd[1380]: imap service init from 200.255.5.8 +May 7 14:50:49 gaucha imapd[1380]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:49 gaucha imapd[1380]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:58 gaucha imapd[1390]: imap service init from 200.255.5.8 +May 7 14:50:58 gaucha imapd[1390]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:50:58 gaucha imapd[1390]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:51:05 gaucha imapd[1456]: imap service init from 200.255.5.8 +May 7 14:51:05 gaucha imapd[1456]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:51:05 gaucha imapd[1456]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:51:10 gaucha imapd[1466]: imap service init from 200.255.5.8 +May 7 14:51:10 gaucha imapd[1466]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:51:10 gaucha imapd[1466]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:51:19 gaucha imapd[1540]: imap service init from 200.255.5.8 +May 7 14:51:19 gaucha imapd[1540]: Authenticated user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:51:19 gaucha imapd[1540]: Logout user=raphaelv host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:55:51 gaucha imapd[2016]: imap service init from 200.255.5.8 +May 7 14:55:51 gaucha imapd[2016]: Authenticated user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:55:51 gaucha imapd[2016]: Logout user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:55:52 gaucha imapd[2019]: imap service init from 200.255.5.8 +May 7 14:55:52 gaucha imapd[2019]: Authenticated user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:55:52 gaucha imapd[2019]: Logout user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:56:26 gaucha imapd[2103]: imap service init from 200.255.5.8 +May 7 14:56:26 gaucha imapd[2103]: Authenticated user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:56:26 gaucha imapd[2103]: Logout user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:56:28 gaucha imapd[2108]: imap service init from 200.255.5.8 +May 7 14:56:28 gaucha imapd[2108]: Authenticated user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 14:56:28 gaucha imapd[2108]: Logout user=niguna host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:10 gaucha imapd[2571]: imap service init from 200.255.5.8 +May 7 15:01:10 gaucha imapd[2571]: Authenticated user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:10 gaucha imapd[2571]: Logout user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:11 gaucha imapd[2574]: imap service init from 200.255.5.8 +May 7 15:01:11 gaucha imapd[2574]: Authenticated user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:12 gaucha imapd[2574]: Logout user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:17 gaucha imapd[2579]: imap service init from 200.255.5.8 +May 7 15:01:17 gaucha imapd[2579]: Authenticated user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:17 gaucha imapd[2579]: Logout user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:20 gaucha imapd[2583]: imap service init from 200.255.5.8 +May 7 15:01:20 gaucha imapd[2583]: Authenticated user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:20 gaucha imapd[2583]: Logout user=sil host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:21 gaucha imapd[2586]: imap service init from 200.255.5.8 +May 7 15:01:21 gaucha imapd[2586]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:21 gaucha imapd[2586]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:23 gaucha imapd[2591]: imap service init from 200.255.5.8 +May 7 15:01:23 gaucha imapd[2591]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:32 gaucha imapd[2591]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:45 gaucha imapd[2622]: imap service init from 200.255.5.8 +May 7 15:01:45 gaucha imapd[2622]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:01:45 gaucha imapd[2622]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:27 gaucha imapd[2694]: imap service init from 200.255.5.8 +May 7 15:02:27 gaucha imapd[2694]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:27 gaucha imapd[2694]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:32 gaucha imapd[2704]: imap service init from 200.255.5.8 +May 7 15:02:32 gaucha imapd[2704]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:32 gaucha imapd[2704]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:39 gaucha imapd[2707]: imap service init from 200.255.5.8 +May 7 15:02:39 gaucha imapd[2707]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:39 gaucha imapd[2707]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:51 gaucha imapd[2716]: imap service init from 200.255.5.8 +May 7 15:02:51 gaucha imapd[2716]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:02:51 gaucha imapd[2716]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:00 gaucha imapd[2723]: imap service init from 200.255.5.8 +May 7 15:03:00 gaucha imapd[2723]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:00 gaucha imapd[2723]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:22 gaucha imapd[2760]: imap service init from 200.255.5.8 +May 7 15:03:22 gaucha imapd[2760]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:22 gaucha imapd[2760]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:27 gaucha imapd[2765]: imap service init from 200.255.5.8 +May 7 15:03:27 gaucha imapd[2765]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:28 gaucha imapd[2765]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:50 gaucha imapd[2787]: imap service init from 200.255.5.8 +May 7 15:03:50 gaucha imapd[2787]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:50 gaucha imapd[2787]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:57 gaucha imapd[2802]: imap service init from 200.255.5.8 +May 7 15:03:57 gaucha imapd[2802]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:03:57 gaucha imapd[2802]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:04:01 gaucha imapd[2806]: imap service init from 200.255.5.8 +May 7 15:04:01 gaucha imapd[2806]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:04:03 gaucha imapd[2806]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:04:26 gaucha imapd[2846]: imap service init from 200.255.5.8 +May 7 15:04:26 gaucha imapd[2846]: Authenticated user=tupa8 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:04:26 gaucha imapd[2846]: Logout user=tupa8 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:04:26 gaucha imapd[2847]: imap service init from 200.255.5.8 +May 7 15:04:26 gaucha imapd[2847]: Authenticated user=tupa8 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:04:26 gaucha imapd[2847]: Logout user=tupa8 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:38 gaucha imapd[2983]: imap service init from 200.255.5.8 +May 7 15:06:38 gaucha imapd[2983]: Authenticated user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:38 gaucha imapd[2983]: Logout user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:38 gaucha imapd[2984]: imap service init from 200.255.5.8 +May 7 15:06:38 gaucha imapd[2984]: Authenticated user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:38 gaucha imapd[2984]: Logout user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:43 gaucha imapd[2985]: imap service init from 200.255.5.8 +May 7 15:06:43 gaucha imapd[2985]: Authenticated user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:43 gaucha imapd[2985]: Logout user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:43 gaucha imapd[2986]: imap service init from 200.255.5.8 +May 7 15:06:43 gaucha imapd[2986]: Authenticated user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:43 gaucha imapd[2986]: Logout user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:43 gaucha imapd[2987]: imap service init from 200.255.5.8 +May 7 15:06:44 gaucha imapd[2987]: Authenticated user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:06:44 gaucha imapd[2987]: Logout user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:07:14 gaucha imapd[2999]: imap service init from 200.255.5.8 +May 7 15:07:14 gaucha imapd[2999]: Authenticated user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:07:15 gaucha imapd[2999]: Logout user=sesan host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:07:22 gaucha imapd[3001]: imap service init from 200.255.5.8 +May 7 15:07:22 gaucha imapd[3001]: Authenticated user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:07:22 gaucha imapd[3001]: Logout user=estudio host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:06 gaucha imapd[3166]: imap service init from 200.255.5.8 +May 7 15:09:06 gaucha imapd[3166]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:06 gaucha imapd[3166]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:07 gaucha imapd[3169]: imap service init from 200.255.5.8 +May 7 15:09:07 gaucha imapd[3169]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:07 gaucha imapd[3169]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:26 gaucha imapd[3187]: imap service init from 200.255.5.8 +May 7 15:09:26 gaucha imapd[3187]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:26 gaucha imapd[3187]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:29 gaucha imapd[3188]: imap service init from 200.255.5.8 +May 7 15:09:29 gaucha imapd[3188]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:29 gaucha imapd[3188]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:32 gaucha imapd[3191]: imap service init from 200.255.5.8 +May 7 15:09:32 gaucha imapd[3191]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:09:32 gaucha imapd[3191]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:22 gaucha imapd[3259]: imap service init from 200.255.5.8 +May 7 15:10:22 gaucha imapd[3259]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:22 gaucha imapd[3259]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:31 gaucha imapd[3263]: imap service init from 200.255.5.8 +May 7 15:10:31 gaucha imapd[3263]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:31 gaucha imapd[3263]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:39 gaucha imapd[3273]: imap service init from 200.255.5.8 +May 7 15:10:39 gaucha imapd[3273]: Authenticated user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:39 gaucha imapd[3273]: Logout user=rfonseca host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:40 gaucha imapd[3275]: imap service init from 200.255.5.8 +May 7 15:10:40 gaucha imapd[3275]: Authenticated user=leobarroso host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:40 gaucha imapd[3275]: Logout user=leobarroso host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:41 gaucha imapd[3276]: imap service init from 200.255.5.8 +May 7 15:10:41 gaucha imapd[3276]: Authenticated user=leobarroso host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:41 gaucha imapd[3276]: Logout user=leobarroso host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:58 gaucha imapd[3283]: imap service init from 200.255.5.8 +May 7 15:10:58 gaucha imapd[3283]: Authenticated user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:59 gaucha imapd[3283]: Logout user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:59 gaucha imapd[3285]: imap service init from 200.255.5.8 +May 7 15:10:59 gaucha imapd[3285]: Authenticated user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:10:59 gaucha imapd[3285]: Logout user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:11:06 gaucha imapd[3290]: imap service init from 200.255.5.8 +May 7 15:11:06 gaucha imapd[3290]: Authenticated user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:11:06 gaucha imapd[3290]: Logout user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:13:03 gaucha imapd[3386]: imap service init from 200.255.5.8 +May 7 15:13:03 gaucha imapd[3386]: Authenticated user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:13:03 gaucha imapd[3386]: Logout user=ceopenedo4 host=bahiana.resenet.com.br [200.255.5.8] +May 7 15:14:04 gaucha imapd[3455]: imap service init from 200.255.5.8 +May 7 15:14:04 gaucha imapd[3455]: Authenticated user=ceopenedo4 host=bahiana.resenet.com.br +May 9 07:22:56 gaucha imapd[13648]: Logout user=marciabernardes host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:23:45 gaucha imapd[13784]: imap service init from 200.255.5.8 +May 9 07:23:45 gaucha imapd[13784]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:23:45 gaucha imapd[13784]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:23:45 gaucha imapd[13785]: imap service init from 200.255.5.8 +May 9 07:23:45 gaucha imapd[13785]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:23:47 gaucha imapd[13785]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:23:53 gaucha imapd[13795]: imap service init from 200.255.5.8 +May 9 07:23:53 gaucha imapd[13795]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:23:53 gaucha imapd[13795]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:01 gaucha imapd[13816]: imap service init from 200.255.5.8 +May 9 07:24:01 gaucha imapd[13816]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:01 gaucha imapd[13816]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:04 gaucha imapd[13824]: imap service init from 200.255.5.8 +May 9 07:24:04 gaucha imapd[13824]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:04 gaucha imapd[13824]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:06 gaucha imapd[13825]: imap service init from 200.255.5.8 +May 9 07:24:06 gaucha imapd[13825]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:06 gaucha imapd[13825]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:14 gaucha imapd[13897]: imap service init from 200.255.5.8 +May 9 07:24:14 gaucha imapd[13897]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:24:14 gaucha imapd[13897]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:25:46 gaucha imapd[14162]: imap service init from 200.255.5.8 +May 9 07:25:46 gaucha imapd[14162]: Authenticated user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:25:46 gaucha imapd[14162]: Logout user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:25:46 gaucha imapd[14164]: imap service init from 200.255.5.8 +May 9 07:25:46 gaucha imapd[14164]: Authenticated user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:25:47 gaucha imapd[14164]: Logout user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:03 gaucha imapd[14186]: imap service init from 200.255.5.8 +May 9 07:26:03 gaucha imapd[14186]: Authenticated user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:03 gaucha imapd[14186]: Logout user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:04 gaucha imapd[14190]: imap service init from 200.255.5.8 +May 9 07:26:04 gaucha imapd[14190]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:05 gaucha imapd[14190]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:07 gaucha imapd[14249]: imap service init from 200.255.5.8 +May 9 07:26:07 gaucha imapd[14249]: Authenticated user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:07 gaucha imapd[14249]: Logout user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:10 gaucha imapd[14307]: imap service init from 200.255.5.8 +May 9 07:26:10 gaucha imapd[14307]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:10 gaucha imapd[14307]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:13 gaucha imapd[14316]: imap service init from 200.255.5.8 +May 9 07:26:13 gaucha imapd[14316]: Authenticated user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:13 gaucha imapd[14316]: Logout user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:13 gaucha imapd[14318]: imap service init from 200.255.5.8 +May 9 07:26:13 gaucha imapd[14318]: Authenticated user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:14 gaucha imapd[14318]: Logout user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:16 gaucha imapd[14322]: imap service init from 200.255.5.8 +May 9 07:26:16 gaucha imapd[14322]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:16 gaucha imapd[14322]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:46 gaucha imapd[14421]: imap service init from 200.255.5.8 +May 9 07:26:46 gaucha imapd[14421]: Authenticated user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:46 gaucha imapd[14421]: Logout user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:48 gaucha imapd[14422]: imap service init from 200.255.5.8 +May 9 07:26:48 gaucha imapd[14422]: Authenticated user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:48 gaucha imapd[14422]: Logout user=nicolau host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:53 gaucha imapd[14432]: imap service init from 200.255.5.8 +May 9 07:26:53 gaucha imapd[14432]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:26:53 gaucha imapd[14432]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:27:01 gaucha imapd[14452]: imap service init from 200.255.5.8 +May 9 07:27:01 gaucha imapd[14452]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:27:01 gaucha imapd[14452]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:27:07 gaucha imapd[14463]: imap service init from 200.255.5.8 +May 9 07:27:07 gaucha imapd[14463]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:27:07 gaucha imapd[14463]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:27:20 gaucha imapd[14492]: imap service init from 200.255.5.8 +May 9 07:27:20 gaucha imapd[14492]: Authenticated user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:27:21 gaucha imapd[14492]: Logout user=robertoferraz host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:28:03 gaucha imapd[14618]: imap service init from 200.255.5.8 +May 9 07:28:03 gaucha imapd[14618]: Authenticated user=tetedias host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:28:03 gaucha imapd[14618]: Logout user=tetedias host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:28:18 gaucha imapd[14644]: imap service init from 200.255.5.8 +May 9 07:28:18 gaucha imapd[14644]: Authenticated user=tetedias host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:28:18 gaucha imapd[14644]: Logout user=tetedias host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:28:19 gaucha imapd[14649]: imap service init from 200.255.5.8 +May 9 07:28:19 gaucha imapd[14649]: Authenticated user=tetedias host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:28:19 gaucha imapd[14649]: Logout user=tetedias host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:02 gaucha imapd[15751]: imap service init from 200.255.5.8 +May 9 07:36:02 gaucha imapd[15751]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:02 gaucha imapd[15751]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:03 gaucha imapd[15752]: imap service init from 200.255.5.8 +May 9 07:36:03 gaucha imapd[15752]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:06 gaucha imapd[15752]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:09 gaucha imapd[15763]: imap service init from 200.255.5.8 +May 9 07:36:09 gaucha imapd[15763]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:09 gaucha imapd[15763]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:19 gaucha imapd[15782]: imap service init from 200.255.5.8 +May 9 07:36:19 gaucha imapd[15782]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:19 gaucha imapd[15782]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:33 gaucha imapd[15805]: imap service init from 200.255.5.8 +May 9 07:36:33 gaucha imapd[15805]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:33 gaucha imapd[15805]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:39 gaucha imapd[15811]: imap service init from 200.255.5.8 +May 9 07:36:39 gaucha imapd[15811]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:40 gaucha imapd[15811]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:42 gaucha imapd[15817]: imap service init from 200.255.5.8 +May 9 07:36:42 gaucha imapd[15817]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:36:42 gaucha imapd[15817]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:37:21 gaucha imapd[15954]: imap service init from 200.255.5.8 +May 9 07:37:21 gaucha imapd[15954]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:37:21 gaucha imapd[15954]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:00 gaucha imapd[16051]: imap service init from 200.255.5.8 +May 9 07:38:00 gaucha imapd[16051]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:01 gaucha imapd[16051]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:01 gaucha imapd[16053]: imap service init from 200.255.5.8 +May 9 07:38:01 gaucha imapd[16053]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:01 gaucha imapd[16053]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:14 gaucha imapd[16081]: imap service init from 200.255.5.8 +May 9 07:38:14 gaucha imapd[16081]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:14 gaucha imapd[16081]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:17 gaucha imapd[16139]: imap service init from 200.255.5.8 +May 9 07:38:17 gaucha imapd[16139]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:17 gaucha imapd[16139]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:19 gaucha imapd[16151]: imap service init from 200.255.5.8 +May 9 07:38:19 gaucha imapd[16151]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:19 gaucha imapd[16151]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:22 gaucha imapd[16207]: imap service init from 200.255.5.8 +May 9 07:38:22 gaucha imapd[16207]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:22 gaucha imapd[16207]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:31 gaucha imapd[16229]: imap service init from 200.255.5.8 +May 9 07:38:31 gaucha imapd[16229]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:31 gaucha imapd[16229]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:33 gaucha imapd[16237]: imap service init from 200.255.5.8 +May 9 07:38:33 gaucha imapd[16237]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:33 gaucha imapd[16237]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:36 gaucha imapd[16240]: imap service init from 200.255.5.8 +May 9 07:38:36 gaucha imapd[16240]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:36 gaucha imapd[16240]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:48 gaucha imapd[16260]: imap service init from 200.255.5.8 +May 9 07:38:48 gaucha imapd[16260]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:48 gaucha imapd[16260]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:54 gaucha imapd[16277]: imap service init from 200.255.5.8 +May 9 07:38:54 gaucha imapd[16277]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:54 gaucha imapd[16277]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:58 gaucha imapd[16286]: imap service init from 200.255.5.8 +May 9 07:38:58 gaucha imapd[16286]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:38:58 gaucha imapd[16286]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:05 gaucha imapd[16297]: imap service init from 200.255.5.8 +May 9 07:39:05 gaucha imapd[16297]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:05 gaucha imapd[16297]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:07 gaucha imapd[16301]: imap service init from 200.255.5.8 +May 9 07:39:07 gaucha imapd[16301]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:07 gaucha imapd[16301]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:08 gaucha imapd[16302]: imap service init from 200.255.5.8 +May 9 07:39:08 gaucha imapd[16302]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:09 gaucha imapd[16302]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:10 gaucha imapd[16304]: imap service init from 200.255.5.8 +May 9 07:39:10 gaucha imapd[16304]: Authenticated user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:10 gaucha imapd[16304]: Logout user=dsf host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:16 gaucha imapd[16315]: imap service init from 200.255.5.8 +May 9 07:39:16 gaucha imapd[16315]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:16 gaucha imapd[16315]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:51 gaucha imapd[16397]: imap service init from 200.255.5.8 +May 9 07:39:51 gaucha imapd[16397]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:51 gaucha imapd[16397]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:54 gaucha imapd[16404]: imap service init from 200.255.5.8 +May 9 07:39:54 gaucha imapd[16404]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:39:54 gaucha imapd[16404]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:40:20 gaucha imapd[16514]: imap service init from 200.255.5.8 +May 9 07:40:20 gaucha imapd[16514]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:40:20 gaucha imapd[16514]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:40:22 gaucha imapd[16524]: imap service init from 200.255.5.8 +May 9 07:40:22 gaucha imapd[16524]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:40:22 gaucha imapd[16524]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:40:45 gaucha imapd[16638]: imap service init from 200.255.5.8 +May 9 07:40:45 gaucha imapd[16638]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:40:45 gaucha imapd[16638]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:11 gaucha imapd[16683]: imap service init from 200.255.5.8 +May 9 07:41:11 gaucha imapd[16683]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:11 gaucha imapd[16683]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:21 gaucha imapd[16703]: imap service init from 200.255.5.8 +May 9 07:41:21 gaucha imapd[16703]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:21 gaucha imapd[16703]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:24 gaucha imapd[16713]: imap service init from 200.255.5.8 +May 9 07:41:24 gaucha imapd[16713]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:28 gaucha imapd[16713]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:40 gaucha imapd[16789]: imap service init from 200.255.5.8 +May 9 07:41:40 gaucha imapd[16789]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:40 gaucha imapd[16789]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:57 gaucha imapd[16821]: imap service init from 200.255.5.8 +May 9 07:41:57 gaucha imapd[16821]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:41:58 gaucha imapd[16821]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:21 gaucha imapd[16892]: imap service init from 200.255.5.8 +May 9 07:42:21 gaucha imapd[16892]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:21 gaucha imapd[16892]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:22 gaucha imapd[16897]: imap service init from 200.255.5.8 +May 9 07:42:22 gaucha imapd[16897]: Authenticated user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:22 gaucha imapd[16897]: Logout user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:28 gaucha imapd[16900]: imap service init from 200.255.5.8 +May 9 07:42:28 gaucha imapd[16900]: Authenticated user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:28 gaucha imapd[16900]: Logout user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:51 gaucha imapd[16993]: imap service init from 200.255.5.8 +May 9 07:42:51 gaucha imapd[16993]: Authenticated user=bedan host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:51 gaucha imapd[16993]: Logout user=bedan host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:42:58 gaucha imapd[17002]: imap service init from 200.255.5.8 +May 9 07:42:58 gaucha imapd[17002]: Authenticated user=bedan host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:43:04 gaucha imapd[17002]: Logout user=bedan host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:43:56 gaucha imapd[17079]: imap service init from 200.255.5.8 +May 9 07:43:56 gaucha imapd[17079]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:43:57 gaucha imapd[17079]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:00 gaucha imapd[17086]: imap service init from 200.255.5.8 +May 9 07:44:00 gaucha imapd[17086]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:01 gaucha imapd[17086]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:08 gaucha imapd[17152]: imap service init from 200.255.5.8 +May 9 07:44:09 gaucha imapd[17152]: Authenticated user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:09 gaucha imapd[17152]: Logout user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:14 gaucha imapd[17161]: imap service init from 200.255.5.8 +May 9 07:44:14 gaucha imapd[17161]: Authenticated user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:14 gaucha imapd[17161]: Logout user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:41 gaucha imapd[17217]: imap service init from 200.255.5.8 +May 9 07:44:41 gaucha imapd[17217]: Authenticated user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:44:41 gaucha imapd[17217]: Logout user=pessoal host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:00 gaucha imapd[17263]: imap service init from 200.255.5.8 +May 9 07:45:00 gaucha imapd[17263]: Authenticated user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:01 gaucha imapd[17263]: Logout user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:21 gaucha imapd[17329]: imap service init from 200.255.5.8 +May 9 07:45:21 gaucha imapd[17329]: Authenticated user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:22 gaucha imapd[17329]: Logout user=noka host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:26 gaucha imapd[17405]: imap service init from 200.255.5.8 +May 9 07:45:29 gaucha imapd[17405]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:32 gaucha imapd[17405]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:35 gaucha imapd[17405]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:35 gaucha imapd[17405]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:39 gaucha imapd[17480]: imap service init from 200.255.5.8 +May 9 07:45:42 gaucha imapd[17480]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:45 gaucha imapd[17480]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:48 gaucha imapd[17480]: AUTHENTICATE LOGIN failure host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:48 gaucha imapd[17480]: Logout user=??? host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:48 gaucha imapd[17488]: imap service init from 200.255.5.8 +May 9 07:45:48 gaucha imapd[17488]: Authenticated user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:48 gaucha imapd[17488]: Logout user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:49 gaucha imapd[17489]: imap service init from 200.255.5.8 +May 9 07:45:49 gaucha imapd[17489]: Authenticated user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:49 gaucha imapd[17490]: imap service init from 200.255.5.8 +May 9 07:45:49 gaucha imapd[17490]: Authenticated user=carolduarte host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:49 gaucha imapd[17490]: Logout user=carolduarte host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:49 gaucha imapd[17489]: Logout user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:49 gaucha imapd[17491]: imap service init from 200.255.5.8 +May 9 07:45:49 gaucha imapd[17491]: Authenticated user=carolduarte host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:52 gaucha imapd[17494]: imap service init from 200.255.5.8 +May 9 07:45:52 gaucha imapd[17494]: Authenticated user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:53 gaucha imapd[17494]: Logout user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:45:59 gaucha imapd[17549]: imap service init from 200.255.5.8 +May 9 07:45:59 gaucha imapd[17549]: Authenticated user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:46:00 gaucha imapd[17549]: Logout user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:46:12 gaucha imapd[17575]: imap service init from 200.255.5.8 +May 9 07:46:12 gaucha imapd[17575]: Authenticated user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:46:12 gaucha imapd[17575]: Logout user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:46:14 gaucha imapd[17577]: imap service init from 200.255.5.8 +May 9 07:46:14 gaucha imapd[17577]: Authenticated user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:46:15 gaucha imapd[17577]: Logout user=hype host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:47:09 gaucha imapd[17491]: Command stream end of file, while reading line user=carolduarte host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:48 gaucha imapd[17978]: imap service init from 200.255.5.8 +May 9 07:48:48 gaucha imapd[17978]: Authenticated user=wald-meister host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:48 gaucha imapd[17978]: Logout user=wald-meister host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:48 gaucha imapd[17979]: imap service init from 200.255.5.8 +May 9 07:48:48 gaucha imapd[17979]: Authenticated user=wald-meister host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:48 gaucha imapd[17979]: Logout user=wald-meister host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:54 gaucha imapd[17985]: imap service init from 200.255.5.8 +May 9 07:48:54 gaucha imapd[17985]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:54 gaucha imapd[17985]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:55 gaucha imapd[17986]: imap service init from 200.255.5.8 +May 9 07:48:55 gaucha imapd[17986]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:48:58 gaucha imapd[17986]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:13 gaucha imapd[18022]: imap service init from 200.255.5.8 +May 9 07:49:13 gaucha imapd[18022]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:13 gaucha imapd[18022]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:17 gaucha imapd[18076]: imap service init from 200.255.5.8 +May 9 07:49:17 gaucha imapd[18076]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:17 gaucha imapd[18076]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:23 gaucha imapd[18094]: imap service init from 200.255.5.8 +May 9 07:49:23 gaucha imapd[18094]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:23 gaucha imapd[18094]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:33 gaucha imapd[18164]: imap service init from 200.255.5.8 +May 9 07:49:33 gaucha imapd[18164]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:33 gaucha imapd[18164]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:39 gaucha imapd[18191]: imap service init from 200.255.5.8 +May 9 07:49:39 gaucha imapd[18191]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:40 gaucha imapd[18191]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:42 gaucha imapd[18199]: imap service init from 200.255.5.8 +May 9 07:49:42 gaucha imapd[18199]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:42 gaucha imapd[18199]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:47 gaucha imapd[18225]: imap service init from 200.255.5.8 +May 9 07:49:47 gaucha imapd[18225]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:49:47 gaucha imapd[18225]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:02 gaucha imapd[18304]: imap service init from 200.255.5.8 +May 9 07:50:02 gaucha imapd[18304]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:02 gaucha imapd[18304]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:05 gaucha imapd[18319]: imap service init from 200.255.5.8 +May 9 07:50:05 gaucha imapd[18319]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:05 gaucha imapd[18319]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:10 gaucha imapd[18350]: imap service init from 200.255.5.8 +May 9 07:50:10 gaucha imapd[18350]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:10 gaucha imapd[18350]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:13 gaucha imapd[18411]: imap service init from 200.255.5.8 +May 9 07:50:13 gaucha imapd[18411]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:13 gaucha imapd[18411]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:16 gaucha imapd[18420]: imap service init from 200.255.5.8 +May 9 07:50:16 gaucha imapd[18420]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:16 gaucha imapd[18420]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:33 gaucha imapd[18508]: imap service init from 200.255.5.8 +May 9 07:50:33 gaucha imapd[18508]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:33 gaucha imapd[18508]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:38 gaucha imapd[18527]: imap service init from 200.255.5.8 +May 9 07:50:38 gaucha imapd[18527]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:38 gaucha imapd[18527]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:57 gaucha imapd[18626]: imap service init from 200.255.5.8 +May 9 07:50:57 gaucha imapd[18626]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:50:57 gaucha imapd[18626]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:04 gaucha imapd[18650]: imap service init from 200.255.5.8 +May 9 07:51:04 gaucha imapd[18650]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:05 gaucha imapd[18650]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:07 gaucha imapd[18670]: imap service init from 200.255.5.8 +May 9 07:51:07 gaucha imapd[18670]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:07 gaucha imapd[18670]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:15 gaucha imapd[18708]: imap service init from 200.255.5.8 +May 9 07:51:15 gaucha imapd[18708]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:15 gaucha imapd[18708]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:57 gaucha imapd[18897]: imap service init from 200.255.5.8 +May 9 07:51:58 gaucha imapd[18897]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:51:58 gaucha imapd[18897]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:52:14 gaucha imapd[18968]: imap service init from 200.255.5.8 +May 9 07:52:14 gaucha imapd[18968]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:52:15 gaucha imapd[18968]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:52:17 gaucha imapd[18986]: imap service init from 200.255.5.8 +May 9 07:52:17 gaucha imapd[18986]: Authenticated user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:52:17 gaucha imapd[18986]: Logout user=lenita host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:53:53 gaucha imapd[19553]: imap service init from 200.255.5.8 +May 9 07:53:53 gaucha imapd[19553]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:53:53 gaucha imapd[19553]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:53:54 gaucha imapd[19558]: imap service init from 200.255.5.8 +May 9 07:53:54 gaucha imapd[19558]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:53:54 gaucha imapd[19558]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:54:24 gaucha imapd[19699]: imap service init from 200.255.5.8 +May 9 07:54:24 gaucha imapd[19699]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:54:24 gaucha imapd[19699]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:54:29 gaucha imapd[19724]: imap service init from 200.255.5.8 +May 9 07:54:29 gaucha imapd[19724]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:54:29 gaucha imapd[19724]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:54:33 gaucha imapd[19747]: imap service init from 200.255.5.8 +May 9 07:54:33 gaucha imapd[19747]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:54:33 gaucha imapd[19747]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:55:07 gaucha imapd[20068]: imap service init from 200.255.5.8 +May 9 07:55:07 gaucha imapd[20068]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:55:07 gaucha imapd[20068]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:55:19 gaucha imapd[20104]: imap service init from 200.255.5.8 +May 9 07:55:19 gaucha imapd[20104]: Authenticated user=valseved host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:55:19 gaucha imapd[20104]: Logout user=valseved host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:55:19 gaucha imapd[20105]: imap service init from 200.255.5.8 +May 9 07:55:19 gaucha imapd[20105]: Authenticated user=valseved host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:55:27 gaucha imapd[20105]: Logout user=valseved host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:56:24 gaucha imapd[20542]: imap service init from 200.255.5.8 +May 9 07:56:24 gaucha imapd[20542]: Authenticated user=valseved host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:56:24 gaucha imapd[20542]: Logout user=valseved host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:06 gaucha imapd[20981]: imap service init from 200.255.5.8 +May 9 07:59:06 gaucha imapd[20981]: Authenticated user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:06 gaucha imapd[20981]: Logout user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:06 gaucha imapd[20982]: imap service init from 200.255.5.8 +May 9 07:59:06 gaucha imapd[20982]: Authenticated user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:09 gaucha imapd[20982]: Logout user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:43 gaucha imapd[21049]: imap service init from 200.255.5.8 +May 9 07:59:43 gaucha imapd[21049]: Authenticated user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:43 gaucha imapd[21049]: Logout user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:43 gaucha imapd[21050]: imap service init from 200.255.5.8 +May 9 07:59:43 gaucha imapd[21050]: Authenticated user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 07:59:43 gaucha imapd[21050]: Logout user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:21 gaucha imapd[21262]: imap service init from 200.255.5.8 +May 9 08:00:21 gaucha imapd[21262]: Authenticated user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:21 gaucha imapd[21262]: Logout user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:23 gaucha imapd[21271]: imap service init from 200.255.5.8 +May 9 08:00:23 gaucha imapd[21271]: Authenticated user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:23 gaucha imapd[21271]: Logout user=auditar host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:37 gaucha imapd[21282]: imap service init from 200.255.5.8 +May 9 08:00:37 gaucha imapd[21282]: Authenticated user=bgr host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:37 gaucha imapd[21282]: Logout user=bgr host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:38 gaucha imapd[21283]: imap service init from 200.255.5.8 +May 9 08:00:38 gaucha imapd[21283]: Authenticated user=bgr host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:38 gaucha imapd[21283]: Logout user=bgr host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:58 gaucha imapd[21362]: imap service init from 200.255.5.8 +May 9 08:00:58 gaucha imapd[21362]: Authenticated user=auditarconsultoria host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:58 gaucha imapd[21362]: Logout user=auditarconsultoria host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:58 gaucha imapd[21363]: imap service init from 200.255.5.8 +May 9 08:00:58 gaucha imapd[21363]: Authenticated user=auditarconsultoria host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:00:58 gaucha imapd[21363]: Logout user=auditarconsultoria host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:28 gaucha imapd[21427]: imap service init from 200.255.5.8 +May 9 08:01:28 gaucha imapd[21427]: Authenticated user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:28 gaucha imapd[21427]: Logout user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:43 gaucha imapd[21459]: imap service init from 200.255.5.8 +May 9 08:01:43 gaucha imapd[21459]: Authenticated user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:43 gaucha imapd[21459]: Logout user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:44 gaucha imapd[21460]: imap service init from 200.255.5.8 +May 9 08:01:44 gaucha imapd[21460]: Authenticated user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:44 gaucha imapd[21460]: Logout user=diretori host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:46 gaucha imapd[21462]: imap service init from 200.255.5.8 +May 9 08:01:46 gaucha imapd[21462]: Authenticated user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:01:47 gaucha imapd[21462]: Logout user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:02:03 gaucha imapd[21486]: imap service init from 200.255.5.8 +May 9 08:02:03 gaucha imapd[21486]: Authenticated user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:02:04 gaucha imapd[21486]: Logout user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:02:05 gaucha imapd[21491]: imap service init from 200.255.5.8 +May 9 08:02:05 gaucha imapd[21491]: Authenticated user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:02:06 gaucha imapd[21491]: Logout user=martti host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:01 gaucha imapd[21603]: imap service init from 200.255.5.8 +May 9 08:03:01 gaucha imapd[21603]: Authenticated user=jurac_lo host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:01 gaucha imapd[21603]: Logout user=jurac_lo host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:02 gaucha imapd[21610]: imap service init from 200.255.5.8 +May 9 08:03:02 gaucha imapd[21610]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:02 gaucha imapd[21610]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:02 gaucha imapd[21611]: imap service init from 200.255.5.8 +May 9 08:03:02 gaucha imapd[21611]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:04 gaucha imapd[21611]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:05 gaucha imapd[21615]: imap service init from 200.255.5.8 +May 9 08:03:06 gaucha imapd[21615]: Authenticated user=jurac_lo host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:06 gaucha imapd[21615]: Logout user=jurac_lo host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:10 gaucha imapd[21620]: imap service init from 200.255.5.8 +May 9 08:03:10 gaucha imapd[21620]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:10 gaucha imapd[21620]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:13 gaucha imapd[21632]: imap service init from 200.255.5.8 +May 9 08:03:13 gaucha imapd[21632]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:13 gaucha imapd[21632]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:28 gaucha imapd[21652]: imap service init from 200.255.5.8 +May 9 08:03:28 gaucha imapd[21652]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:28 gaucha imapd[21652]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:31 gaucha imapd[21658]: imap service init from 200.255.5.8 +May 9 08:03:31 gaucha imapd[21658]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:31 gaucha imapd[21658]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:44 gaucha imapd[21671]: imap service init from 200.255.5.8 +May 9 08:03:44 gaucha imapd[21671]: Authenticated user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:44 gaucha imapd[21671]: Logout user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:55 gaucha imapd[21693]: imap service init from 200.255.5.8 +May 9 08:03:55 gaucha imapd[21693]: Authenticated user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:56 gaucha imapd[21693]: Logout user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:59 gaucha imapd[21695]: imap service init from 200.255.5.8 +May 9 08:03:59 gaucha imapd[21695]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:03:59 gaucha imapd[21695]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:01 gaucha imapd[21699]: imap service init from 200.255.5.8 +May 9 08:04:01 gaucha imapd[21699]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:01 gaucha imapd[21699]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:19 gaucha imapd[21725]: imap service init from 200.255.5.8 +May 9 08:04:19 gaucha imapd[21725]: Authenticated user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:19 gaucha imapd[21725]: Logout user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:23 gaucha imapd[21735]: imap service init from 200.255.5.8 +May 9 08:04:23 gaucha imapd[21735]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:23 gaucha imapd[21735]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:26 gaucha imapd[21743]: imap service init from 200.255.5.8 +May 9 08:04:26 gaucha imapd[21743]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:26 gaucha imapd[21743]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:32 gaucha imapd[21749]: imap service init from 200.255.5.8 +May 9 08:04:32 gaucha imapd[21749]: Authenticated user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:46 gaucha imapd[21749]: Logout user=cooperarh host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:55 gaucha imapd[21881]: imap service init from 200.255.5.8 +May 9 08:04:55 gaucha imapd[21881]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:56 gaucha imapd[21881]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:58 gaucha imapd[21940]: imap service init from 200.255.5.8 +May 9 08:04:58 gaucha imapd[21940]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:04:58 gaucha imapd[21940]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:01 gaucha imapd[21947]: imap service init from 200.255.5.8 +May 9 08:05:01 gaucha imapd[21947]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:01 gaucha imapd[21947]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:05 gaucha imapd[21964]: imap service init from 200.255.5.8 +May 9 08:05:05 gaucha imapd[21964]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:05 gaucha imapd[21964]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:18 gaucha imapd[22030]: imap service init from 200.255.5.8 +May 9 08:05:18 gaucha imapd[22030]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:18 gaucha imapd[22030]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:21 gaucha imapd[22038]: imap service init from 200.255.5.8 +May 9 08:05:21 gaucha imapd[22038]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:22 gaucha imapd[22038]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:24 gaucha imapd[22040]: imap service init from 200.255.5.8 +May 9 08:05:24 gaucha imapd[22040]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:24 gaucha imapd[22040]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:35 gaucha imapd[22057]: imap service init from 200.255.5.8 +May 9 08:05:35 gaucha imapd[22057]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:35 gaucha imapd[22057]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:37 gaucha imapd[22062]: imap service init from 200.255.5.8 +May 9 08:05:37 gaucha imapd[22062]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:37 gaucha imapd[22062]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:40 gaucha imapd[22067]: imap service init from 200.255.5.8 +May 9 08:05:40 gaucha imapd[22067]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:40 gaucha imapd[22067]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:55 gaucha imapd[22140]: imap service init from 200.255.5.8 +May 9 08:05:55 gaucha imapd[22140]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:05:56 gaucha imapd[22140]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:13 gaucha imapd[22167]: imap service init from 200.255.5.8 +May 9 08:06:13 gaucha imapd[22167]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:13 gaucha imapd[22167]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:18 gaucha imapd[22176]: imap service init from 200.255.5.8 +May 9 08:06:18 gaucha imapd[22176]: Authenticated user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:18 gaucha imapd[22176]: Logout user=resenet host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:31 gaucha imapd[22209]: imap service init from 200.255.5.8 +May 9 08:06:31 gaucha imapd[22209]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:31 gaucha imapd[22209]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:31 gaucha imapd[22212]: imap service init from 200.255.5.8 +May 9 08:06:31 gaucha imapd[22212]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:06:43 gaucha imapd[22212]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:32 gaucha imapd[22350]: imap service init from 200.255.5.8 +May 9 08:07:32 gaucha imapd[22350]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:33 gaucha imapd[22350]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:36 gaucha imapd[22355]: imap service init from 200.255.5.8 +May 9 08:07:36 gaucha imapd[22355]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:36 gaucha imapd[22355]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:48 gaucha imapd[22382]: imap service init from 200.255.5.8 +May 9 08:07:48 gaucha imapd[22382]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:48 gaucha imapd[22382]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:48 gaucha imapd[22387]: imap service init from 200.255.5.8 +May 9 08:07:48 gaucha imapd[22387]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:48 gaucha imapd[22387]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:51 gaucha imapd[22395]: imap service init from 200.255.5.8 +May 9 08:07:51 gaucha imapd[22395]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:51 gaucha imapd[22395]: Logout user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:55 gaucha imapd[22401]: imap service init from 200.255.5.8 +May 9 08:07:55 gaucha imapd[22401]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:55 gaucha imapd[22401]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:58 gaucha imapd[22409]: imap service init from 200.255.5.8 +May 9 08:07:58 gaucha imapd[22409]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:07:58 gaucha imapd[22409]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:00 gaucha imapd[22417]: imap service init from 200.255.5.8 +May 9 08:08:00 gaucha imapd[22417]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:00 gaucha imapd[22417]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:09 gaucha imapd[22427]: imap service init from 200.255.5.8 +May 9 08:08:10 gaucha imapd[22427]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:10 gaucha imapd[22427]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:55 gaucha imapd[22498]: imap service init from 200.255.5.8 +May 9 08:08:55 gaucha imapd[22498]: Authenticated user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:55 gaucha imapd[22498]: Logout user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:08:58 gaucha imapd[22502]: imap service init from 200.255.5.8 +May 9 08:08:58 gaucha imapd[22502]: Authenticated user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:04 gaucha imapd[22502]: Logout user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:12 gaucha imapd[22530]: imap service init from 200.255.5.8 +May 9 08:09:12 gaucha imapd[22530]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:13 gaucha imapd[22530]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:14 gaucha imapd[22539]: imap service init from 200.255.5.8 +May 9 08:09:14 gaucha imapd[22539]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:15 gaucha imapd[22539]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:19 gaucha imapd[22600]: imap service init from 200.255.5.8 +May 9 08:09:19 gaucha imapd[22600]: Authenticated user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:19 gaucha imapd[22600]: Logout user=rgmuller host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:24 gaucha imapd[22604]: imap service init from 200.255.5.8 +May 9 08:09:24 gaucha imapd[22604]: Authenticated user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:24 gaucha imapd[22604]: Logout user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:25 gaucha imapd[22606]: imap service init from 200.255.5.8 +May 9 08:09:25 gaucha imapd[22606]: Authenticated user=fonterra host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:26 gaucha imapd[22606]: Logout user=fonterra host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:26 gaucha imapd[22608]: imap service init from 200.255.5.8 +May 9 08:09:26 gaucha imapd[22608]: Authenticated user=fonterra host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:27 gaucha imapd[22608]: Logout user=fonterra host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:51 gaucha imapd[22633]: imap service init from 200.255.5.8 +May 9 08:09:51 gaucha imapd[22633]: Authenticated user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:52 gaucha imapd[22633]: Logout user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:58 gaucha imapd[22650]: imap service init from 200.255.5.8 +May 9 08:09:58 gaucha imapd[22650]: Authenticated user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:09:58 gaucha imapd[22650]: Logout user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:17 gaucha imapd[22800]: imap service init from 200.255.5.8 +May 9 08:10:17 gaucha imapd[22800]: Authenticated user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:17 gaucha imapd[22800]: Logout user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:18 gaucha imapd[22801]: imap service init from 200.255.5.8 +May 9 08:10:18 gaucha imapd[22801]: Authenticated user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:18 gaucha imapd[22801]: Logout user=diegoperes host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:19 gaucha imapd[22805]: imap service init from 200.255.5.8 +May 9 08:10:19 gaucha imapd[22805]: Authenticated user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:20 gaucha imapd[22805]: Logout user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:30 gaucha imapd[22825]: imap service init from 200.255.5.8 +May 9 08:10:30 gaucha imapd[22825]: Authenticated user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:30 gaucha imapd[22825]: Logout user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:38 gaucha imapd[22836]: imap service init from 200.255.5.8 +May 9 08:10:38 gaucha imapd[22836]: Authenticated user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:10:38 gaucha imapd[22836]: Logout user=terabyte host=bahiana.resenet.com.br [200.255.5.8] +May 9 08:11:00 gaucha imapd[22914]: imap service init from 200.255.5.8 +May 9 08:11:00 gaucha imapd[22914]: Authenticated user=claudiadessimoni host=bahiana.resenet.com.br [200.255.5.8] diff --git a/etc/rules/log-entries/kernel b/etc/rules/log-entries/kernel new file mode 100644 index 000000000..82fda3d4c --- /dev/null +++ b/etc/rules/log-entries/kernel @@ -0,0 +1 @@ +kernel: tcp_parse_options: Illegal window scaling value 200 >14 received. diff --git a/etc/rules/log-entries/mail-alerts b/etc/rules/log-entries/mail-alerts new file mode 100644 index 000000000..37afcbc0f --- /dev/null +++ b/etc/rules/log-entries/mail-alerts @@ -0,0 +1,63 @@ +openarmor HIDS Notification. +2006 May 25 17:07:58 + +Received From: (gaucha) 200.255.5.5->/var/log/maillog +Rule: 6254 fired (level 10) -> "Multiple attempts to send e-mail from invalid/unkonown sender domain.'" +Portion of the log(s): + +sm-mta[20900]: k4PK8NYf020900: ruleset=check_mail, arg1=, relay=200-138-41-205.ctame705.dsl.brasiltelecom.net.br [200.138.41.205] (may be forged), reject=553 5.1.8 ... Domain of sender address brbomaquinas@brbom.com does not exist +sm-mta[20881]: k4PK8FOQ020881: ruleset=check_mail, arg1=, relay=200-138-41-205.ctame705.dsl.brasiltelecom.net.br [200.138.41.205] (may be forged), reject=553 5.1.8 ... Domain of sender address brbomaquinas@brbom.com does not exist +sm-mta[20867]: k4PK86E0020867: ruleset=check_mail, arg1=, relay=200-138-41-205.ctame705.dsl.brasiltelecom.net.br [200.138.41.205] (may be forged), reject=553 5.1.8 ... Domain of sender address brbomaquinas@brbom.com does not exist + + + + +openarmor HIDS Notification. +2006 May 25 16:40:15 + +Received From: (gaucha) 200.255.5.5->/var/log/maillog +Rule: 6253 fired (level 10) -> "Multiple relaying attempts for spam.'" +Portion of the log(s): + +sm-mta[14582]: k4PJeY7S014582: ruleset=check_rcpt, arg1=, relay=200-207-91-189.speedycti.com.br [200.207.91.189] (may be forged), reject=550 5.7.1 ... Relaying denied. IP name possibly forged [200.207.91.189] +sm-mta[14582]: k4PJeY7S014582: ruleset=check_rcpt, arg1=, relay=200-207-91-189.speedycti.com.br [200.207.91.189] (may be forged), reject=550 5.7.1 ... Relaying denied. IP name possibly forged [200.207.91.189] +sm-mta[14582]: k4PJeY7S014582: ruleset=check_rcpt, arg1=, relay=200-207-91-189.speedycti.com.br [200.207.91.189] (may be forged), reject=550 5.7.1 ... Relaying denied. IP name possibly forged [200.207.91.189] + + + + --END OF NOTIFICATION + + + +openarmor HIDS Notification. +2006 May 24 20:25:21 + +Received From: (gaucha) 200.255.5.5->/var/log/maillog +Rule: 6253 fired (level 10) -> "Multiple relaying attempts for spam.'" +Portion of the log(s): + +sm-mta[22707]: ruleset=check_relay, arg1=[201.29.120.119], arg2=127.0.0.4, relay=120119.user.veloxzone.com.br [201.29.120.119] (may be forged), reject=550 5.7.1 Rejected: 201.29.120.119 listed at sbl-xbl.spamhaus.org +sm-mta[22675]: ruleset=check_relay, arg1=[201.29.120.119], arg2=127.0.0.4, relay=120119.user.veloxzone.com.br [201.29.120.119] (may be forged), reject=550 5.7.1 Rejected: 201.29.120.119 listed at sbl-xbl.spamhaus.org +sm-mta[22653]: ruleset=check_relay, arg1=[201.29.120.119], arg2=127.0.0.4, relay=120119.user.veloxzone.com.br [201.29.120.119] (may be forged), reject=550 5.7.1 Rejected: 201.29.120.119 listed at sbl-xbl.spamhaus.org +sm-mta[22625]: ruleset=check_relay, arg1=[201.29.120.119], arg2=127.0.0.4, relay=120119.user.veloxzone.com.br [201.29.120.119] (may be forged), reject=550 5.7.1 Rejected: 201.29.120.119 listed at sbl-xbl.spamhaus.org + + + + +openarmor HIDS Notification. +2006 May 25 03:13:08 + +Received From: (gaucha) 200.255.5.5->/var/log/maillog +Rule: 6253 fired (level 10) -> "Multiple relaying attempts for spam.'" +Portion of the log(s): + +sm-mta[21399]: ruleset=check_relay, arg1=[201.24.166.179], arg2=127.0.0.5, relay=201-24-166-179.gnace703.dsl.brasiltelecom.net.br [201.24.166.179] (may be forged), reject=550 5.7.1 Rejected: 201.24.166.179 listed at sbl-xbl.spamhaus.org +sm-mta[21392]: ruleset=check_relay, arg1=[201.24.166.179], arg2=127.0.0.5, relay=201-24-166-179.gnace703.dsl.brasiltelecom.net.br [201.24.166.179] (may be forged), reject=550 5.7.1 Rejected: 201.24.166.179 listed at sbl-xbl.spamhaus.org +sm-mta[21377]: ruleset=check_relay, arg1=[201.24.166.179], arg2=127.0.0.5, relay=201-24-166-179.gnace703.dsl.brasiltelecom.net.br [201.24.166.179] (may be forged), reject=550 5.7.1 Rejected: 201.24.166.179 listed at sbl-xbl.spamhaus.org +sm-mta[21373]: ruleset=check_relay, arg1=[201.24.166.179], arg2=127.0.0.5, relay=201-24-166-179.gnace703.dsl.brasiltelecom.net.br [201.24.166.179] (may be forged), reject=550 5.7.1 Rejected: 201.24.166.179 listed at sbl-xbl.spamhaus.org + + + + --END OF NOTIFICATION + + diff --git a/etc/rules/log-entries/mail-errors b/etc/rules/log-entries/mail-errors new file mode 100644 index 000000000..f2594b8b0 --- /dev/null +++ b/etc/rules/log-entries/mail-errors @@ -0,0 +1,32 @@ +pop3d: authentication error: Input/output error +pop3d: authentication error: Input/output error +postfix/postfix-script: fatal: the Postfix mail system is not running +postfix/postfix-script: fatal: the Postfix mail system is not running + +openarmor HIDS Notification. +2006 May 25 03:50:36 + +Received From: /var/log/maillog +Rule: 102 fired (level 7) -> "Unknown problem somewhere in the system.'" +Portion of the log(s): + + postfix/smtp[8909]: 774C14AEF2: to=, relay=127.0.0.1[127.0.0.1], delay=423, status=deferred (host 127.0.0.1[127.0.0.1] said: 451 Local Error (in reply to end of DATA command)) + + + + --END OF NOTIFICATION + + +openarmor HIDS Notification. +2006 May 25 03:32:34 + +Received From: /var/log/maillog +Rule: 102 fired (level 7) -> "Unknown problem somewhere in the system.'" +Portion of the log(s): + +scorpion postfix/smtp[9144]: connect to rmailb2.walla.co.il[192.118.82.145]: Connection refused (port 25) + + + + --END OF NOTIFICATION + diff --git a/etc/rules/log-entries/ns1 b/etc/rules/log-entries/ns1 new file mode 100644 index 000000000..10e61b4ba --- /dev/null +++ b/etc/rules/log-entries/ns1 @@ -0,0 +1,11 @@ +> 1:Nov 30 18:01:53 xx.xx.xx.xx ns204: NetScreen device_id=ns204 +> [Root]system-critical-00027: 2nd push has been confirmed. (2005-11-30 +> 17:56:44) +> +> 2:Nov 30 18:01:59 xx.xx.xx.xx ns204: NetScreen device_id=ns204 +> [Root]system-critical-00027: Configuration Erase sequence accepted, +> unit reset. (2005-11-30 17:56:50) +> +> 3:Nov 30 18:01:59 xx.xx.xx.xx ns204: NetScreen device_id=ns204 +> [Root]system-notification-00033: NSM keys were deleted. (2005-11-30 +> 17:56:50) diff --git a/etc/rules/log-entries/proftpd b/etc/rules/log-entries/proftpd new file mode 100644 index 000000000..1740ceba7 --- /dev/null +++ b/etc/rules/log-entries/proftpd @@ -0,0 +1,68 @@ +May 21 20:20:44 slacker proftpd[25526] slacker.lab.theopenarmor.org: ProFTPD 1.2.10 (stable) (built Tue Aug 2 22:33:07 PDT 2005) standalone mode STARTUP +May 21 20:21:18 slacker proftpd[25530] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): FTP session opened. +May 21 20:21:21 slacker proftpd[25530] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): no such user 'a' +May 21 20:21:21 slacker proftpd[25530] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): USER a: no such user found from 192.168.2.10 [192.168.2.10] to 192.168.2.32:21 +May 21 20:22:14 slacker proftpd[25530] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): FTP session closed. +May 21 20:22:15 slacker proftpd[25556] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): FTP session opened. +May 21 20:22:28 slacker proftpd[25556] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): USER dcid: Login successful. +May 21 20:22:35 slacker proftpd[25556] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): FTP session closed. +May 21 20:22:42 slacker proftpd[25557] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): FTP session opened. +May 21 20:22:44 slacker proftpd[25557] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): USER dcid (Login failed): Incorrect password. +May 21 20:22:46 slacker proftpd[25557] slacker.lab.theopenarmor.org (192.168.2.10[192.168.2.10]): FTP session closed. + +May 30 14:41:52 valhalla proftpd[11727]: valhalla.ahmetozturk.name.tr (85.103.201.222[85.103.201.222]) - unable to find open port in PassivePorts range 65532-65533: defaulting to INPORT_ANY +May 30 15:39:27 valhalla proftpd[13464]: valhalla.ahmetozturk.name.tr (212.156.175.130[212.156.175.130]) - unable to find open port in PassivePorts range 65532-65533: defaulting to INPORT_ANY + + +May 29 18:49:42 valhalla proftpd[16661]: valhalla.ahmetozturk.name.tr (85.103.107.214[85.103.107.214]) - Refused PORT 192,168,1,33,4,83 (address mismatch) +May 31 13:11:38 valhalla proftpd[10486]: valhalla.ahmetozturk.name.tr (85.102.240.252[85.102.240.252]) - Refused PORT 10,0,65,23,19,139 (address mismatch) + + +Jun 1 11:51:24 valhalla proftpd[7301]: valhalla.ahmetozturk.name.tr (81.215.6.178[81.215.6.178]) - Maximum login attempts (3) exceeded +Jun 1 11:51:24 valhalla proftpd[7301]: valhalla.ahmetozturk.name.tr (81.215.6.178[81.215.6.178]) - Maximum login attempts (3) exceeded + + + +May 29 11:27:28 hayaletgemi proftpd[4874]: warning: host name/name mismatch: www.ahmetozturk.name.tr != nil.alannim.com +Jun 3 07:48:10 hayaletgemi proftpd[1026]: warning: host name/address mismatch: 216.117.134.168 != nameservices.net + + +Jun 2 15:07:14 hayaletgemi proftpd[458988]: warning: can't verify hostname: gethostbyname(designstudio) failed +Jun 3 15:35:28 hayaletgemi proftpd[696376]: warning: can't verify hostname: gethostbyname(dsl.dynamic859612386.ttnet.net.tr) failed + + + +May 30 17:06:40 queen proftpd[1769554]: connect from 212.146.159.45 +May 30 21:46:50 queen proftpd[2142266]: connect from 88.224.90.235 + + +May 30 21:04:35 valhalla proftpd[22104]: valhalla.ahmetozturk.name.tr (85.97.67.160[85.97.67.160]) - FTP no transfer timeout, disconnected +May 30 22:53:09 valhalla proftpd[24395]: valhalla.ahmetozturk.name.tr (88.240.52.97[88.240.52.97]) - FTP no transfer timeout, disconnected + + +May 31 06:50:39 valhalla proftpd[345]: valhalla.ahmetozturk.name.tr (217.20.94.150[217.20.94.150]) - FTP login timed out, disconnected +May 31 15:13:38 valhalla proftpd[14273]: valhalla.ahmetozturk.name.tr (85.104.215.80[85.104.215.80]) - FTP login timed out, disconnected + + + +May 31 11:26:23 valhalla proftpd[6399]: valhalla.ahmetozturk.name.tr (88.226.116.196[88.226.116.196]) - FTP session idle timeout, disconnected. +May 31 13:10:54 valhalla proftpd[8987]: valhalla.ahmetozturk.name.tr (85.104.215.80[85.104.215.80]) - FTP session idle timeout, disconnected. + + +May 30 13:44:57 valhalla proftpd[8521]: valhalla.ahmetozturk.name.tr (84.134.231.103[84.134.231.103]) - Data transfer stall timeout: 3600 seconds +Jun 3 08:24:13 valhalla proftpd[24038]: valhalla.ahmetozturk.name.tr (85.104.252.16[85.104.252.16]) - Data transfer stall timeout: 3600 seconds + + +May 29 15:13:37 whale proftpd[4555]: whale.ahmetozturk.name.tr (dsl85-105-3059.ttnet.net.tr[85.105.10.139]) - ProFTPD terminating (signal 11) +May 29 15:13:53 whale proftpd[4592]: whale.ahmetozturk.name.tr (dsl85-105-3059.ttnet.net.tr[85.105.10.139]) - ProFTPD terminating (signal 11) + + +May 30 17:21:53 whale proftpd[2056246]: whale.ahmetozturk.name.tr (193.140.92.250[193.140.92.250]) - Reallocating sreaddir buffer from 10 entries to 20 entries +May 30 17:21:53 whale proftpd[2056246]: whale.ahmetozturk.name.tr (193.140.92.250[193.140.92.250]) - Reallocating sreaddir buffer from 20 entries to 40 entries +May 30 17:21:53 whale proftpd[2056246]: whale.ahmetozturk.name.tr (193.140.92.250[193.140.92.250]) - Reallocating sreaddir buffer from 40 entries to 80 entries +May 30 17:21:53 whale proftpd[2056246]: whale.ahmetozturk.name.tr (193.140.92.250[193.140.92.250]) - Reallocating sreaddir buffer from 80 entries to 160 entries +May 30 17:21:53 whale proftpd[2056246]: whale.ahmetozturk.name.tr (193.140.92.250[193.140.92.250]) - Reallocating sreaddir buffer from 160 entries to 320 entries + + +May 30 16:22:39 whale proftpd[25749]: whale.ahmetozturk.name.tr (adsl85-105-30850.tt.net.tr[85.105.10.222]) - listen() failed in inet_listen(): Address already in use +May 31 13:21:13 whale proftpd[15942]: whale.ahmetozturk.name.tr (adsl85-105-30850.tt.net.tr[85.105.10.222]) - listen() failed in inet_listen(): Address already in use diff --git a/etc/rules/log-entries/smbd b/etc/rules/log-entries/smbd new file mode 100644 index 000000000..1170bede1 --- /dev/null +++ b/etc/rules/log-entries/smbd @@ -0,0 +1,9 @@ +smbd[12252]: getpeername failed. Error was Transport endpoint is not connected +smbd[12252]: Denied connection from (0.0.0.0) +smbd[12252]: getpeername failed. Error was Transport endpoint is not connected +smbd[12252]: Connection denied from 0.0.0.0 +smbd[12252]: write_socket_data: write failure. Error = Connection reset by peer +smbd[12252]: write_socket: Error writing 5 bytes to socket 5: ERRNO = Connection reset by peer +smbd[12252]: Error writing 5 bytes to client. -1. (Connection reset by peer) +May 31 15:54:18 homesmbsrv smbd[124]: Permission denied-- user not allowed to delete, pause, or resume print job. User name: oahmet. Printer name: prnq1. + diff --git a/etc/rules/log-entries/spamd b/etc/rules/log-entries/spamd new file mode 100644 index 000000000..3fb6d888c --- /dev/null +++ b/etc/rules/log-entries/spamd @@ -0,0 +1,19 @@ +A clean mail: + +Mar 19 08:21:13 h780152 spamd[11565]: connection from localhost [127.0.0.1] at port 49144 +Mar 19 08:21:13 h780152 spamd[11565]: checking message <20060318231614.f9991a2d.johnxj@comcast.net> for root:98. +Mar 19 08:21:14 h780152 spamd[11565]: clean message (0.0/6.0) for root:98 in 1.6 seconds, 3347 bytes. +Mar 19 08:21:14 h780152 spamd[11565]: result: . 0 - AWL,FORGED_RCVD_HELO scantime=1.6,size=3347,mid=<20060318231614.f9991a2d.johnxj@comcast.net>,autolearn=ham +Mar 19 08:21:14 h780152 qmail-scanner[25042]: Clear:RC:0(217.72.192.234):SA:0(0.0/6.0): 1.681359 3302 sylpheed-admin@good-day.net peter@ifup.de [sylpheed:27685]_Sync_two_copies_of_Sylpheed <20060318231614.f9991a2d.johnxj@comcast.net> 1142752873.25044-0.ifup.de:898 + + +and a recognized spam: + +Mar 19 08:36:33 h780152 spamd[18424]: connection from localhost [127.0.0.1] at port 49145 +Mar 19 08:36:33 h780152 spamd[18424]: checking message <3388717865.3821662804@douglas.co.za> for root:98. +Mar 19 08:36:37 h780152 spamd[18424]: identified spam (8.1/6.0) for root:98 in 4.2 seconds, 1432 bytes. +Mar 19 08:36:37 h780152 spamd[18424]: result: Y 8 - FORGED_RCVD_HELO,INFO_TLD,RCVD_BY_IP,RCVD_IN_XBL,URIBL_SBL,URIBL_SC_SURBL,URIBL_WS_SURBL scantime=4.2,size=1432,mid=<3388717865.3821662804@douglas.co.za>,autolearn=no +Mar 19 08:36:37 h780152 qmail-scanner[31528]: Clear:RC:0(213.165.64.100):SA:1(8.1/6.0): 4.195255 1371 srs0=k3bc=5k=douglas.co.za=deonegqf@gmx.net peter@ifup.de $E}{UALLYY_EXPLICIT:_Group_glorious_teens_hardcoore <3388717865.3821662804@douglas.co.za> 1142753793.31530-0.ifup.de:134 + + +Thanks Peter diff --git a/etc/rules/log-entries/sshd b/etc/rules/log-entries/sshd new file mode 100644 index 000000000..e6e7065f1 --- /dev/null +++ b/etc/rules/log-entries/sshd @@ -0,0 +1,345 @@ +Jul 7 10:51:24 eva sshd[19537]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:25 eva sshd[19539]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:26 eva sshd[19542]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:26 eva sshd[19544]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:28 eva sshd[19546]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:28 eva sshd[19548]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:29 eva sshd[19550]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:30 eva sshd[19553]: Invalid user admin from 83.15.231.75 +Jul 7 10:51:31 eva sshd[19555]: Invalid user admin1 from 83.15.231.75 +Jul 7 10:51:32 eva sshd[19557]: Invalid user admin1 from 83.15.231.75 +Jul 7 10:51:33 eva sshd[19559]: Invalid user admin1 from 83.15.231.75 +Jul 7 10:51:34 eva sshd[19561]: Invalid user admin1 from 83.15.231.75 +Jul 7 10:51:35 eva sshd[19564]: Invalid user admin1 from 83.15.231.75 +Jul 7 10:51:36 eva sshd[19566]: Invalid user admin1 from 83.15.231.75 +Jul 7 10:51:37 eva sshd[19568]: Invalid user admin01 from 83.15.231.75 +Jul 7 10:51:38 eva sshd[19570]: Invalid user admin01 from 83.15.231.75 +Jul 7 10:51:39 eva sshd[19572]: Invalid user admin01 from 83.15.231.75 +Jul 7 10:51:40 eva sshd[19574]: Invalid user admin01 from 83.15.231.75 +Jul 7 10:51:41 eva sshd[19577]: Invalid user admin01 from 83.15.231.75 +Jul 7 10:51:42 eva sshd[19579]: Invalid user test from 83.15.231.75 +Jul 7 10:51:43 eva sshd[19581]: Invalid user test from 83.15.231.75 +Jul 7 10:51:44 eva sshd[19583]: Invalid user test from 83.15.231.75 +Jul 7 10:51:45 eva sshd[19585]: Invalid user test from 83.15.231.75 +Jul 7 10:51:45 eva sshd[19588]: Invalid user test from 83.15.231.75 +Jul 7 10:51:46 eva sshd[19590]: Invalid user test from 83.15.231.75 +Jul 7 10:51:47 eva sshd[19592]: Invalid user test from 83.15.231.75 +Jul 7 10:51:48 eva sshd[19594]: Invalid user test1 from 83.15.231.75 +Jul 7 10:51:49 eva sshd[19596]: Invalid user test1 from 83.15.231.75 +Jul 7 10:51:50 eva sshd[19598]: Invalid user test1 from 83.15.231.75 +Jul 7 10:51:51 eva sshd[19601]: Invalid user test1 from 83.15.231.75 +Jul 7 10:51:52 eva sshd[19603]: Invalid user test1 from 83.15.231.75 +Jul 7 10:51:53 eva sshd[19605]: Invalid user test1 from 83.15.231.75 +Jul 7 10:51:54 eva sshd[19607]: Invalid user test01 from 83.15.231.75 +Jul 7 10:51:55 eva sshd[19609]: Invalid user test01 from 83.15.231.75 +Jul 7 10:51:56 eva sshd[19612]: Invalid user test01 from 83.15.231.75 +Jul 7 10:51:56 eva sshd[19614]: Invalid user test01 from 83.15.231.75 +Jul 7 10:51:58 eva sshd[19616]: Invalid user test01 from 83.15.231.75 +Jul 7 10:51:58 eva sshd[19618]: Invalid user test02 from 83.15.231.75 +Jul 7 10:52:00 eva sshd[19620]: Invalid user test02 from 83.15.231.75 +Jul 7 10:52:00 eva sshd[19623]: Invalid user test02 from 83.15.231.75 +Jul 7 10:52:01 eva sshd[19625]: Invalid user test02 from 83.15.231.75 +Jul 7 10:52:02 eva sshd[19627]: Invalid user test02 from 83.15.231.75 +Jul 7 10:52:03 eva sshd[19629]: Invalid user test03 from 83.15.231.75 +Jul 7 10:52:04 eva sshd[19631]: Invalid user test03 from 83.15.231.75 +Jul 7 10:52:05 eva sshd[19633]: Invalid user test03 from 83.15.231.75 +Jul 7 10:52:06 eva sshd[19636]: Invalid user test03 from 83.15.231.75 +Jul 7 10:52:07 eva sshd[19638]: Invalid user test03 from 83.15.231.75 +Jul 7 10:52:08 eva sshd[19640]: Invalid user test04 from 83.15.231.75 +Jul 7 10:52:09 eva sshd[19642]: Invalid user test04 from 83.15.231.75 +Jul 7 10:52:18 eva sshd[19646]: Invalid user test04 from 83.15.231.75 +Jul 7 10:52:20 eva sshd[19648]: Invalid user test04 from 83.15.231.75 +Jul 7 10:52:20 eva sshd[19651]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:21 eva sshd[19653]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:22 eva sshd[19655]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:23 eva sshd[19657]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:24 eva sshd[19659]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:25 eva sshd[19661]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:26 eva sshd[19664]: Invalid user guest from 83.15.231.75 +Jul 7 10:52:27 eva sshd[19666]: Invalid user guest01 from 83.15.231.75 +Jul 7 10:52:28 eva sshd[19668]: Invalid user guest01 from 83.15.231.75 +Jul 7 10:52:29 eva sshd[19670]: Invalid user ftpadmin from 83.15.231.75 +Jul 7 10:52:30 eva sshd[19672]: Invalid user ftpadmin from 83.15.231.75 +Jul 7 10:52:31 eva sshd[19675]: Invalid user ftpadmin from 83.15.231.75 +Jul 7 10:52:32 eva sshd[19677]: Invalid user ftpadmin from 83.15.231.75 +Jul 7 10:52:33 eva sshd[19679]: Invalid user ftpuser from 83.15.231.75 +Jul 7 10:52:33 eva sshd[19681]: Invalid user ftpuser from 83.15.231.75 +Jul 7 10:52:35 eva sshd[19683]: Invalid user ftpuser from 83.15.231.75 +Jul 7 10:52:35 eva sshd[19686]: Invalid user ftpuser from 83.15.231.75 +Jul 7 10:52:36 eva sshd[19688]: Invalid user backup from 83.15.231.75 +Jul 7 10:52:37 eva sshd[19690]: Invalid user backup from 83.15.231.75 +Jul 7 10:52:38 eva sshd[19692]: Invalid user backup from 83.15.231.75 +Jul 7 10:52:39 eva sshd[19694]: Invalid user backup from 83.15.231.75 +Jul 7 10:52:40 eva sshd[19696]: Invalid user postgres from 83.15.231.75 +Jul 7 10:52:41 eva sshd[19699]: Invalid user postgres from 83.15.231.75 +Jul 7 10:52:43 eva sshd[19703]: Invalid user account from 83.15.231.75 +Jul 7 10:52:44 eva sshd[19705]: Invalid user webmaster from 83.15.231.75 +Jul 7 10:52:45 eva sshd[19707]: Invalid user webmaster from 83.15.231.75 +Jul 7 10:52:46 eva sshd[19710]: Invalid user webmaster from 83.15.231.75 +Jul 7 10:52:46 eva sshd[19712]: Invalid user webmaster from 83.15.231.75 +Jul 7 10:52:48 eva sshd[19714]: Invalid user webmaster from 83.15.231.75 +Jul 7 10:52:48 eva sshd[19716]: Invalid user webadmin from 83.15.231.75 +Jul 7 10:52:49 eva sshd[19718]: Invalid user webadmin from 83.15.231.75 +Jul 7 10:52:50 eva sshd[19721]: Invalid user webadmin from 83.15.231.75 +Jul 7 10:52:51 eva sshd[19723]: Invalid user webadmin from 83.15.231.75 +Jul 7 10:52:52 eva sshd[19725]: Invalid user webadmin from 83.15.231.75 +Jul 7 10:52:53 eva sshd[19727]: Invalid user nagios from 83.15.231.75 +Jul 7 10:52:54 eva sshd[19729]: Invalid user nagios from 83.15.231.75 +Jul 7 10:52:55 eva sshd[19731]: Invalid user nagios from 83.15.231.75 +Jul 7 10:52:56 eva sshd[19734]: Invalid user nagios from 83.15.231.75 +Jul 7 10:52:57 eva sshd[19736]: Invalid user nagios from 83.15.231.75 +Jul 7 10:52:58 eva sshd[19738]: Invalid user ftptest from 83.15.231.75 +Jul 7 10:52:59 eva sshd[19740]: Invalid user ftptest from 83.15.231.75 +Jul 7 10:53:00 eva sshd[19742]: Invalid user ftptest from 83.15.231.75 +Jul 7 10:53:01 eva sshd[19745]: Invalid user ftptest from 83.15.231.75 +Jul 7 10:53:01 eva sshd[19747]: Invalid user ftptest from 83.15.231.75 +Jul 7 10:53:02 eva sshd[19749]: Invalid user ftptest from 83.15.231.75 +Jul 7 10:53:03 eva sshd[19751]: Invalid user library from 83.15.231.75 +Jul 7 10:53:04 eva sshd[19753]: Invalid user library from 83.15.231.75 +Jul 7 10:53:05 eva sshd[19755]: Invalid user library from 83.15.231.75 +Jul 7 10:53:06 eva sshd[19758]: Invalid user ftpguest from 83.15.231.75 +Jul 7 10:53:07 eva sshd[19760]: Invalid user ftpguest from 83.15.231.75 +Jul 7 10:53:08 eva sshd[19762]: Invalid user ftpguest from 83.15.231.75 +Jul 7 10:53:09 eva sshd[19764]: Invalid user ftpguest from 83.15.231.75 +Jul 7 10:53:10 eva sshd[19766]: Invalid user info from 83.15.231.75 +Jul 7 10:53:11 eva sshd[19769]: Invalid user info from 83.15.231.75 +Jul 7 10:53:11 eva sshd[19771]: Invalid user info from 83.15.231.75 +Jul 7 10:53:13 eva sshd[19782]: Invalid user info from 83.15.231.75 +Jul 7 10:53:13 eva sshd[19787]: Invalid user info from 83.15.231.75 +Jul 7 10:53:21 eva sshd[19805]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:22 eva sshd[19807]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:23 eva sshd[19809]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:23 eva sshd[19811]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:25 eva sshd[19813]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:25 eva sshd[19816]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:26 eva sshd[19818]: Invalid user upload from 83.15.231.75 +Jul 7 10:53:27 eva sshd[19820]: Invalid user usertest from 83.15.231.75 +Jul 7 10:53:28 eva sshd[19822]: Invalid user update from 83.15.231.75 +Jul 7 10:53:29 eva sshd[19824]: Invalid user update from 83.15.231.75 +Jul 7 10:53:30 eva sshd[19826]: Invalid user update from 83.15.231.75 +Jul 7 10:53:31 eva sshd[19829]: Invalid user update from 83.15.231.75 +Jul 7 10:53:32 eva sshd[19831]: Invalid user update from 83.15.231.75 +Jul 7 10:53:33 eva sshd[19833]: Invalid user update from 83.15.231.75 +Jul 7 10:53:40 eva sshd[19845]: Invalid user apache from 83.15.231.75 +Jul 7 10:53:41 eva sshd[19847]: Invalid user apache from 83.15.231.75 +Jul 7 10:53:42 eva sshd[19849]: Invalid user apache from 83.15.231.75 +Jul 7 10:53:43 eva sshd[19851]: Invalid user apache from 83.15.231.75 +Jul 7 10:53:44 eva sshd[19853]: Invalid user apache from 83.15.231.75 +Jul 7 10:53:45 eva sshd[19855]: Invalid user apache from 83.15.231.75 +Jul 7 10:53:46 eva sshd[19858]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:47 eva sshd[19860]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:48 eva sshd[19862]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:49 eva sshd[19864]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:50 eva sshd[19866]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:51 eva sshd[19869]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:51 eva sshd[19871]: Invalid user webuser from 83.15.231.75 +Jul 7 10:53:53 eva sshd[19873]: Invalid user oracle from 83.15.231.75 +Jul 7 10:53:54 eva sshd[19875]: Invalid user oracle from 83.15.231.75 +Jul 7 10:53:58 eva sshd[19878]: Invalid user oracle from 83.15.231.75 +Jul 7 10:53:59 eva sshd[19880]: Invalid user oracle from 83.15.231.75 +Jul 7 10:54:00 eva sshd[19882]: Invalid user cyrus from 83.15.231.75 +Jul 7 10:54:01 eva sshd[19885]: Invalid user cyrus from 83.15.231.75 +Jul 7 10:54:01 eva sshd[19887]: Invalid user cyrus from 83.15.231.75 +Jul 7 10:54:02 eva sshd[19889]: Invalid user cyrus from 83.15.231.75 +Jul 7 10:54:03 eva sshd[19891]: Invalid user server from 83.15.231.75 +Jul 7 10:54:04 eva sshd[19893]: Invalid user server from 83.15.231.75 +Jul 7 10:54:06 eva sshd[19898]: Invalid user daniel from 83.15.231.75 +Jul 7 10:54:07 eva sshd[19900]: Invalid user user from 83.15.231.75 +Jul 7 10:54:08 eva sshd[19902]: Invalid user user from 83.15.231.75 +Jul 7 10:54:09 eva sshd[19904]: Invalid user user from 83.15.231.75 +Jul 7 10:54:10 eva sshd[19906]: Invalid user user from 83.15.231.75 +Jul 7 10:54:11 eva sshd[19909]: Invalid user user from 83.15.231.75 +Jul 7 10:54:12 eva sshd[19911]: Invalid user linux from 83.15.231.75 +Jul 7 10:54:13 eva sshd[19913]: Invalid user linux from 83.15.231.75 +Jul 7 10:54:13 eva sshd[19915]: Invalid user linux from 83.15.231.75 +Jul 7 10:54:15 eva sshd[19917]: Invalid user linux from 83.15.231.75 +Jul 7 10:54:15 eva sshd[19920]: Invalid user linux from 83.15.231.75 +Jul 7 10:54:16 eva sshd[19922]: Invalid user student from 83.15.231.75 +Jul 7 10:54:17 eva sshd[19924]: Invalid user student from 83.15.231.75 +Jul 7 10:54:18 eva sshd[19926]: Invalid user student from 83.15.231.75 +Jul 7 10:54:19 eva sshd[19928]: Invalid user student from 83.15.231.75 +Jul 7 10:54:20 eva sshd[19930]: Invalid user student from 83.15.231.75 +Jul 7 10:54:21 eva sshd[19933]: Invalid user temp from 83.15.231.75 +Jul 7 10:54:22 eva sshd[19935]: Invalid user temp from 83.15.231.75 +Jul 7 10:54:23 eva sshd[19937]: Invalid user temp from 83.15.231.75 +Jul 7 10:54:24 eva sshd[19939]: Invalid user temp from 83.15.231.75 +Jul 7 10:54:25 eva sshd[19941]: Invalid user temp from 83.15.231.75 +Jul 7 10:54:26 eva sshd[19944]: Invalid user contact from 83.15.231.75 +Jul 7 10:54:26 eva sshd[19946]: Invalid user contact from 83.15.231.75 +Jul 7 10:54:27 eva sshd[19948]: Invalid user ftpd from 83.15.231.75 +Jul 7 10:54:28 eva sshd[19950]: Invalid user gopher from 83.15.231.75 +Jul 7 10:54:29 eva sshd[19952]: Invalid user gopher from 83.15.231.75 +Jul 7 10:54:30 eva sshd[19954]: Invalid user jobs from 83.15.231.75 +Jul 7 10:54:31 eva sshd[19957]: Invalid user sysadmin from 83.15.231.75 +Jul 7 10:54:32 eva sshd[19959]: Invalid user sysadmin from 83.15.231.75 +Jul 7 10:54:33 eva sshd[19961]: Invalid user sysadmin from 83.15.231.75 +Jul 7 10:54:34 eva sshd[19963]: Invalid user sysadmin from 83.15.231.75 +Jul 7 10:54:35 eva sshd[19965]: Invalid user named from 83.15.231.75 +Jul 7 10:54:36 eva sshd[19968]: Invalid user pgsql from 83.15.231.75 +Jul 7 10:54:36 eva sshd[19970]: Invalid user pgsql from 83.15.231.75 +Jul 7 10:54:38 eva sshd[19972]: Invalid user pgsql from 83.15.231.75 +Jul 7 10:54:38 eva sshd[19974]: Invalid user pgsql from 83.15.231.75 +Jul 7 10:54:39 eva sshd[19976]: Invalid user unix from 83.15.231.75 +Jul 7 10:54:40 eva sshd[19979]: Invalid user unix from 83.15.231.75 +Jul 7 10:54:41 eva sshd[19981]: Invalid user unix from 83.15.231.75 +Jul 7 10:54:42 eva sshd[19983]: Invalid user unix from 83.15.231.75 +Jul 7 10:54:49 eva sshd[20000]: Invalid user postmaster from 83.15.231.75 +Jul 7 10:54:50 eva sshd[20003]: Invalid user postmaster from 83.15.231.75 +Jul 7 10:54:51 eva sshd[20005]: Invalid user operator from 83.15.231.75 +Jul 7 10:54:52 eva sshd[20007]: Invalid user operator from 83.15.231.75 +Jul 7 10:54:54 eva sshd[20011]: Invalid user users from 83.15.231.75 +Jul 7 10:54:55 eva sshd[20013]: Invalid user internet from 83.15.231.75 +Jul 7 10:54:56 eva sshd[20016]: Invalid user internet from 83.15.231.75 +Jul 7 10:54:58 eva sshd[20020]: Invalid user carlos from 83.15.231.75 +Jul 7 10:54:58 eva sshd[20022]: Invalid user adm from 83.15.231.75 +Jul 7 10:55:00 eva sshd[20024]: Invalid user data from 83.15.231.75 +Jul 7 10:55:00 eva sshd[20027]: Invalid user nologin from 83.15.231.75 +Jul 7 10:55:01 eva sshd[20029]: Invalid user smtp from 83.15.231.75 +Jul 7 10:55:03 eva sshd[20031]: Invalid user gdm from 83.15.231.75 +Jul 7 10:55:04 eva sshd[20033]: Invalid user martin from 83.15.231.75 +Jul 7 10:55:05 eva sshd[20035]: Invalid user carlos from 83.15.231.75 +Jul 7 10:55:06 eva sshd[20038]: Invalid user david from 83.15.231.75 +Jul 7 10:55:06 eva sshd[20040]: Invalid user richard from 83.15.231.75 +Jul 7 10:55:08 eva sshd[20042]: Invalid user andy from 83.15.231.75 +Jul 7 10:55:08 eva sshd[20044]: Invalid user kevin from 83.15.231.75 +Jul 7 10:55:10 eva sshd[20046]: Invalid user jeff from 83.15.231.75 +Jul 7 10:55:10 eva sshd[20049]: Invalid user data from 83.15.231.75 +Jul 7 10:55:11 eva sshd[20051]: Invalid user patrick from 83.15.231.75 +Jul 7 10:55:12 eva sshd[20053]: Invalid user jane from 83.15.231.75 +Jul 7 10:55:13 eva sshd[20055]: Invalid user sql from 83.15.231.75 +Jul 7 10:55:14 eva sshd[20057]: Invalid user tester from 83.15.231.75 +Jul 7 10:55:15 eva sshd[20059]: Invalid user andrew from 83.15.231.75 +Jul 7 10:55:16 eva sshd[20062]: Invalid user steven from 83.15.231.75 +Jul 7 10:55:17 eva sshd[20064]: Invalid user angela from 83.15.231.75 +Jul 7 10:55:18 eva sshd[20066]: Invalid user andrea from 83.15.231.75 +Jul 7 10:55:19 eva sshd[20068]: Invalid user webaccount from 83.15.231.75 +Jul 7 10:55:20 eva sshd[20070]: Invalid user seth from 83.15.231.75 +Jul 7 10:55:21 eva sshd[20073]: Invalid user bobby from 83.15.231.75 +Jul 7 10:55:21 eva sshd[20075]: Invalid user peter from 83.15.231.75 +Jul 7 10:55:23 eva sshd[20077]: Invalid user john from 83.15.231.75 +Jul 7 10:55:23 eva sshd[20079]: Invalid user mike from 83.15.231.75 +Jul 7 10:55:24 eva sshd[20081]: Invalid user ally from 83.15.231.75 +Jul 7 10:55:25 eva sshd[20084]: Invalid user norman from 83.15.231.75 +Jul 7 10:55:26 eva sshd[20086]: Invalid user nike from 83.15.231.75 +Jul 7 10:55:27 eva sshd[20088]: Invalid user diana from 83.15.231.75 +Jul 7 10:55:28 eva sshd[20090]: Invalid user george from 83.15.231.75 +Jul 7 10:55:29 eva sshd[20092]: Invalid user james from 83.15.231.75 +Jul 7 10:55:30 eva sshd[20094]: Invalid user transfer from 83.15.231.75 +Jul 7 10:55:31 eva sshd[20097]: Invalid user spam from 83.15.231.75 +Jul 7 10:55:32 eva sshd[20099]: Invalid user spam from 83.15.231.75 +Jul 7 10:55:35 eva sshd[20102]: Invalid user denis from 83.15.231.75 +Jul 7 10:55:36 eva sshd[20104]: Invalid user anders from 83.15.231.75 +Jul 7 10:55:37 eva sshd[20106]: Invalid user friends from 83.15.231.75 +Jul 7 10:55:38 eva sshd[20108]: Invalid user friend from 83.15.231.75 +Jul 7 10:55:39 eva sshd[20110]: Invalid user blast from 83.15.231.75 +Jul 7 10:55:40 eva sshd[20112]: Invalid user ferrari from 83.15.231.75 +Jul 7 10:55:41 eva sshd[20115]: Invalid user bill from 83.15.231.75 +Jul 7 10:55:42 eva sshd[20117]: Invalid user bill from 83.15.231.75 +Jul 7 10:55:43 eva sshd[20119]: Invalid user bill from 83.15.231.75 +Jul 7 10:55:44 eva sshd[20121]: Invalid user bill from 83.15.231.75 +Jul 7 10:55:45 eva sshd[20123]: Invalid user demo from 83.15.231.75 +Jul 7 10:55:46 eva sshd[20126]: Invalid user forum from 83.15.231.75 +Jul 7 10:55:47 eva sshd[20128]: Invalid user master from 83.15.231.75 +Jul 7 10:55:48 eva sshd[20130]: Invalid user pat from 83.15.231.75 +Jul 7 10:55:49 eva sshd[20132]: Invalid user jan from 83.15.231.75 +Jul 7 10:55:50 eva sshd[20134]: Invalid user mark from 83.15.231.75 +Jul 7 10:55:50 eva sshd[20137]: Invalid user support from 83.15.231.75 +Jul 7 10:55:51 eva sshd[20139]: Invalid user cold from 83.15.231.75 +Jul 7 10:55:52 eva sshd[20141]: Invalid user smith from 83.15.231.75 +Jul 7 10:55:53 eva sshd[20143]: Invalid user ppp from 83.15.231.75 +Jul 7 10:55:54 eva sshd[20145]: Invalid user anna from 83.15.231.75 +Jul 7 10:55:55 eva sshd[20147]: Invalid user seba from 83.15.231.75 +Jul 7 10:55:56 eva sshd[20150]: Invalid user lotus from 83.15.231.75 +Jul 7 10:55:57 eva sshd[20152]: Invalid user engine from 83.15.231.75 +Jul 7 10:55:58 eva sshd[20154]: Invalid user domain from 83.15.231.75 +Jul 7 10:55:59 eva sshd[20156]: Invalid user www from 83.15.231.75 +Jul 7 10:56:00 eva sshd[20158]: Invalid user www from 83.15.231.75 +Jul 7 10:56:01 eva sshd[20161]: Invalid user www from 83.15.231.75 +Jul 7 10:56:02 eva sshd[20163]: Invalid user www from 83.15.231.75 +Jul 7 10:56:03 eva sshd[20165]: Invalid user www from 83.15.231.75 +Jul 7 10:56:03 eva sshd[20167]: Invalid user masters from 83.15.231.75 +Jul 7 10:56:05 eva sshd[20169]: Invalid user users from 83.15.231.75 +Jul 7 10:56:05 eva sshd[20172]: Invalid user users from 83.15.231.75 +Jul 7 10:56:06 eva sshd[20174]: Invalid user solaris from 83.15.231.75 +Jul 7 10:56:07 eva sshd[20176]: Invalid user cvs from 83.15.231.75 +Jul 7 10:56:08 eva sshd[20178]: Invalid user guest1 from 83.15.231.75 +Jul 7 10:56:09 eva sshd[20180]: Invalid user guest02 from 83.15.231.75 +Jul 7 10:56:10 eva sshd[20182]: Invalid user www-data from 83.15.231.75 +Aug 7 15:13:17 eva sshd[27633]: Invalid user webmaster from 200.94.18.3 +Aug 7 15:13:23 eva sshd[27650]: Invalid user sales from 200.94.18.3 +Aug 7 15:13:24 eva sshd[27652]: Invalid user admin from 200.94.18.3 +Aug 7 15:13:26 eva sshd[27655]: Invalid user andrea from 200.94.18.3 +Aug 7 15:13:28 eva sshd[27657]: Invalid user backup from 200.94.18.3 +Aug 7 15:13:29 eva sshd[27659]: Invalid user guest from 200.94.18.3 +Aug 7 15:13:31 eva sshd[27662]: Invalid user guest1 from 200.94.18.3 +Aug 7 15:13:33 eva sshd[27664]: Invalid user guest2 from 200.94.18.3 +Aug 7 15:13:34 eva sshd[27666]: Invalid user guest3 from 200.94.18.3 +Aug 7 15:13:36 eva sshd[27669]: Invalid user guest4 from 200.94.18.3 +Aug 7 15:13:38 eva sshd[27671]: Invalid user guest5 from 200.94.18.3 +Aug 7 15:13:39 eva sshd[27673]: Invalid user guest6 from 200.94.18.3 +Aug 7 15:13:41 eva sshd[27676]: Invalid user guest7 from 200.94.18.3 +Aug 7 15:13:43 eva sshd[27678]: Invalid user guest8 from 200.94.18.3 +Aug 7 15:13:44 eva sshd[27680]: Invalid user guest9 from 200.94.18.3 +Aug 7 15:13:46 eva sshd[27683]: Invalid user guest10 from 200.94.18.3 +Aug 7 15:13:48 eva sshd[27685]: Invalid user michael from 200.94.18.3 +Aug 7 15:13:50 eva sshd[27688]: Invalid user gigi from 200.94.18.3 +Aug 7 15:13:52 eva sshd[27692]: Invalid user france from 200.94.18.3 +Aug 7 15:13:54 eva sshd[27694]: Invalid user raider from 200.94.18.3 +Aug 7 15:13:55 eva sshd[27696]: Invalid user movie from 200.94.18.3 +Aug 7 15:13:57 eva sshd[27699]: Invalid user movies from 200.94.18.3 +Aug 7 15:13:59 eva sshd[27701]: Invalid user judith from 200.94.18.3 +Aug 7 15:14:00 eva sshd[27705]: Invalid user default from 200.94.18.3 +Aug 7 15:14:02 eva sshd[27708]: Invalid user sean from 200.94.18.3 +Aug 7 15:14:04 eva sshd[27710]: Invalid user erik from 200.94.18.3 +Aug 7 15:14:05 eva sshd[27713]: Invalid user house from 200.94.18.3 +Aug 7 15:14:07 eva sshd[27721]: Invalid user status from 200.94.18.3 +Aug 7 15:14:09 eva sshd[27727]: Invalid user music from 200.94.18.3 +Aug 7 15:14:10 eva sshd[27734]: Invalid user test from 200.94.18.3 +Aug 7 15:14:12 eva sshd[27737]: Invalid user christian from 200.94.18.3 +Aug 7 15:14:14 eva sshd[27744]: Invalid user upload from 200.94.18.3 +Aug 7 15:14:15 eva sshd[27746]: Invalid user security from 200.94.18.3 +Aug 7 15:14:17 eva sshd[27749]: Invalid user scanner from 200.94.18.3 +Aug 7 15:14:19 eva sshd[27751]: Invalid user work from 200.94.18.3 +Aug 7 15:14:20 eva sshd[27753]: Invalid user eli from 200.94.18.3 +Aug 7 15:14:22 eva sshd[27756]: Invalid user ariel from 200.94.18.3 +Aug 7 15:14:24 eva sshd[27759]: Invalid user matt from 200.94.18.3 +Aug 7 15:14:25 eva sshd[27761]: Invalid user smoke from 200.94.18.3 +Aug 7 15:14:27 eva sshd[27764]: Invalid user papa from 200.94.18.3 +Aug 7 15:14:29 eva sshd[27766]: Invalid user beth from 200.94.18.3 +Aug 7 15:14:30 eva sshd[27768]: Invalid user samba from 200.94.18.3 +Aug 7 15:14:32 eva sshd[27771]: Invalid user library from 200.94.18.3 +Aug 7 15:14:34 eva sshd[27773]: Invalid user don from 200.94.18.3 +Aug 7 15:14:35 eva sshd[27775]: Invalid user webuser from 200.94.18.3 +Aug 7 15:14:37 eva sshd[27778]: Invalid user monitor from 200.94.18.3 +Aug 7 15:14:39 eva sshd[27780]: Invalid user roberto from 200.94.18.3 +Aug 7 15:14:40 eva sshd[27782]: Invalid user mama from 200.94.18.3 +Aug 7 15:14:42 eva sshd[27785]: Invalid user windows from 200.94.18.3 +Aug 7 15:14:44 eva sshd[27787]: Invalid user fritz from 200.94.18.3 +Aug 7 15:14:45 eva sshd[27789]: Invalid user linux from 200.94.18.3 +Aug 7 15:14:47 eva sshd[27797]: Invalid user debian from 200.94.18.3 +Aug 7 15:14:49 eva sshd[27805]: Invalid user darwin from 200.94.18.3 +Aug 7 15:14:50 eva sshd[27807]: Invalid user redhat from 200.94.18.3 +Aug 7 15:14:52 eva sshd[27810]: Invalid user edith from 200.94.18.3 +Aug 7 15:14:54 eva sshd[27812]: Invalid user neo from 200.94.18.3 +Aug 7 15:14:55 eva sshd[27814]: Invalid user neo from 200.94.18.3 +Aug 7 15:14:57 eva sshd[27817]: Invalid user bebe from 200.94.18.3 +Aug 7 15:14:59 eva sshd[27819]: Invalid user postgres from 200.94.18.3 +Aug 7 15:15:00 eva sshd[27821]: Invalid user antonio from 200.94.18.3 +Aug 7 15:15:02 eva sshd[27824]: Invalid user archive from 200.94.18.3 +Aug 7 15:15:05 eva sshd[27845]: Invalid user cathy from 200.94.18.3 +Aug 7 15:15:06 eva sshd[27848]: Invalid user alex from 200.94.18.3 +Aug 7 15:15:08 eva sshd[27850]: Invalid user download from 200.94.18.3 +Aug 7 15:15:10 eva sshd[27852]: Invalid user eric from 200.94.18.3 +Aug 7 15:15:11 eva sshd[27855]: Invalid user gaby from 200.94.18.3 +Aug 7 15:15:13 eva sshd[27857]: Invalid user beer from 200.94.18.3 +Aug 7 15:15:15 eva sshd[27859]: Invalid user mp3 from 200.94.18.3 +Aug 7 15:15:16 eva sshd[27862]: Invalid user ghost from 200.94.18.3 +Aug 7 15:15:18 eva sshd[27864]: Invalid user virus from 200.94.18.3 +Aug 7 15:15:20 eva sshd[27871]: Invalid user gloria from 200.94.18.3 +Aug 7 15:15:21 eva sshd[27874]: Invalid user erwin from 200.94.18.3 +Aug 7 15:15:23 eva sshd[27881]: Invalid user update from 200.94.18.3 +Aug 7 15:15:25 eva sshd[27883]: Invalid user kiss from 200.94.18.3 +Aug 7 15:15:26 eva sshd[27886]: Invalid user army from 200.94.18.3 +Aug 7 15:15:28 eva sshd[27888]: Invalid user andreas from 200.94.18.3 +Aug 7 15:15:33 eva sshd[27891]: Invalid user jojo from 200.94.18.3 +Aug 7 15:15:34 eva sshd[27893]: Invalid user service from 200.94.18.3 diff --git a/etc/rules/log-entries/symantecws b/etc/rules/log-entries/symantecws new file mode 100644 index 000000000..cd60ddac8 --- /dev/null +++ b/etc/rules/log-entries/symantecws @@ -0,0 +1,12 @@ +20070717,30020,1=3,41=SWS-3.0.1.86/lists,100=Version 3.0.3299,3=7,2=29 +20070717,30024,100=SWS-3.0.1.86,2=36 +20070717,30044,1=3,3=1,2=302 +20070717,30044,1=3,1202=20070715.002,1203=20070715.002,3=7,2=301 +20070717,30225,1=3,41=SWS-3.0.1.86/dictionaries,100=Version 3.0.638,3=7,2=29 +20070717,30517,1=3,41=SWS-3.0.1.86/vendor-config,100=Version 3.0.6,3=7,2=29 +20070717,40031,1=3,41=SWS-3.0.1.86/lists,100=Version 3.0.3299,3=7,2=29 +20070717,73613,1=5,11=10.1.1.3,10=userc,3=1,2=1 +20070717,103426,1=5,11=1.2.3.4,10=virtadmin,3=1,2=1 +20070717,73614,1=5,11=1.2.3.4,1106=News,60=http://news.bbc.co.uk/,10=userX,1000=212.58.240.42,2=27 +20070717,115252,1=5,11=1.2.3.4,1106=Miscellaneous,60=https://ad.doubleclick.net/,10=userY,1000=216.73.87.52,2=27 +20070717,122017,1=5,11=2.3.4.5,1106=Finance,60=http://www.esl.org/abc.exe,10=userB,1000=208.2.188.219,2=27 diff --git a/etc/rules/log-entries/telnetd b/etc/rules/log-entries/telnetd new file mode 100644 index 000000000..a30e5c96f --- /dev/null +++ b/etc/rules/log-entries/telnetd @@ -0,0 +1,15 @@ +May 27 15:52:37 valhalla telnetd[4882]: refused connect from mstr195175-16075.dial-in.ttnet.net.tr +May 27 16:48:29 valhalla telnetd[5010]: refused connect from 88.226.34.75 +Jun 2 09:50:28 queen in.telnetd[19636]: [ID 947420 local2.warning] refused connect from 220-129-149-114.dynamic.hinet.net +May 11 10:28:07 queen in.telnetd[19847]: [ID 927837 local2.info] connect from dsl85-105-30859.ttnet.net.tr +May 30 17:11:32 hayaletgemi telnetd[360652]: connect from valhalla.metu.edu.tr +May 12 14:45:17 hayaletgemi in.telnetd[4821]: [ID 927837 local2.info] connect from dsl85-105-30859.ttnet.net.tr +May 12 14:45:17 hayaletgemi telnetd[4821]: [ID 682499 daemon.info] ttloop: read: Not a data message +May 28 17:14:52 queen telnetd[76014]: connect from vod85-15-3859.ttnet.net.tr +May 28 17:14:53 queen telnetd[76014]: ttloop: read: A connection with a remote socket was reset by that socket. +Jun 2 09:59:27 valhalla-eth in.telnetd[19826]: [ID 927837 local2.info] connect from adsl105-3085-tr.ttnet.net.tr +Jun 2 09:59:28 valhalla-eth telnetd[19826]: [ID 485252 daemon.info] ttloop: peer died: Error 0 +May 29 23:57:28 isik telnetd[946360]: connect from 85-10-085.ttnet.net.tr +May 29 23:57:28 isik telnetd[946360]: ttloop: peer died: A file or directory in the path name does not exist. +May 29 20:59:00 valhalla-eth telnetd[2507000]: warning: can't verify hostname: gethostbyname(dsl.dynamic812154227.ttnet.net.tr +May 30 00:19:11 valhalla-eth telnetd[987186]: warning: can't verify hostname: gethostbyname(131.1.satis-tl.ru) failed diff --git a/etc/rules/log-entries/unkown b/etc/rules/log-entries/unkown new file mode 100644 index 000000000..993af03db --- /dev/null +++ b/etc/rules/log-entries/unkown @@ -0,0 +1,17 @@ + Apr 14 19:18:56 mozart in.telnetd[11634]: connect from 192.168.11.200 + Apr 14 19:18:56 mozart imapd[11635]: connect from 192.168.11.200 + Apr 14 19:18:56 mozart in.fingerd[11637]: connect from 192.168.11.200 + Apr 14 19:18:56 mozart ipop3d[11638]: connect from 192.168.11.200 + Apr 14 19:18:56 mozart in.telnetd[11639]: connect from 192.168.11.200 + Apr 14 19:18:56 mozart in.ftpd[11640]: connect from 192.168.11.200 + Apr 14 19:19:03 mozart ipop3d[11642]: connect from 192.168.11.200 + Apr 14 19:19:03 mozart imapd[11643]: connect from 192.168.11.200 + Apr 14 19:19:04 mozart in.fingerd[11646]: connect from 192.168.11.200 + Apr 14 19:19:05 mozart in.fingerd[11648]: connect from 192.168.11.200 + + Apr 14 21:01:58 mozart imapd[11667]: command stream end of file, while reading line user=??? host=[192.168.11.200] + Apr 14 21:01:58 mozart ipop3d[11668]: No such file or directory while reading line user=??? host=[192.168.11.200] + Apr 14 21:02:05 mozart sendmail[11675]: NOQUEUE: [192.168.11.200]: expn root + + Apr 14 21:03:09 mozart telnetd[11682]: ttloop: peer died: Invalid or incomplete multibyte or wide character + Apr 14 21:03:12 mozart ftpd[11688]: FTP session closed diff --git a/etc/rules/log-entries/vpn.log b/etc/rules/log-entries/vpn.log new file mode 100644 index 000000000..18dfa367b --- /dev/null +++ b/etc/rules/log-entries/vpn.log @@ -0,0 +1,20 @@ +31220 06/01/2005 19:05:22.120 SEV=8 IKEDBG/0 RPT=41554 12.34.56.78 RECEIVED Message (msgid=0) with payloads :HDR + SA (1) + NONE (0) total length : 84 +31222 06/01/2005 19:05:22.120 SEV=8 IKEDBG/0 RPT=41555 12.34.56.78 RECEIVED Message (msgid=0) with payloads : HDR + SA (1) + NONE (0) total length : 84 +31224 06/01/2005 19:05:22.120 SEV=9 IKEDBG/0 RPT=41556 12.34.56.78 processing SA payload +31225 06/01/2005 19:05:22.120 SEV=8 IKEDECODE/0 RPT=28390 12.34.56.78 SA Payload Decode : DOI : IPSEC (1) +31228 06/01/2005 19:05:22.120 SEV=8 IKEDECODE/0 RPT=28391 12.34.56.78 Proposal Decode: +31233 06/01/2005 19:05:22.120 SEV=8 IKEDECODE/0 RPT=28393 12.34.56.78 Phase 1 SA Attribute Decode for Transform # 1: +31238 06/01/2005 19:05:22.120 SEV=12 IKEDECODE/0 RPT=28394 IKE Decode of received SA attributes follows: 0000: 80010005 80020002 80030001 80040002 ................ +31241 06/01/2005 19:05:22.120 SEV=7 IKEDBG/0 RPT=41557 12.34.56.78 Oakley proposal is acceptable +31244 06/01/2005 19:05:22.230 SEV=9 IKEDBG/46 RPT=12648 12.34.56.78 constructing Cisco Unity VID payload +31245 06/01/2005 19:05:22.230 SEV=9 IKEDBG/46 RPT=12649 12.34.56.78 constructing xauth V6 VID payload +31247 06/01/2005 19:05:22.230 SEV=9 IKEDBG/38 RPT=1153 12.34.56.78 Constructing VPN 3000 spoofing IOS Vendor ID payload (version: 1.0.0, capabilities: 20000409) +31286 06/01/2005 19:05:22.460 SEV=8 AUTHDBG/1 RPT=1302 AUTH_Open() returns 277 +31287 06/01/2005 19:05:22.460 SEV=7 AUTH/12 RPT=1302 Authentication session opened: handle = 277 +31311 06/01/2005 19:05:22.560 SEV=6 AUTH/41 RPT=1240 12.34.56.78 Authentication successful: handle = 277, server = Internal, group = L2L: Smc +31325 06/01/2005 19:05:22.560 SEV=4 AUTH/22 RPT=1084 User [L2L: Smc] Group [L2L: Smc] connected, Session Type: IPSec/LAN-to-LAN +31326 06/01/2005 19:05:22.570 SEV=4 AUTH/84 RPT=1029 LAN-to-LAN tunnel to headend device 12.34.56.78 connected +31351 06/01/2005 19:05:22.580 SEV=7 AUTH/13 RPT=1300 Authentication session closed: handle = 277 +31352 06/01/2005 19:05:25.540 SEV=4 EVENT/39 RPT=1915 Event Manager erased file(s) LOG34591.TXT when saving file: log35028.txt +22929 04/06/2005 10:07:08.170 SEV=3 AUTH/5 RPT=10801 66.119.119.212 Authentication rejected: Reason = Unspecified handle = 732, server = 162.116.30.137, user = Romano_Bobby, domain = +Nov 23 19:10:03 test.net 24067 23/11/2006 19:10:03.123 SEV=4 IKE/52 RPT=764 112.10.1.1 Group [NONE] User [xyz] User (xyz) authenticated. diff --git a/etc/rules/log-entries/vpopmail b/etc/rules/log-entries/vpopmail new file mode 100644 index 000000000..06465ae70 --- /dev/null +++ b/etc/rules/log-entries/vpopmail @@ -0,0 +1,26 @@ +Sep 14 07:21:42 iron vpopmail[939]: vchkpw-pop3: password fail keith1@xxxx.com:219.136.100.198 +Sep 14 07:21:42 iron vpopmail[937]: vchkpw-pop3: password fail keith2@xxxx.com:219.136.100.198 +Sep 14 07:21:42 iron vpopmail[935]: vchkpw-pop3: password fail keith3@xxxx.com:219.136.100.198 +Sep 14 07:21:42 iron vpopmail[931]: vchkpw-pop3: password fail keith4@xxxx.com:219.136.100.198 +Sep 14 07:21:41 iron vpopmail[923]: vchkpw-pop3: password fail keith5@xxxx.com:219.136.100.198 +Sep 14 07:21:40 iron vpopmail[910]: vchkpw-pop3: password fail keith6@xxxx.com:219.136.100.198 +Sep 14 07:21:40 iron vpopmail[903]: vchkpw-pop3: password fail keith7@xxxx.com:219.136.100.198 +Sep 14 07:21:40 iron vpopmail[901]: vchkpw-pop3: password fail keith9@xxxx.com:219.136.100.198 +Sep 14 07:21:39 iron vpopmail[899]: vchkpw-pop3: password fail keitha@xxxx.com:219.136.100.198 +Sep 14 07:21:39 iron vpopmail[896]: vchkpw-pop3: password fail keithb@xxxx.com:219.136.100.198 +Sep 14 07:21:39 iron vpopmail[893]: vchkpw-pop3: password fail keithc@xxxx.com:219.136.100.198 +Sep 14 07:21:39 iron vpopmail[890]: vchkpw-pop3: password fail keithd@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[883]: vchkpw-pop3: password fail keithe@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[888]: vchkpw-pop3: password fail keithf@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[881]: vchkpw-pop3: password fail keithg@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[884]: vchkpw-pop3: password fail keithh@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[878]: vchkpw-pop3: password fail keithi@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[872]: vchkpw-pop3: password fail keithj@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[873]: vchkpw-pop3: password fail keithk@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[876]: vchkpw-pop3: password fail keithl@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[870]: vchkpw-pop3: password fail keithm@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[868]: vchkpw-pop3: password fail keithn@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[866]: vchkpw-pop3: password fail keitho@xxxx.com:219.136.100.198 +Sep 14 07:21:38 iron vpopmail[863]: vchkpw-pop3: password fail keithp@xxxx.com:219.136.100.198 +Sep 14 07:21:37 iron vpopmail[858]: vchkpw-pop3: password fail keithq@xxxx.com:219.136.100.198 +Sep 14 07:21:37 iron vpopmail[860]: vchkpw-pop3: password fail keiths@xxxx.com:219.136.100.198 diff --git a/etc/rules/log-entries/worms b/etc/rules/log-entries/worms new file mode 100644 index 000000000..826711815 --- /dev/null +++ b/etc/rules/log-entries/worms @@ -0,0 +1,54 @@ +86 200.255.5.155 TCP_MISS/404 1495 GET http://pawlacz.com/nul.php - DIRECT/193.84.182.19 text/html +588 200.255.5.155 TCP_MISS/404 1495 GET http://pawlacz.com/nul.php - DIRECT/193.84.182.19 text/html +9 200.255.5.155 TCP_NEGATIVE_HIT/404 726 GET http://arborfolia.com/nul.php - NONE/- text/html +326 200.255.5.155 TCP_MISS/404 717 GET http://arborfolia.com/nul.php - DIRECT/66.49.208.142 text/html +1001 200.255.5.155 TCP_MISS/404 4439 GET http://appaloosa.no/nul.php - DIRECT/85.19.133.103 text/html +966 200.255.5.155 TCP_MISS/404 4439 GET http://appaloosa.no/nul.php - DIRECT/85.19.133.103 text/html +543 200.255.5.155 TCP_MISS/404 518 GET http://1point2.iae.nl/nul.php - DIRECT/212.61.24.92 text/html +545 200.255.5.155 TCP_MISS/404 518 GET http://1point2.iae.nl/nul.php - DIRECT/212.61.24.92 text/html +504 200.255.5.155 TCP_MISS/404 443 GET http://ujscie.one.pl/nul.php - DIRECT/82.96.66.63 text/html + + +openarmor HIDS Notification. +2006 Jun 20 08:09:32 + +Received From: (wrouter) 200.255.5.3->/usr/local/squid/var/logs/access.log +Rule: 5055 fired (level 10) -> "Multiple attempts to access a non-existent file.'" +Portion of the log(s): + +576 200.255.5.155 TCP_MISS/404 520 GET http://www.autovorota.ru/nul.php - DIRECT/84.252.138.31 text/html +543 200.255.5.155 TCP_MISS/404 520 GET http://www.autovorota.ru/nul.php - DIRECT/84.252.138.31 text/html +955 200.255.5.155 TCP_MISS/404 4920 GET http://www.autoekb.ru/nul.php - DIRECT/217.114.0.67 text/html +934 200.255.5.155 TCP_MISS/404 4920 GET http://www.autoekb.ru/nul.php - DIRECT/217.114.0.67 text/html +328 200.255.5.155 TCP_MISS/404 722 GET http://www.aureaorodeley.com/nul.php - DIRECT/70.84.243.130 text/html +329 200.255.5.155 TCP_MISS/404 722 GET http://www.aureaorodeley.com/nul.php - DIRECT/70.84.243.130 text/html +546 200.255.5.155 TCP_MISS/404 536 GET http://asdesign.cz/nul.php - DIRECT/193.86.238.16 text/html +512 200.255.5.155 TCP_MISS/404 536 GET http://asdesign.cz/nul.php - DIRECT/193.86.238.16 text/html +2085 200.255.5.155 TCP_MISS/404 502 GET http://www.jonogueira.com/nul.php - DIRECT/69.0.160.233 text/html + + + + --END OF NOTIFICATION + + + + openarmor HIDS Notification. + 2006 Jun 20 08:09:33 + + Received From: (wrouter) 200.255.5.3->/usr/local/squid/var/logs/access.log + Rule: 5055 fired (level 10) -> "Multiple attempts to access a non-existent file.'" + Portion of the log(s): + + 1004 200.255.5.155 TCP_MISS/404 1812 GET http://avenue.ee/nul.php - DIRECT/195.5.116.3 text/html + 784 200.255.5.155 TCP_MISS/404 1812 GET http://avenue.ee/nul.php - DIRECT/195.5.116.3 text/html + 543 200.255.5.155 TCP_MISS/404 520 GET http://www.autovorota.ru/nul.php - DIRECT/84.252.138.31 text/html + 955 200.255.5.155 TCP_MISS/404 4920 GET http://www.autoekb.ru/nul.php - DIRECT/217.114.0.67 text/html + 934 200.255.5.155 TCP_MISS/404 4920 GET http://www.autoekb.ru/nul.php - DIRECT/217.114.0.67 text/html + 328 200.255.5.155 TCP_MISS/404 722 GET http://www.aureaorodeley.com/nul.php - DIRECT/70.84.243.130 text/html + 329 200.255.5.155 TCP_MISS/404 722 GET http://www.aureaorodeley.com/nul.php - DIRECT/70.84.243.130 text/html + 546 200.255.5.155 TCP_MISS/404 536 GET http://asdesign.cz/nul.php - DIRECT/193.86.238.16 text/html + 512 200.255.5.155 TCP_MISS/404 536 GET http://asdesign.cz/nul.php - DIRECT/193.86.238.16 text/html + +http://www.fortinet.com/VirusEncyclopedia/search/encyclopediaSearch.do?method=viewVirusDetailsInfoDirectly&fid=223894 + +http://www.trendmicro.co.jp/vinfo/virusencyclo/default5.asp?VName=TROJ_BAGLE.EY&VSect=T diff --git a/etc/rules/log-entries/xferlog b/etc/rules/log-entries/xferlog new file mode 100644 index 000000000..784a01575 --- /dev/null +++ b/etc/rules/log-entries/xferlog @@ -0,0 +1,14 @@ +Fri Mar 31 10:22:44 2006 0 201.44.122.146 32003 /usr/pages/users/resende/htdocs/images/festas/bannerterror.jpg a _ d r canalresende ftp 0 * c + + "Fri Mar 31 10:22:45 2006 0 201.44.122.146 88302 + /usr/pages/users/resende/htdocs/images/festas/banterror.jpg a _ d r + canalresende ftp 0 * c" + +Mon Apr 17 18:27:14 2006 1 64.160.42.130 0 /pub/lyx/devel/log b _ o a mozilla@example.com ftp 0 * i +Mon Apr 17 18:27:20 2006 2 64.160.42.130 42930 /pub/lyx/devel/log/qtbuild.log b _ o a mozilla@example.com ftp 0 * c +Mon Apr 17 20:35:20 2006 1 66.249.66.74 0 /pub/noweb b _ o a googlebot@google.com ftp 0 * i +Tue Apr 18 00:29:01 2006 176 193.219.28.2 6359760 /pub/lyx/devel/lyx-devel.tar.bz2 b _ o a mirror@icm.edu.pl ftp 0 * i +Tue Apr 18 00:30:02 2006 60 193.219.28.2 0 /pub/lyx/devel/log/xformsbuild.log b _ o a mirror@icm.edu.pl ftp 0 * i +Tue Apr 18 00:31:02 2006 60 193.219.28.2 0 /pub/lyx/devel/log/qtbuild.log b _ o a mirror@icm.edu.pl ftp 0 * i +Tue Apr 18 10:47:30 2006 1 66.249.65.137 0 /pub/lyx/html b _ o a googlebot@google.com ftp 0 * i +Tue Apr 18 15:48:41 2006 1 83.135.64.94 0 /pub/lyx b _ o a mozilla@example.com ftp 0 * i diff --git a/etc/rules/mailscanner_rules.xml b/etc/rules/mailscanner_rules.xml new file mode 100644 index 000000000..3658b9548 --- /dev/null +++ b/etc/rules/mailscanner_rules.xml @@ -0,0 +1,51 @@ + + + + + + mailscanner + Grouping of mailscanner rules. + + + + 3700 + not + Non spam message. Ignored. + + + + 3700 + spam + Mail Scanner spam detected. + spam, + + + + 3702 + + Multiple attempts of spam. + multiple_spam, + + + + 1002 + update\.bad\.phishing\.sites + ^Phishing bad sites list updated + ignore + + + + diff --git a/etc/rules/mcafee_av_rules.xml b/etc/rules/mcafee_av_rules.xml new file mode 100644 index 000000000..533f98db3 --- /dev/null +++ b/etc/rules/mcafee_av_rules.xml @@ -0,0 +1,125 @@ + + +^259$|^100$|^1000$|^1001$|^1002$|^1003$|^1004$|^1005$|^1006$|^1007$|^1008$|^5003$|^5005$|^5008$|^5010$|^5011$|^5019$|^5020$|^5021$|^5022$|^5030$|^5031$|^5032$|^5033$|^5034$|^5035$|^5046$|^5047$|^5048$|^5049$|^5051$|^5054$|^5057$|^5059$|^5060$|^5063$|^5063$ +^258$|^5001$|^5028$|^5036$|^5037$|^5038$|^5039$|^5040$|^5041$|^5053$|^5056$|^5061$|^5062$|^5065$ +^257$|^5000$|^5026$|^5052$|^5055$ +quarantined|moved to quarantine|file was deleted|deleted successfully|has been deleted|message deleted|deleted after|cleaned|successfully deleted +The file \.+ contain|infected with|User defined detection|scan found|error attempting to clean +10 + + + + 18101,18102,18103 + windows + ^McLogEvent + Grouping of McAfee Windows AV rules. + + + + 7500 + $MCAFEE_INFO + McAfee Windows AV informational event. + + + + 7500 + $MCAFEE_WARN + McAfee Windows AV warning event. + + + + 7500 + $MCAFEE_ERROR + McAfee Windows AV error event. + + + + 7500 + $MCAFEE_VIRUS + virus + McAfee Windows AV - Virus detected and not removed. + + + + 7504 + $MCAFEE_VIRUS_OK + virus + McAfee Windows AV - Virus detected and properly removed. + + + + 7504 + Will be deleted + virus + McAfee Windows AV - Virus detected and file will be deleted. + + + + 7500 + scan started|scan stopped + McAfee Windows AV - Scan started or stopped. + + + + 7501 + ^257 + completed\. No detections + McAfee Windows AV - Scan completed with no viruses found. + + + + 7500 + scan was cancelled |has taken too long + McAfee Windows AV - Virus scan cancelled. + + + + 7500 + scan was canceled because + McAfee Windows AV - Virus scan cancelled due to shutdown. + + + + 7500 + update was successful + McAfee Windows AV - Virus program or DAT update succeeded. + + + + 7500 + update failed + McAfee Windows AV - Virus program or DAT update failed. + + + + 7500 + update was cancelled + McAfee Windows AV - Virus program or DAT update cancelled. + + + + 7505 + contains the EICAR test file + alert_by_email + McAfee Windows AV - EICAR test file detected. + + + + + + 7502 + Multiple McAfee AV warning events. + + + + diff --git a/etc/rules/mhn_cowrie_rules.xml b/etc/rules/mhn_cowrie_rules.xml new file mode 100644 index 000000000..7517dd9b0 --- /dev/null +++ b/etc/rules/mhn_cowrie_rules.xml @@ -0,0 +1,26 @@ + + + + + + + + + cowrie + SSH login attempted on cowrie honeypot + SSH login attempted on cowrie honeypot + + + + cowrie + SSH session on cowrie honeypot + SSH session established on cowrie honeypot + + + + cowrie + command attempted on cowrie honeypot + A command was attempted in SSH session on cowrie honeypot + + + diff --git a/etc/rules/mhn_dionaea_rules.xml b/etc/rules/mhn_dionaea_rules.xml new file mode 100644 index 000000000..78ac1d5ff --- /dev/null +++ b/etc/rules/mhn_dionaea_rules.xml @@ -0,0 +1,13 @@ + + + + + + + + + dionaea + Connection to Dionaea Honeypot identified + + + diff --git a/etc/rules/ms-exchange_rules.xml b/etc/rules/ms-exchange_rules.xml new file mode 100644 index 000000000..19be4753d --- /dev/null +++ b/etc/rules/ms-exchange_rules.xml @@ -0,0 +1,56 @@ + + + + + + + + + msexchange + Grouping of Exchange rules. + + + + 3800 + RCPT + ^550 + E-mail rcpt is not valid (invalid account). + spam, + + + + 3800 + ^5 + E-mail 500 error code. + spam, + + + + 3801 + + Multiple e-mail attempts to an invalid account. + multiple_spam, + + + + 3802 + + Multiple e-mail 500 error code (spam). + multiple_spam, + + + + diff --git a/etc/rules/ms-se_rules.xml b/etc/rules/ms-se_rules.xml new file mode 100644 index 000000000..7fc4011f7 --- /dev/null +++ b/etc/rules/ms-se_rules.xml @@ -0,0 +1,131 @@ + + + + + + + + windows + 18101,18102,18103 + ^Microsoft Antimalware + Grouping of Microsoft Security Essentials rules. + + + + 7701 + ^1118$|^1119$ + virus + Microsoft Security Essentials - Virus detected, but unable to remove. + + + + 7701 + ^1107$ + virus + Microsoft Security Essentials - Virus detected and properly removed. + + + + 7701 + ^1119$|^1118$|^1117$|^1116$ + virus + Microsoft Security Essentials - Virus detected. + + + + 7701 + ^1015$ + virus, + Microsoft Security Essentials - Suspicious activity detected. + + + + 7701 + ^5007$ + Microsoft Security Essentials - Configuration changed. + policy_changed, + + + + 7701 + ^5008$ + Microsoft Security Essentials - Service failed. + + + + 7701 + ^3002$ + Microsoft Security Essentials - Real time protection failed. + + + + 7701 + ^2012$ + Microsoft Security Essentials - Cannot use Dynamic Signature Service. + + + + 7701 + ^2004$ + Microsoft Security Essentials - Loading definitions failed. Using last good set. + + + + 7701 + ^2003$ + Microsoft Security Essentials - Engine update failed. + + + + 7701 + ^2001$ + Microsoft Security Essentials - Definitions update failed. + + + + 7701 + ^1005$ + Microsoft Security Essentials - Scan error. Scan has stopped. + + + + 7701 + ^1002$ + Microsoft Security Essentials - Scan stopped before completion. + + + + + 7711, 7712 + Virus:DOS/EICAR_Test_File + alert_by_email + Microsoft Security Essentials - EICAR test file detected. + + + + + 7711 + Multiple Microsoft Security Essentials AV warnings detected. + + + + 7712 + Multiple Microsoft Security Essentials AV warnings detected. + + + + + diff --git a/etc/rules/ms1016_usbdetect_rules.xml b/etc/rules/ms1016_usbdetect_rules.xml new file mode 100644 index 000000000..af4dfcf37 --- /dev/null +++ b/etc/rules/ms1016_usbdetect_rules.xml @@ -0,0 +1,10 @@ + + + + + 18104 + ^6416$ + A new external device was recognized by the System + windows, + + diff --git a/etc/rules/ms_dhcp_rules.xml b/etc/rules/ms_dhcp_rules.xml new file mode 100644 index 000000000..6d9106759 --- /dev/null +++ b/etc/rules/ms_dhcp_rules.xml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + ms-dhcp-ipv4 + Grouping for the MS-DHCP rules. + + + + 6300 + ^00 + The log was started. + service_start, + + + + 6300 + ^01 + The log was stopped. + service_availability, + + + + 6300 + ^02 + The log was temporarily paused due to low disk space. + system_error, + + + + 6300 + ^10 + A new IP address was leased to a client. + dhcp_lease_action, + + + + 6300 + ^11 + A lease was renewed by a client. + dhcp_lease_action, + + + + 6300 + ^12 + A lease was released by a client. + dhcp_lease_action, + + + + 6300 + ^13 + An IP address was found to be in use on the network. + dhcp_lease_action, + + + + 6300 + ^14 + A lease request could not be satisfied because the scope's address pool was exhausted. + service_availability,dhcp_lease_action, + + + + 6300 + ^15 + A lease was denied. + dhcp_lease_action, + + + + 6300 + ^16 + A lease was deleted. + dhcp_lease_action, + + + + 6300 + ^17 + A lease was expired and DNS records for an expired leases have not been deleted. + dhcp_lease_action, + + + + 6300 + ^18 + A lease was expired and DNS records were deleted. + dhcp_lease_action,dhcp_dns_maintenance + + + + 6300 + ^20 + A BOOTP address was leased to a client. + dhcp_lease_action, + + + + 6300 + ^21 + A dynamic BOOTP address was leased to a client. + dhcp_lease_action, + + + + + 6300 + ^22 + A BOOTP request could not be satisfied because the scope's address pool for BOOTP was exhausted. + dhcp_lease_action, + + + + 6300 + ^23 + A BOOTP IP address was deleted after checking to see it was not in use. + dhcp_lease_action, + + + + 6300 + ^24 + IP address cleanup operation has began. + dhcp_maintenance, + + + + 6300 + ^25 + IP address cleanup statistics. + dhcp_maintenance, + + + + 6300 + ^30 + DNS update request to the named DNS server. + dhcp_dns_maintenance, + + + + 6300 + ^31 + DNS update failed. + dhcp_dns_maintenance, + + + + 6300 + ^32 + DNS update successful. + dhcp_dns_maintenance, + + + + 6300 + ^33 + Packet dropped due to NAP policy. + dhcp_lease_action, + + + + + 6300 + ^5 + Codes above 50 are used for Rogue Server Detection information. + dhcp_rogue_server, + + + + + + + + + ms-dhcp-ipv6 + Grouping for the MS-DHCP rules. + + + + 6350 + ^11000 + Solicit. + dhcp_ipv6, + + + + 6350 + ^11001|^11002 + Advertise. + dhcp_ipv6, + + + + 6350 + ^11003 + Confirm. + dhcp_ipv6, + + + + 6350 + ^11004 + Renew. + dhcp_ipv6, + + + + 6350 + ^11005 + Rebind. + dhcp_ipv6, + + + + + 6350 + ^11006 + DHCP Decline. + dhcp_ipv6, + + + + 6350 + ^11007 + Release. + dhcp_ipv6, + + + + 6350 + ^11008 + Information Request. + dhcp_ipv6, + + + + 6350 + ^11009 + Scope Full. + dhcp_ipv6, + + + + 6350 + ^11010 + Started. + service_start, + + + + 6350 + ^11011 + Stopped. + service_availability, + + + + 6350 + ^11012 + Audit log paused. + service_availability, + + + + + 6350 + ^11013 + DHCP Log File. + system_error, + + + + 6350 + ^11014 + Bad Address. + dhcp_ipv6, + + + + 6350 + ^11015 + Address is already in use. + dhcp_ipv6, + + + + 6350 + ^11016 + Client deleted. + dhcp_ipv6, + + + + 6350 + ^11017 + DNS record not deleted. + dhcp_ipv6, + + + + 6350 + ^11018 + Expired. + dhcp_ipv6, + + + + 6350 + ^11019 + Expired and Deleted count. + dhcp_ipv6, + + + + 6350 + ^11020 + Database cleanup begin. + dhcp_ipv6, + + + + + 6350 + ^11021 + Database cleanup end. + dhcp_ipv6, + + + + 6350 + ^11023 + Service not authorized in AD. + dhcp_ipv6, + + + + 6350 + ^11024 + Service authorized in AD. + dhcp_ipv6, + + + + 6350 + ^11025 + Service has not determined if it is authorized in AD. + dhcp_ipv6, + + + diff --git a/etc/rules/ms_firewall_rules.xml b/etc/rules/ms_firewall_rules.xml new file mode 100644 index 000000000..3f2e1c1f4 --- /dev/null +++ b/etc/rules/ms_firewall_rules.xml @@ -0,0 +1,173 @@ + + + + + + 18104 + ^5024$ + Windows Firewall Service has started successfully + windows_firewall + + + + 18104 + ^5025$ + Windows Firewall Service has been stopped + windows_firewall + + + + 18104 + ^5027$ + Windows Firewall Service was unable to retrieve the security policy from the local storage. Windows Firewall will continue to enforce the current policy + windows_firewall + + + + 18104 + ^5028$ + Windows Firewall was unable to parse the new security policy. Windows Firewall will continue to enforce the current policy + windows_firewall + + + + 18104 + ^5029$ + The Windows Firewall service failed to initialize the driver. Windows Firewall will continue to enforce the current policy + windows_firewall + + + + 18104 + ^5030$ + Windows Firewall Service failed to start + windows_firewall + + + + 18105 + ^5031$ + Windows Firewall Service blocked an application from accepting incoming connections on the network + windows_firewall + + + + 18105 + ^5032$ + Windows Firewall was unable to notify the user that it blocked an application from accepting incoming connections on the network + windows_firewall + + + + 18104 + ^5033$ + Windows Firewall Driver started successfully + windows_firewall + + + + 18104 + ^5034$ + Windows Firewall Driver was stopped + windows_firewall + + + + 18105 + ^5035$ + Windows Firewall Driver failed to start + windows_firewall + + + + 18105 + ^5037$ + Windows Firewall Driver detected a critical runtime error, terminating + windows_firewall + + + + 18104 + ^4946$ + A rule was added to Windows Firewall exception list + windows_firewall + + + + 18104 + ^4947$ + A rule was modified from Windows Firewall exception list + windows_firewall + + + + 18104 + ^4948$ + A rule was deleted from Windows Firewall exception list + windows_firewall + + + + 18104 + ^4949$ + Windows Firewall settings were restored to the default values + windows_firewall + + + + 18104 + ^4950$ + A Windows Firewall setting was changed + windows_firewall + + + + 18105 + ^4951$ + Windows Firewall ignored a rule because its major version number is not recognized. + windows_firewall + + + + 18105 + ^4952$ + Windows Firewall ignored parts of a rule because its minor version number is not recognized. Other parts of the rule will be enforced + windows_firewall + + + + 18105 + ^4953$ + Windows Firewall ignored a rule because it could not be parsed + windows_firewall + + + + 18104 + ^4954$ + Group Policy settings for Windows Firewall were changed, and the new settings were applied + windows_firewall + + + + 18104 + ^4956$ + Windows Firewall changed the active profile + windows_firewall + + + + 18105 + ^4957$ + Windows Firewall did not apply some rules + windows_firewall + + + + 18105 + ^4958$ + Windows Firewall did not apply some rules because the rule referred to items not configured on this computer + windows_firewall + + + diff --git a/etc/rules/ms_ftpd_rules.xml b/etc/rules/ms_ftpd_rules.xml new file mode 100644 index 000000000..5ffd5062c --- /dev/null +++ b/etc/rules/ms_ftpd_rules.xml @@ -0,0 +1,73 @@ + + + + + + msftp + Grouping for the Microsoft ftp rules. + + + + 11500 + USER + New FTP connection. + connection_attempt, + + + + 11500 + PASS + 530 + FTP Authentication failed. + authentication_failed, + + + + 11500 + PASS + 230 + FTP Authentication success. + authentication_success, + + + + 11500 + ^5 + FTP client request failed. + + + + 11502 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11501 + + Multiple connection attempts from same source. + recon, + + + + 11504 + + Multiple FTP errors from same source. + + + + + diff --git a/etc/rules/ms_ipsec_rules.xml b/etc/rules/ms_ipsec_rules.xml new file mode 100644 index 000000000..d0584555c --- /dev/null +++ b/etc/rules/ms_ipsec_rules.xml @@ -0,0 +1,149 @@ + + + + + + + 18104 + ^4646$ + IKE DoS-prevention mode started + windows, + + + + + 18105 + ^4652$|^4653$ + An IPsec Main Mode negotiation failed + windows, + + + + + 18105 + ^4654$ + An IPsec Quick Mode negotiation failed + windows, + + + + + 18104 + ^4983$|^4984$ + An IPsec Extended Mode negotiation failed + windows, + + + + + 18104 + ^4960$ + IPsec dropped an inbound packet that failed an integrity check + windows, + + + + + 18104 + ^4961$|^4962$ + IPsec dropped an inbound packet that failed a replay check + windows, + + + + + 18104 + ^4963$ + IPsec dropped an inbound clear text packet that should have been secured + windows, + + + + + 18104 + ^4965$ + IPsec received a packet from a remote computer with an incorrect Security Parameter Index (SPI) + windows, + + + + + 18104 + ^4976$ + During Main Mode negotiation, IPsec received an invalid negotiation packet + windows, + + + + + 18104 + ^4977$ + During Quick Mode negotiation, IPsec received an invalid negotiation packet + windows, + + + + + 18104 + ^4978$ + During Extended Mode negotiation, IPsec received an invalid negotiation packet + windows, + + + + + 18104 + ^5453$ + An IPsec negotiation with a remote computer failed because the IKE and AuthIP IPsec Keying Modules (IKEEXT) service is not started + windows, + + + + + 18105 + ^5480$ + IPsec Services failed to get the complete list of network interfaces on the computer + windows, + + + + + 18105 + ^5483$ + IPsec Services failed to initialize RPC server. IPsec Services could not be started + windows, + + + + + 18105 + ^5484$ + IPsec Services has experienced a critical failure and has been shut down + windows, + + + + + 18105 + ^5485$ + IPsec Services failed to process some IPsec filters on a plug-and-play event for network interfaces + windows, + + + + + 18104 + ^4710$ + IPsec Services was disabled + windows, + + + + + 18105 + ^4712$ + IPsec Services encountered a potentially serious failure + windows, + + + diff --git a/etc/rules/ms_powershell_rules.xml b/etc/rules/ms_powershell_rules.xml new file mode 100644 index 000000000..24fd12cfe --- /dev/null +++ b/etc/rules/ms_powershell_rules.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + 18101 + ^400$ + PowerShell + Windows PowerShell was started. + + + + 18101 + ^800$ + PowerShell + Windows PowerShell command executed. + + + + 18101 + ^403$ + PowerShell + Windows PowerShell was stopped. + + + + 20501 + Set-StrictMode -Version 1; .+[A-Za-z0-9@_-]+ + A wrong/misspelled command was tried + + + + 20501 + CommandLine= CommandInvocation + Powershell background activity + + + + 20501 + Set-ExecutionPolicy|Mimikatz|EncodedCommand|Payload|Find-AVSignature|DllInjection|ReflectivePEInjection|Invoke-Shellcode|Invoke--Shellcode|Invoke-ShellcodeMSIL|Get-GPPPassword|Get-Keystrokes|Get-TimedScreenshot|Get-VaultCredential|Invoke-CredentialInjection|Invoke-NinjaCopy|Invoke-TokenManipulation|Out-Minidump|Set-MasterBootRecord|New-ElevatedPersistenceOption|Invoke-CallbackIEX|Invoke-PSInject|Invoke-DllEncode|Get-ServiceUnquoted|Get-ServiceEXEPerms|Get-ServicePerms|Invoke-ServiceUserAdd|Invoke-ServiceCMD|Write-UserAddServiceBinary|Write-CMDServiceBinary|Write-UserAddMSI|Write-ServiceEXE|Write-ServiceEXECMD|Restore-ServiceEXE|Invoke-ServiceStart|Invoke-ServiceStop|Invoke-ServiceEnable|Invoke-ServiceDisable|Invoke-FindDLLHijack|Invoke-FindPathHijack|Get-RegAlwaysInstallElevated|Get-RegAutoLogon|Get-UnattendedInstallFiles|Get-Webconfig|Get-Webconfig|Get-ApplicationHost|Invoke-AllChecks|Invoke-MassCommand|Invoke-MassMimikatz|Invoke-MassSearch|Invoke-MassTemplate|Invoke-MassTokens|HTTP-Backdoor|Add-ScrnSaveBackdoor|Gupt-Backdoor|Invoke-ADSBackdoor|Execute-OnTime|DNS_TXT_Pwnage|Out-Word|Out-Excel|Out-Java|Out-Shortcut|Out-CHM|Out-HTA|Enable-DuplicateToken|Remove-Update|Execute-DNSTXT-Code|Download-Execute-PS|Execute-Command-MSSQL|Download_Execute|Get-PassHashes|Invoke-CredentialsPhish|Get-LsaSecret|Get-Information|Invoke-MimikatzWDigestDowngrade|Copy-VSS|Check-VM|Invoke-NetworkRelay|Create-MultipleSessions|Run-EXEonRemote|Invoke-BruteForce|Port-Scan|Invoke-PowerShellIcmp|Invoke-PowerShellUdp|Invoke-PsGcatAgent|Invoke-PoshRatHttps|Invoke-PowerShellTcp|Invoke-PoshRatHttp|Invoke-PowerShellWmi|Invoke-PSGcat|Remove-PoshRat|TexttoEXE|Invoke-Encode|Invoke-Decode|Base64ToString|StringtoBase64|Do-Exfiltration|Parse_Keys|Add-Exfiltration|Add-Persistence|Remove-Persistence|Invoke-CreateCertificate|powercat|Find-PSServiceAccounts|Get-PSADForestKRBTGTInfo|Discover-PSMSSQLServers|Discover-PSMSExchangeServers|Get-PSADForestInfo|Get-KerberosPolicy|Discover-PSInterestingServices + Possibly Dangerous Command Detected (https://gist.github.com/gfoss/2b39d680badd2cad9d82#file-powershell-command-line-logging) + + + diff --git a/etc/rules/msauth_rules.xml b/etc/rules/msauth_rules.xml new file mode 100644 index 000000000..0d66f1e77 --- /dev/null +++ b/etc/rules/msauth_rules.xml @@ -0,0 +1,969 @@ + + + +6 + + + + windows + Group of windows rules. + + + + 18100 + ^INFORMATION + Windows informational event. + + + + 18100 + ^WARNING + Windows warning event. + + + + 18100 + ^ERROR + Windows error event. + system_error, + + + + 18100 + ^AUDIT_SUCCESS|^success + Windows audit success event. + + + + 18100 + ^AUDIT_FAILURE|^failure + Windows audit failure event. + + + + 18105 + ^529$|^530$|^531$|^532$|^533$|^534$|^535$|^536$|^537$|^539$|^4625$ + Windows Logon Failure. + win_authentication_failed, + + + + 18104 + ^528$|^540$|^673$|^4624$|^4769$ + Windows Logon Success. + authentication_success, + + + + 18105 + ^577$|^4673$ + Failed attempt to perform a privileged + operation. + + + + 18104 + ^682$|^683$|^4778$|^4779$ + Session reconnected/disconnected to winstation. + + + + 18104 + ^624$|^626$|^4720$|^4722$ + User account enabled or created. + adduser,account_changed, + + + + 18104 + ^628$|^642$|^685$|^4738$|^4781$ + User account changed. + account_changed, + + + + 18104 + ^630$|^629$|^4725$|^4726$ + User account disabled or deleted. + adduser,account_changed, + + + + 18104 + ^612$|^643$|^4719$|^4907$|^4912$|^4719$ + Windows Audit Policy changed. + policy_changed, + + + + 18104 + ^632$|^4728$|^633$|^4729$|^636$|^4732$|^637$|^4733$|^639$|^4735$| + ^641$|^4737$|^637$|^4733$|^659$|^4755$|^660$|^4766$|^668$|^4764$| + ^649$|^4745$|^650$|^4746$|^651$|^4747$|^654$|^4750$|^655$|^4751$| + ^656$|^4752$|^659$|^4755$|^660$|^4756$|^661$|^4757$|^664$|^4760$| + ^665$|^4761$|^666$|^4762$ + Group Account Changed + group_changed,win_group_changed, + + + + 18104 + ^640$ + General account database changed. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=640 + adduser,account_changed, + + + + 18104 + ^644$|^4740$ + User account locked out (multiple login errors). + authentication_failures, + + + + 18104 + ^513$|^4609$ + Windows is shutting down. + system_shutdown, + + + + 18104 + ^517$|^1102$ + Windows audit log was cleared. + logs_cleared, + + + + 18107 + alert_by_email + + First time this user logged in this system. + authentication_success, + + + + 18105 + ^680$ + Windows login attempt (ignored). Duplicated. + + + + 18102, 18103 + ^20187$|^20014$|^20078$|^20050$|^20049$|^20189$ + Remote access login failure. + authentication_failed, + + + + 18101 + ^20158$ + Remote access login success. + authentication_success, + + + + 18104 + ^646$|^645$|^647$|^4741$|^4742$|^4743$ + Computer account added/changed/deleted. + account_changed, + + + + + ^65xxx + Group account added/changed/deleted. + This rule has been deprecated + account_changed, + + + + 18103 + ^13570$ + Windows file system full. + low_diskspace, + + + + + + 18106 + ^529$|^4625$ + Logon Failure - Unknown user or bad password. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=4625 + win_authentication_failed, + + + + 18106 + ^530$ + Logon Failure - Account logon time restriction + violation. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=530 + win_authentication_failed,login_denied, + + + + 18106 + ^531$ + Logon Failure - Account currently disabled. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=531 + win_authentication_failed,login_denied, + + + + 18106 + ^532$ + Logon Failure - Specified account expired. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=532 + win_authentication_failed,login_denied, + + + + 18106 + ^533$ + Logon Failure - User not allowed to login at + this computer. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=533 + win_authentication_failed,login_denied, + + + + 18106 + ^534$ + Logon Failure - User not granted logon type. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=534 + win_authentication_failed, + + + + 18106 + ^535$ + Logon Failure - Account's password expired. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=535 + win_authentication_failed, + + + + 18106 + ^536$|^537$ + Logon Failure - Internal error. + win_authentication_failed, + + + + 18106 + ^539$ + Logon Failure - Account locked out. + win_authentication_failed, + + + + 18105 + ^673$|^675$|^681$|^4769$ + Windows DC Logon Failure. + win_authentication_failed, + + + + 18104 + ^520$|^4616$ + System time changed. + time_changed, + + + + 18102 + ^1076$ + unexpected shutdown + system_error, system_shutdown, + Unexpected Windows shutdown. + + + + 18104 + ^671$|^4767$ + User account unlocked. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=4767 + account_changed, + + + + 18114 + ^631$|^635$|^658$ + Security enabled group created. + adduser,account_changed, + + + + 18114 + ^634$|^638$|^662$ + Security enabled group deleted. + adduser,account_changed, + + + + + 18101 + ^7040$ + policy_changed, + Service startup type was changed. + This does not appear to be logged on Windows 2000. + + + + 18101 + ^11724$ + alert_by_email + Application Uninstalled. + + + + 18101 + ^11707$ + alert_by_email + Application Installed. + + + + 18104 + ^4608$ + Windows is starting up. + + + + 18104 + ^538$|^551$|^4634$|^4647$ + Windows User Logoff. + + + + + + 18104 + ^631$|^4727$|^635$|^4731$|^658$|^4754$|^648$|^4744$|^653$|^4749$| + ^663$|^4759$ + Group Account Created + group_created,win_group_created, + + + + 18104 + ^634$|^4730$|^638$|^4734$|^662$|^4758$|^652$|^4748$|^657$|^4753$| + ^667$|^4763$ + Group Account Deleted + group_deleted,win_group_deleted, + + + + 18200 + ^631$|^4727$ + Security Enabled Global Group Created + group_created,win_group_created, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=631 + + + + 18114 + ^632$|^4728$ + Security Enabled Global Group Member Added + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=632 + + + + 18114 + ^633$|^4729$ + Security Enabled Global Group Member Removed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=633 + + + + 18201 + ^634$|^4730$ + Security Enabled Global Group Deleted + group_deleted,win_group_deleted, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=634 + + + + 18200 + ^635$|^4731$ + Security Enabled Local Group Created + group_created,win_group_created, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=635 + + + + 18114 + ^636$|^4732$ + Security Enabled Local Group Member Added + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=636 + + + + 18114 + ^637$|^4733$ + Security Enabled Local Group Member Removed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=637 + + + + 18201 + ^638$|^4734$ + Security Enabled Local Group Deleted + group_deleted,win_group_deleted, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=638 + + + + 18114 + ^639$|^4735$ + Security Enabled Local Group Changed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=639 + + + + 18114 + ^641$|^4737$ + Security Enabled Global Group Changed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=641 + + + + 18200 + ^658$|^4754$ + Security Enabled Universal Group Created + group_created,win_group_created, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=658 + + + + 18114 + ^659$|^4755$ + Security Enabled Universal Group Changed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=659 + + + + 18114 + ^660$|^4756$ + Security Enabled Universal Group Member Added + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=660 + + + + 18114 + ^661$|^4757$ + Security Enabled Universal Group Member Removed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=661 + + + + 18201 + ^662$|^4758$ + Security Enabled Universal Group Deleted + group_deleted,win_group_deleted, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=662 + + + + 18207,18208 + ID:[ ]+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]*S-1-5-32-544 + Administrators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-1-0\}| ID:[ ]+S-1-1-0 + Everyone Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-9\}| ID:[ ]+S-1-5-9 + Enterprise Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-11\}| ID:[ ]+S-1-5-11 + Authenticated Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-13\}| ID:[ ]+S-1-5-13 + Terminal Server Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-512\}| ID:[ ]+S-1-5-21\S+-512 + Domain Admins Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-513\}| ID:[ ]+S-1-5-21\S+-513 + Domain Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18223,18203 + Target Account Name: None + Local User Group NONE + Bogus group user added to upon creation + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-514\}| ID:[ ]+S-1-5-21\S+-514 + Domain Guests Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-515\}| ID:[ ]+S-1-5-21\S+-515 + Domain Computers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-516\}| ID:[ ]+S-1-5-21\S+-516 + Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-21\S+-517\}| ID:[ ]+S-1-5-21\S+-517 + Cert Publishers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21.+-518\}| ID:[ ]+S-1-5-21.+-518 + Schema Admins Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-519\}| ID:[ ]+S-1-5-21\S+-519 + Enterprise Admins Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-520\}| ID:[ ]+S-1-5-21\S+-520 + Group Policy Creator Owners Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-21\S+-553\}| ID:[ ]+S-1-5-21\S+-553 + RAS and IAS Servers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-545\}| ID:[ ]+S-1-5-32-545 + Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-546\}| ID:[ ]+S-1-5-32-546 + Guests Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-547\}| ID:[ ]+S-1-5-32-547 + Power Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-548\}| ID:[ ]+S-1-5-32-548 + Account Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-549\}| ID:[ ]+S-1-5-32-549 + Server Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-550\}| ID:[ ]+S-1-5-32-550 + Print Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-551\}| ID:[ ]+S-1-5-32-551 + Backup Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-552\}| ID:[ ]+S-1-5-32-552 + Replicators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-554\}| ID:[ ]+S-1-5-32-554 + Pre-Windows 2000 Compatible Access Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-555\}| ID:[ ]+S-1-5-32-555 + Remote Desktop Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-556\}| ID:[ ]+S-1-5-32-556 + Network Configuration Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-557\}| ID:[ ]+S-1-5-32-557 + Incoming Forest Trust Builders Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-558\}| ID:[ ]+S-1-5-32-558 + Performance Monitor Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-559\}| ID:[ ]+S-1-5-32-559 + Performance Log Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-560\}| ID:[ ]+S-1-5-32-560 + Windows Authorization Access Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-561\}| ID:[ ]+S-1-5-32-561 + Terminal Server License Servers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-562\}| ID:[ ]+S-1-5-32-562 + Distributed COM Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-498\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-498 + Enterprise Read-only Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-529\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-529 + Read-only Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-569\}| ID:[ ]+S-1-5-32-569 + Cryptographic Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-571\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-571 + Allowed RODC Password Replication Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-572\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-572 + Denied RODC Password Replication Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-573\}| ID:[ ]+S-1-5-32-573 + Event Log Readers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-574\}| ID:[ ]+S-1-5-32-574 + Certificate Service DCOM Access Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18101 + ^200$|^300$|^302$ + TS Gateway login success. + authentication_success, + https://technet.microsoft.com/en-us/library/cc775181(v=ws.10).aspx + + + + 18102, 18103 + ^201$|^203$|^204$|^301$|^304$|^305$|^306$|^1001$ + TS Gateway login failure. + authentication_failed, + https://technet.microsoft.com/en-us/library/cc775181(v=ws.10).aspx + + + + 18101 + ^202$|^303$ + TS Gateway user disconnected. + https://technet.microsoft.com/en-us/library/cc775181(v=ws.10).aspx + + + + + 18107,18149 + ^528$|^538$|^540$|^4624$ + ^LOCAL SERVICE|^NETWORK SERVICE|^ANONYMOUS LOGON + Windows Logon Success (ignored). + + + + + + 18139 + Failure Code: 0x1F + Windows DC integrity check on decrypted + field failed. + + win_authentication_failed,attacks, + + + + 18139 + Failure Code: 0x22 + Windows DC - Possible replay attack. + + win_authentication_failed,attacks, + + + + 18139 + Failure Code: 0x25 + Windows DC - Clock skew too great. + + win_authentication_failed,attacks, + + + + + + 18105 + ^18456$ + win_authentication_failed, + MS SQL Server Logon Failure. + + + + 18104 + ^18454$|^18453$ + MS SQL Server Logon Success. + authentication_success, + + + + + 18107 + ^4624$ + Logon Type: 8 + MS Exchange Logon Success. + + + + 18149 + ^4634$ + Logon Type: 8 + User Logoff Exchange. + + + + + + 18108 + + Multiple failed attempts to perform a + privileged operation by the same user. + + + + win_authentication_failed + Multiple Windows Logon Failures. + authentication_failures, + + + + 18105 + Multiple Windows audit failure events. + + + + 18103 + Multiple Windows error events. + + + + 18102 + Multiple Windows warning events. + + + + 18125 + Multiple remote access login failures. + authentication_failures, + + + + 18258 + Multiple TS Gateway login failures. + authentication_failures, + + + + + 18103 + : chromoting: .* Access denied for client: + Chrome Remote Desktop attempt - access denied + + + + 18101 + : chromoting: .* Client connected: + Chrome Remote Desktop attempt - connected + + + + 18101 + : chromoting: .* Client disconnected: + Chrome Remote Desktop attempt - disconnected + + + + + diff --git a/etc/rules/mysql_rules.xml b/etc/rules/mysql_rules.xml new file mode 100644 index 000000000..c50df5f07 --- /dev/null +++ b/etc/rules/mysql_rules.xml @@ -0,0 +1,85 @@ + + + + + + + mysql_log + MySQL messages grouped. + + + + 50100 + ^MySQL log: \d+ \S+ \d+ Connect + Database authentication success. + authentication_success, + + + + 50105 + Access denied for user + Database authentication failure. + authentication_failed, + + + + 50100 + ^MySQL log: \d+ \S+ \d+ Query + Database query. + + + + 50100 + ^MySQL log: \d+ \S+ \d+ Quit + User disconnected from database. + + + + 50100 + mysqld ended|Shutdown complete + Database shutdown message. + service_availability, + + + + 50100 + mysqld started|mysqld restarted + Database startup message. + service_availability, + + + + 50100 + ^MySQL log: \d+ \S+ \d+ \[ERROR\] + Database error. + + + + 50125 + Fatal error: + Database fatal error. + service_availability, + + + + 50125 + Multiple database errors. + service_availability, + + + + + diff --git a/etc/rules/named_rules.xml b/etc/rules/named_rules.xml new file mode 100644 index 000000000..654e75b75 --- /dev/null +++ b/etc/rules/named_rules.xml @@ -0,0 +1,325 @@ + + + + + + named + Grouping of the named rules + + + + 12100 + dropping source port zero packet from + Invalid DNS packet. Possibility of attack. + invalid_access, + + + + 12100 + denied AXFR from + Failed attempt to perform a zone transfer. + access_denied, + + + + 12100 + denied update from|unapproved update from + DNS update denied. + Generally mis-configuration. + http://seclists.org/incidents/2000/May/217 + client_misconfig, + + + + 12100 + unable to rename log file + Log permission misconfiguration in Named. + system_error, + + + + 12100 + unexpected RCODE + Unexpected error while resolving domain. + + + + 12100 + refused notify from non-master + DNS configuration error. + + + + 12100 + update \S+ denied + DNS update using RFC2136 Dynamic protocol. + + + + 12100 + query \(cache\) denied|: query \(cache\) + Query cache denied (probably config error). + http://www.reedmedia.net/misc/dns/errors.html + connection_attempt, + + + + 12100 + exiting \(due to fatal error\) + Named fatal error. DNS service going down. + service_availability, + + + + ^zone \S+ serial number \S+ received from master + \S+ \S ours (\S+) + Serial number from master is lower + than stored. + system_error, + + + + ^transfer of \S+ from \S+ failed while receiving \S+ REFUSED + Unable to perform zone transfer. + system_error, + + + + ^zone \S+: expired + Zone transfer error. + + + + 12100 + zone transfer deferred due to quota + Zone transfer deferred. + + + + 12100 + bad owner name \(check-names\) + Hostname contains characters that check-names does not like. + + + + 12100 + loaded serial|transferred serial + Zone transfer. + + + + 12100 + syntax error near| + reloading configuration failed: unexpected token + Syntax error in a named configuration file. + + + + + 12100 + refresh: retry limit for master \S+ exceeded + Zone transfer rety limit exceeded + + + + 12100 + already exists previous definition + Zone has been duplicated. + + + + 12100 + starting BIND + BIND has been started + + + + 12100 + has no address records + Missing A or AAAA record + + + + 12100 + zone \S+: \(master\) removed + Zone has been removed from a master server + + + + 12100 + loading from master file \S+ failed: not at top of zone$ + Origin of zone and owner name of SOA do not match. + + + + 12100 + already exists previous definition + Zone has been duplicated + + + + 12100 + reloading configuration failed: unexpected end of input + BIND Configuration error. + + + + 12100 + zone \S+: \(master\) removed + Zone has been removed from a master server + + + + 12100 + loading from master file \S+ failed: not at top of zone$ + Origin of zone and owner name of SOA do not match. + + + + 12100 + ^transfer of| + AXFR started$ + Zone transfer. + + + + 12128 + failed to connect: connection refused + Zone transfer failed, unable to connect to master. + + + + 12100 + IPv6 interfaces failed + Could not listen on IPv6 interface. + + + + 12100 + failed; interface ignored + Could not bind to an interface. + + + + 12128 + failed while receiving responses: not authoritative + Master is not authoritative for zone. + + + + 12100 + open: \S+: permission denied$ + Could not open configuration file, permission denied. + + + + 12100 + loading configuration: permission denied + Could not open configuration file, permission denied. + + + + 12100 + IN SOA -E + Domain in SOA -E. + + + + 12128 + failed to connect: host unreachable + Master appears to be down. + + + + 12100 + IN AXFR - + Domain is queried for a zone transferred. + + + + 12100 + IN A \+ + Domain A record found. + + + + 12100 + client \S+: bad zone transfer request: \S+: non-authoritative zone \(NOTAUTH\) + Bad zone transfer request. + + + + 12100 + refresh: failure trying master + Cannot refresh a domain from the master server. + + + + 12100 + SOA record not at top of zone + Origin of zone and owner name of SOA do not match. + + + + 12100 + command channel listening on + named command channel is listening. + + + + 12100 + automatic empty zone + named has created an automatic empty zone. + + + + 12100 + reloading configuration failed: out of memory + Server does not have enough memory to reload the configuration. + + + + 12100 + zone transfer \S+ denied + zone transfer denied + + + + 12100 + error sending response: host unreachable$ + Cannot send a DNS response. + + + + 12100 + update forwarding .+ denied$ + Cannot update forwarding domain. + + + + 12100 + : parsing failed$ + Parsing of a configuration file has failed. + + + + 12108 + + Multiple query (cache) failures. + connection_attempt, + + + diff --git a/etc/rules/netscreenfw_rules.xml b/etc/rules/netscreenfw_rules.xml new file mode 100644 index 000000000..239697205 --- /dev/null +++ b/etc/rules/netscreenfw_rules.xml @@ -0,0 +1,123 @@ + + + + + + netscreenfw + Grouping for the Netscreen Firewall rules + + + + 4500 + notification + Netscreen notification message. + + + + 4500 + warning + Netscreen warning message. + + + + 4500 + critical + Netscreen critical/alert message. + + + + 4500 + alert + Netscreen critical/alert message. + + + + 4500 + information + Netscreen informational message. + + + + + 4503 + ^00027 + Netscreen Erase sequence started. + service_availability, + + + + 4501 + ^00002 + Successfull admin login to the Netscreen firewall + authentication_success, + + + + 4502 + ^00515 + Successfull admin login to the Netscreen firewall + authentication_success, + + + + 4501 + ^00018 + Firewall policy changed. + config_changed, + + + + 4504 + ^00767 + Firewall configuration changed. + config_changed, + + + + 4503 + + Multiple Netscreen critical messages from + same source IP. + + + + 4503 + Multiple Netscreen critical messages. + + + + 4513 + + Multiple Netscreen alert messages from + same source IP. + + + + 4513 + Multiple Netscreen alert messages. + + + + 4500 + SYN flood! + netscreen detected a SYN flood. + + + + + + diff --git a/etc/rules/nginx_rules.xml b/etc/rules/nginx_rules.xml new file mode 100644 index 000000000..0a7b311c8 --- /dev/null +++ b/etc/rules/nginx_rules.xml @@ -0,0 +1,88 @@ + + + + + + nginx-errorlog + Nginx messages grouped. + + + + 31300 + ^\S+ \S+ \[error\] + Nginx error message. + + + + 31300 + ^\S+ \S+ \[warn\] + Nginx warning message. + + + + 31300 + ^\S+ \S+ \[crit\] + Nginx critical message. + + + + 31301 + failed \(2: No such file or directory\)|is not found \(2: No such file or directory\) + Server returned 404 (reported in the access.log). + + + + 31301 + accept\(\) failed \(53: Software caused connection abort\) + Incomplete client request. + + + + 31301 + no user/password was provided for basic authentication + Initial 401 authentication request. + + + + 31301 + password mismatch, client| was not found in + Web authentication failed. + authentication_failed, + + + + 31315 + + Multiple web authentication failures. + authentication_failures, + + + + 31303 + failed \(2: No such file or directory + Common cache error when files were removed. + + + + 31301 + failed \(36: File name too long\) + Invalid URI, file name too long. + invalid_request, + + + + + diff --git a/etc/rules/nsd_rules.xml b/etc/rules/nsd_rules.xml new file mode 100644 index 000000000..f671889ff --- /dev/null +++ b/etc/rules/nsd_rules.xml @@ -0,0 +1,97 @@ + + + + + nsd + NSD grouping. + + + + 53200 + unrecognized RR type + Syntax error in nsd configuration. + + + + nsd + 53200 + server initialization failed|syntax error$ + Syntax error in nsd configuration. + + + + 53200 + ^NSTATS|^XSTATS + nsd statistics + + + + nsd + Can't bind + Cannot bind to a socket. + + + + nsd + nsd is already running + nsd is already running. + + + + nsd + 53200 + received notify response error NOT IMPL + Notify is not implemented. + + + + nsd + 53200 + read with \d+ errors$ + Zone file read with errors. + + + + nsd + 53200 + received error code + Error grouping. + + + + nsd + 53208 + NOT IMPL + Zone xfer not implemented. + + + + 53200 + tcp: Connection reset by peer$ + tcp connection reset. + + + + 53200 + received error code NOT IMPL + Attempted zone transfer not configured. + + + + 53208 + received error code SERVER NOT AUTHORITATIVE FOR ZONE + Server not authoritative for zone transfer. + + + + + + diff --git a/etc/rules/openarmor_rules.xml b/etc/rules/openarmor_rules.xml new file mode 100644 index 000000000..162da22d1 --- /dev/null +++ b/etc/rules/openarmor_rules.xml @@ -0,0 +1,359 @@ + + + + + + + openarmor + openarmor + Grouping of openarmor rules. + + + + 500 + + alert_by_email + Agent started + New openarmor agent connected. + + + + 500 + alert_by_email + openarmor started + openarmor server started. + + + + 500 + alert_by_email + Agent started + openarmor agent started. + + + + 500 + alert_by_email + Agent disconnected + openarmor agent disconnected. + + + + openarmor + rootcheck + Rootcheck event. + rootcheck, + + + + 509 + Host-based anomaly detection event (rootcheck). + rootcheck, + + + + + 510 + ^NTFS Alternate data stream found.*(?:Thumbs\.db:encryptable'\.|:Zone\.Identifier'\.|Exchsrvr/Mailroot/vsi) + Ignored common NTFS ADS entries. + rootcheck, + + + + 510 + ^Windows Audit + Windows Audit event. + rootcheck, + + + + 510 + ^Windows Malware + Windows malware detected. + rootcheck, + + + + 510 + ^Application Found + Windows application monitor event. + rootcheck, + + + + 510 + ^Starting rootcheck scan|^Ending rootcheck scan\.| + ^Starting syscheck scan|^Ending syscheck scan\. + Ignoring rootcheck/syscheck scan messages. + rootcheck,syscheck + + + + 510 + ^System Audit + System Audit event. + rootcheck, + + + + 514 + Adware|Spyware + Windows Adware/Spyware application found. + rootcheck, + + + + 516 + ^System Audit: Web vulnerability + System Audit: Vulnerable web application found. + rootcheck, + + + + + 500 + ^openarmor: output: + openarmor process monitoring rules. + process_monitor, + + + + 530 + openarmor: output: 'df -P': /dev/.*100% + Partition usage reached 100% (disk space monitor). + low_diskspace, + + + + 531 + cdrom|/media|usb|/mount|floppy|dvd + Ignoring external medias. + + + + 530 + openarmor: output: 'netstat -tan + + Listened ports status (netstat) changed (new port opened or closed). + + + + 530 + openarmor: output: 'w' + + no_log + List of logged in users. It will not be alerted by default. + + + + 530 + openarmor: output: 'last -n + + no_log + List of the last logged in users. + + + + openarmor + syscheck_integrity_changed + Integrity checksum changed. + syscheck, + + + + openarmor + syscheck_integrity_changed_2nd + Integrity checksum changed again (2nd time). + syscheck, + + + + openarmor + syscheck_integrity_changed_3rd + Integrity checksum changed again (3rd time). + syscheck, + + + + openarmor + syscheck_deleted + File deleted. Unable to retrieve checksum. + syscheck, + + + + openarmor + syscheck_new_entry + File added to the system. + syscheck, + + + + 500 + ^openarmor: agentless: + Integrity checksum for agentless device changed. + syscheck,agentless + + + + + openarmor + hostinfo_modified + Host information changed. + hostinfo, + + + + openarmor + hostinfo_new + Host information added. + hostinfo, + + + + + + 500 + ^openarmor: File rotated + Log file rotated. + + + + 500 + ^openarmor: File size reduced + Log file size reduced. + attacks, + + + + 500 + ^openarmor: Event log cleared + Microsoft Event log cleared. + logs_cleared, + + + + openarmor + 550 + syscheck-registry + syscheck, + Registry Integrity Checksum Changed + + + + openarmor + 551 + syscheck-registry + syscheck, + Registry Integrity Checksum Changed Again (2nd time) + + + + openarmor + 552 + syscheck-registry + syscheck, + Registry Integrity Checksum Changed Again (3rd time) + + + + openarmor + 553 + syscheck-registry + syscheck, + Registry Entry Deleted. Unable to Retrieve Checksum + + + + openarmor + 554 + syscheck-registry + syscheck, + Registry Entry Added to the System + + + + + + ar_log + Active Response Messages Grouped + active_response, + + + + 600 + firewall-drop.sh + add + Host Blocked by firewall-drop.sh Active Response + active_response, + + + + 600 + firewall-drop.sh + delete + Host Unblocked by firewall-drop.sh Active Response + active_response, + + + + 600 + host-deny.sh + add + Host Blocked by host-deny.sh Active Response + active_response, + + + + 600 + host-deny.sh + delete + Host Unblocked by host-deny.sh Active Response + active_response, + + + + 600 + route-null.sh + add + Host Blocked by route-null.sh Active Response + active_response, + + + + 600 + route-null.sh + delete + Host Unblocked by route-null.sh Active Response + active_response, + + + + openarmor + openarmor-logcollector + Logcollector Messages Grouped + + + + 700 + INFO: + Ignore informational messages (usually at startup) + + + diff --git a/etc/rules/openbsd-dhcpd_rules.xml b/etc/rules/openbsd-dhcpd_rules.xml new file mode 100644 index 000000000..f06e17f3a --- /dev/null +++ b/etc/rules/openbsd-dhcpd_rules.xml @@ -0,0 +1,84 @@ + + + + + + dhcpd + dhcpd grouping. + + + + 53000 + ^DHCPREQUEST|^DHCPOFFER |^DHCPDISCOVER|^DHCPACK + Normal dhcp. + + + + 53000 + answers a ping after sending a release|Possible release spoof + A host issued a release but is responding to pings. + + + + 53000 + expecting left brace\.$| + fixed-address parameter not allowed here\.$| + parameters not allowed after first declaration\.$| + Configuration file errors encountered + Configuration errors. + + + + 53000 + exiting\.$ + dhcpd is exiting. + + + + 53000 + Can't listen on + dhcpd cannot listen to an interface. + + + + 53006 + has no subnet declaration for + dhcpd is not configured to listen to an interface. + + + + 53000 + Listening on + dhcpd has been started. + + + + 53000 + ^Address range + Message with address range. + + + + 53009 + not on net + Defined address range is not on the configured network. + + + + 53000 + ^no free leases + DHCP server has run out of leases. + + + + 53000 + ^already acking lease + Multiple acks. + + + + + diff --git a/etc/rules/openbsd_rules.xml b/etc/rules/openbsd_rules.xml new file mode 100644 index 000000000..c84f6938c --- /dev/null +++ b/etc/rules/openbsd_rules.xml @@ -0,0 +1,310 @@ + + + + + + + + + + bsd_kernel + Grouping of bsd_kernel alerts + + + + 51500 + ichiic0: abort failed, status 0x40 + A timeout occurred waiting for a transfer. + + + + 51500 + Check Condition \(error 0x70\) on opcode 0x0 + Check media in optical drive. + + + + 51500 + BBB bulk-in clear stall failed + A disk has timed out. + + + + 51500 + arp info overwritten for + arp info has been overwritten for a host + + + + 51500 + was not properly unmounted + A filesystem was not properly unmounted, likely system crash + + + + 51500 + UKC> quit + UKC was used, possibly modifying a kernel at boot time. + + + + 51500 + Michael MIC failure + Michael MIC failure: Checksum failure in the tkip protocol. + + + + 51500 + soft error \(corrected\) + A soft error has been corrected on a hard drive, + this is a possible early sign of failure. + + + + 51500 + acpithinkpad\d: unknown event + Unknown acpithinkpad event + + + + 51500 + Critical temperature, shutting down + System shutdown due to temperature + + + + 51500 + _AL0\[0\] _PR0 failed + Unknown ACPI event (bug 6299 in OpenBSD bug tracking system). + + + + 51500 + ehci_freex: xfer=0xffff8000003ef800 not busy, 0x4f4e5155 + USB diagnostic message. + + + + 51500 + ichiic0: abort failed, status 0x0 + Possible APM or ACPI event. + + + + 51500 + Filesystem is not clean - run fsck + Unclean filesystem, run fsck. + + + + 51500 + atascsi_passthru_done, timeout + Timeout in atascsi_passthru_done. + + + + 51500 + RTC BIOS diagnostic error 80\ + Clock battery error 80 + + + + 51500 + i/o error on block + I/O error on a storage device + + + + 51500 + kbc: cmd word write error + kbc error. + + + + 51500 + BBB reset failed, IOERROR + USB reset failed, IOERROR. + + + + groupdel + Grouping for groupdel rules. + groupdel, + + + + 51521 + group deleted + Group deleted. + groupdel, + + + + savecore + no core dump + No core dumps. + + + + reboot + rebooted by + System was rebooted. + + + + ^ftp-proxy + proxy cannot connect to server + ftp-proxy cannot connect to a server. + + + + bsd_kernel + uncorrectable data error reading fsbn + Hard drive is dying. + + + + bsd_kernel + ^carp + state transition + MASTER -> BACKUP + CARP master to backup. + + + + bsd_kernel + duplicate IP6 address + Duplicate IPv6 address. + + + + bsd_kernel + failed loadfirmware of file + Could not load a firmware. + + + + ^hotplugd + Permission denied$ + hotplugd could not open a file. + + + + open-userdel + user removed: name= + User account deleted. + account_changed, + + + + ntpd + bad peer from + Bad ntp peer. + + + + ^dhclient$ + 1002 + receive_packet failed on + dhclient receive_packet failed. + + + + 51533 + Input/output error$ + dhclient receive_packet failed due to I/O error. + + + + ^dhclient$ + 1002 + SIOCDIFADDR failed + SIOCDIFADDR failed + + + + 51535 + Device not configured$ + dhclient: device not configured. + + + + + + + + doas + doas grouping + + + + 51550 + cannot stat + doas cannot stat a file. + + + + 51551 + : Permission denied$ + doas cannot stat a file due to permissions. + + + + 51550 + path not secure$ + A critical path for doas does not have secure permissions. + + + + 51550 + failed command for + Failed doas command. + + + + 51550 + ran command + A command was run using doas. + + + + 51555 + as root + A doas command was run as root. + + + + 51550 + failed auth for + doas authentication failed. + + + + sendsyslog + ^dropped + sendsyslog dropped log messages. + + + + ntpd + Connection refused$ + ntpd peer connection refused. + + + + ntpd + recvmsg + ntpd peer connection refused. + + + + + + diff --git a/etc/rules/opensmtpd_rules.xml b/etc/rules/opensmtpd_rules.xml new file mode 100644 index 000000000..bc0134c7d --- /dev/null +++ b/etc/rules/opensmtpd_rules.xml @@ -0,0 +1,68 @@ + + + + + + smtpd + OpenSMTPd grouping. + + + + smtpd + 53500 + Failed + Message failed. + + + + smtpd + 53500 + New session + New session created. + + + + smtpd + 53500 + Closing session + Session closed. + + + + smtpd + 53500 + Accepted + Message accepted. + + + + smtpd + 53500 + delivery: Ok + Email delivered. + + + + 53501 + Command not supported$ + SMTP command not supported. + + + + smtpd + 53500 + IO error: No SSL error$ + OpenSMTPd: no SSL + + + + smtpd + 53500 + Server certificate verification failed + Server TLS certificate verification failed. + + + diff --git a/etc/rules/owncloud_rules.xml b/etc/rules/owncloud_rules.xml new file mode 100644 index 000000000..49d4c83ed --- /dev/null +++ b/etc/rules/owncloud_rules.xml @@ -0,0 +1,58 @@ + + + owncloud + ownCloud messages grouped. + + + + 53300 + Login failed: + ownCloud authentication failed. + authentication_failed, + + + + 53301 + + ownCloud brute force (multiple failed logins). + authentication_failures, + + + + 53300 + Passed filename is not valid, might be malicious + ownCloud possible malicious request. + web,appsec,attack, + + + + 53300 + ^4$ + ownCloud FATAL message. + + + + 53300 + ^3$ + ownCloud ERROR message. + + + + 53300 + ^2$ + ownCloud WARN message. + + + + 53300 + ^1$ + ownCloud INFO message. + + + + 53300 + ^0$ + ownCloud DEBUG message. + + + \ No newline at end of file diff --git a/etc/rules/pam_rules.xml b/etc/rules/pam_rules.xml new file mode 100644 index 000000000..2ab982e83 --- /dev/null +++ b/etc/rules/pam_rules.xml @@ -0,0 +1,117 @@ + + + + + + pam + Grouping of the pam_unix rules. + + + + 5500 + session opened for user + Login session opened. + authentication_success, + + + + 5500 + session closed for user + Login session closed. + + + + 5500 + authentication failure; logname= + User login failed. + authentication_failed, + + + + 5500 + check pass; user unknown|error retrieving information about user + Attempt to login with an invalid user. + invalid_login + + + + + 5501 + ^CRON$ + ^pam_unix\(cron:session\): session opened for user + Ignoring Annoying Ubuntu/debian cron login events. + + + + 5502 + ^CRON$ + ^pam_unix\(cron:session\): session closed for user + Ignoring Annoying Ubuntu/debian cron login events. + + + + 5504 + ^pam_unix\S+: check pass; user unknown$ + Ignoring events with a user or a password. + + + + 5503 + + Multiple failed logins in a small period of time. + authentication_failures, + + + + 5500 + gdm:auth\): conversation failed + PAM and gdm are not playing nicely. + + + + login + cannot open shared object file: No such file or directory + PAM misconfiguration. + + + + login + illegal module type: + PAM misconfiguration. + + + + : password changed for + User changed password. + + + + unix_chkpwd + unix_chkpwd grouping. + + + + 5556 + password check failed + Password check failed. + authentication_failure + + + + + + + diff --git a/etc/rules/php_rules.xml b/etc/rules/php_rules.xml new file mode 100644 index 000000000..08ed5834c --- /dev/null +++ b/etc/rules/php_rules.xml @@ -0,0 +1,111 @@ + + + + + + 31301, 30101 + PHP Warning: + PHP Warning message. + + + + 31301, 30101 + PHP Fatal error: + PHP Fatal error. + + + + 31301, 30101 + PHP Parse error: + PHP Parse error. + + + + ^PHP Warning: + PHP Warning message. + + + + ^PHP Fatal error: + PHP Fatal error. + + + + ^PHP Parse error: + PHP Parse error. + + + + + + 31401, 31404 + PHP Warning message. + + + + 31410 + expects parameter 1 to be string, array given in + attack, + PHP web attack. + + + + 31410 + Failed opening|failed to open stream + PHP internal error (missing file). + alert_by_email + + + + 31410 + bytes written, possibly out of free disk space in + PHP internal error (server out of space). + alert_by_email + low_diskspace, + + + + + + 31402, 31405 + PHP Fatal error. + + + + 31420 + Failed opening required |Call to undefined function + PHP internal error (missing file or function). + alert_by_email + + + + + + + 31403, 31406 + PHP Parse error. + alert_by_email + + + + + + diff --git a/etc/rules/pix_rules.xml b/etc/rules/pix_rules.xml new file mode 100644 index 000000000..53ce8fabf --- /dev/null +++ b/etc/rules/pix_rules.xml @@ -0,0 +1,237 @@ + + + + + + + + + pix + Grouping of PIX rules + + + + 4300 + ^1- + PIX alert message. + + + + 4300 + ^2- + PIX critical message. + + + + 4300 + ^3- + PIX error message. + + + + 4300 + ^4- + PIX warning message. + + + + 4300 + ^5-|^6- + PIX notification/informational message. + + + + 4300 + ^7- + PIX debug message. + + + + 4314 + ^6-605004 + Failed login attempt at the PIX firewall. + authentication_failed, + + + + 4314 + ^5-502103 + Privilege changed in the PIX firewall. + + + + 4314 + ^6-605005 + Successful login to the PIX firewall. + authentication_success, + + + + 4314 + ^6-308001 + Password mismatch while running 'enable' + on the PIX. + authentication_failed, + + + + 4313 + ^4-405001 + ARP collision detected by the PIX. + + + + 4313 + ^4-401004 + Attempt to connect from a blocked (shunned) IP. + access_denied, + + + + 4313 + ^4-710004 + Connection limit exceeded. + + + + 4310 + ^1-106021|^1-106022 + Attack in progress detected by the PIX. + + + + 4311 + ^2-106012|^2-106017|^2-106020 + Attack in progress detected by the PIX. + + + + 4313 + ^4-4000 + Attack in progress detected by the PIX. + + + + + 4330, 4331, 4332 + Attack in progress detected by the PIX. + ids, + + + + 4314 + ^6-113005 + AAA (VPN) authentication failed. + authentication_failed, + + + + 4314 + ^6-113004 + AAA (VPN) authentication successful. + authentication_success, + + + + 4314 + ^6-113006 + AAA (VPN) user locked out. + authentication_failed, + + + + 4312 + ^3-201008 + The PIX is disallowing new connections. + service_availability, + + + + 4310 + ^1-105005|^1-105009|^1-105043 + Failed|Lost Failover + Firewall failover pair communication problem. + service_availability, + + + + 4314 + ^5-111003 + Firewall configuration deleted. + config_changed, + + + + 4314 + ^5-111005|^5-111004|^5-111002|^5-111007 + Firewall configuration changed. + config_changed, + + + + 4314 + ^5-111008|^7-111009 + Firewall command executed (for accounting only). + + + + 4314 + ^5-502101|^5-502102 + User created or modified on the Firewall. + adduser,account_changed, + + + + 4310 + Multiple PIX alert messages. + + + + 4311 + Multiple PIX critical messages. + + + + 4312 + Multiple PIX error messages. + system_error, + + + + 4313 + Multiple PIX warning messages. + + + + 4333 + + Multiple attack in progress messages. + + + + 4334 + Multiple AAA (VPN) authentication failures. + authentication_failures, + + + + + diff --git a/etc/rules/policy_rules.xml b/etc/rules/policy_rules.xml new file mode 100644 index 000000000..d01e24a98 --- /dev/null +++ b/etc/rules/policy_rules.xml @@ -0,0 +1,34 @@ + + + + + + authentication_success + + Successful login during non-business hours. + login_time, + + + + authentication_success + weekends + Successful login during weekend. + login_day, + + + + + diff --git a/etc/rules/postfix_rules.xml b/etc/rules/postfix_rules.xml new file mode 100644 index 000000000..49c47809e --- /dev/null +++ b/etc/rules/postfix_rules.xml @@ -0,0 +1,162 @@ + + +6 + + + + postfix-reject + Grouping of the postfix reject rules. + + + + 3300 + ^554$ + Attempt to use mail server as relay + (client host rejected). + spam, + + + + 3300 + ^550$ + Rejected by access list + (Requested action not taken). + spam, + + + + 3300 + ^450$ + Sender domain is not found + (450: Requested mail action not taken). + spam, + + + + 3300 + ^503$ + Improper use of SMTP command pipelining + (503: Bad sequence of commands). + spam, + + + + 3300 + ^504$ + Recipient address must contain FQDN + (504: Command parameter not implemented). + spam, + + + + 3301, 3302 + blocked using + IP Address deny-listed by anti-spam (blocked). + spam, + + + + postfix + Grouping of the postfix rules. + + + + 3320 + defer service failure|Resource temporarily unavailable| + ^fatal: the Postfix mail system is not running + Postfix process error. + service_availability, + + + + 3320 + authentication failed + Postfix SASL authentication failure. + authentication_failed, + + + + 3300 + ^452 + Postfix insufficient disk space error. + service_availability, + + + + 3320 + ^daemon started + Postfix started. + + + + 3320 + ^terminating on signal + Postfix stopped. + service_availability, + + + + 3301 + + Multiple relaying attempts of spam. + multiple_spam, + + + + 3302 + + Multiple attempts to send e-mail from a + rejected sender IP (access). + multiple_spam, + + + + 3303 + + Multiple attempts to send e-mail from + invalid/unknown sender domain. + multiple_spam, + + + + 3304 + + Multiple misuse of SMTP service + (bad sequence of commands). + multiple_spam, + + + + 3305 + + Multiple attempts to send e-mail to + invalid recipient or from unknown sender domain. + multiple_spam, + + + + 3306 + + Multiple attempts to send e-mail from + deny-listed IP address (blocked). + multiple_spam, + + + + 3332 + + Multiple SASL authentication failures. + authentication_failures, + + + + ^clamsmtpd: + Grouping of the clamsmtpd rules. + + diff --git a/etc/rules/postgresql_rules.xml b/etc/rules/postgresql_rules.xml new file mode 100644 index 000000000..5b3f82c6c --- /dev/null +++ b/etc/rules/postgresql_rules.xml @@ -0,0 +1,102 @@ + + + + + + + postgresql_log + PostgreSQL messages grouped. + + + + 50500 + ^LOG + PostgreSQL log message. + + + + 50500 + ^NOTICE|INFO + PostgreSQL informational message. + + + + 50500 + ^ERROR + PostgreSQL error message. + + + + 50500 + ^FATAL + PostgreSQL error message. + + + + 50500 + ^DEBUG + PostgreSQL debug message. + + + + 50501 + duration: | statement: + Database query. + + + + 50501 + connection authorized + Database authentication success. + authentication_success, + + + + 50504 + authentication failed + Database authentication failure. + authentication_failed, + + + + 50504 + terminating connection due + Database shutdown message. + service_availability, + + + + 50501 + aborting any active transactions|shutting down + Database shutdown message. + service_availability, + + + + 50504 + Multiple database errors. + service_availability, + + + + 50503 + Multiple database errors. + service_availability, + + + + + diff --git a/etc/rules/proftpd_rules.xml b/etc/rules/proftpd_rules.xml new file mode 100644 index 000000000..f56caf58c --- /dev/null +++ b/etc/rules/proftpd_rules.xml @@ -0,0 +1,195 @@ + + + + + + + proftpd + Grouping for the proftpd rules. + + + + 11200 + FTP session opened\.$ + FTP session opened. + connection_attempt, + + + + 11200 + FTP session closed\.$ + FTP session closed. + + + + 11200 + no such user + Attempt to login using a non-existent user. + invalid_login, + + + + 11200 + Incorrect password\.$|Login failed + Login failed accessing the FTP server + authentication_failed, + + + + 11200 + Login successful + FTP Authentication success. + authentication_success, + + + + 11200 + Connection from \S+ \[\S+\] denied + Connection denied by ProFTPD configuration. + access_denied, + + + + 11200 + refused connect from + Connection refused by TCP Wrappers. + access_denied, + + + + 11200 + unable to find open port in PassivePorts range + Small PassivePorts range in config file. + Server misconfiguration. + + + + 11200 + Refused PORT + Attempt to bypass firewall that can't adequately + keep state of FTP traffic. + http://www.kb.cert.org/vuls/id/328867 + US-Cert Note VU#328867: Multiple vendors' firewalls do not adequately keep state of FTP traffic + + + + 11200 + Maximum login attempts + Multiple failed login attempts. + authentication_failures, + + + + 11200 + host name/name mismatch|host name/address mismatch + Mismatch in server's hostname. + + + + 11200 + warning: can't verify hostname: + Reverse lookup error (bad ISP config). + + + + 11200 + connect from + Remote host connected to FTP server. + connection_attempt, + + + + 11200 + FTP no transfer timeout, disconnected + Remote host disconnected due to inactivity. + + + + 11200 + FTP login timed out, disconnected + Remote host disconnected due to login time out. + + + + 11200 + FTP session idle timeout, disconnected + Remote host disconnected due to time out. + + + + 11200 + Data transfer stall timeout: + Data transfer stalled. + + + + 11200 + ProFTPD terminating \(signal 11\) + FTP process crashed. + service_availability, + + + + 11200 + Reallocating sreaddir buffer + FTP server Buffer overflow attempt. + + + + 11200 + listen\(\) failed in + Unable to bind to adress. + + + + 11200 + error setting IPV6_V6ONLY: Protocol not available| + - mod_delay/|PAM\(setcred\): System error| + PAM\(close_session\): System error|cap_set_proc failed|reverting to normal operation|error retrieving information about user + IPv6 error and mod-delay info (ignored). + + + + 11200 + unable to open incoming connection + Couldn't open the incoming connection. + Check log message for reason. + + + + 11204 + + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11201 + + Multiple connection attempts from same source. + recon, + + + + 11215 + + Multiple timed out logins from same source. + + + + + + diff --git a/etc/rules/proxmox-ve_rules.xml b/etc/rules/proxmox-ve_rules.xml new file mode 100644 index 000000000..c81fe759d --- /dev/null +++ b/etc/rules/proxmox-ve_rules.xml @@ -0,0 +1,28 @@ + + + pvedaemon + pvedaemon messages grouped. + + + + 53400 + authentication failure; + Proxmox VE authentication failed. + authentication_failed, + + + + 53401 + + Proxmox VE brute force (multiple failed logins). + authentication_failures, + + + + 53400 + successful auth for user + Proxmox VE authentication succeeded. + authentication_success, + + + \ No newline at end of file diff --git a/etc/rules/psad_rules.xml b/etc/rules/psad_rules.xml new file mode 100644 index 000000000..c3f1a6d4a --- /dev/null +++ b/etc/rules/psad_rules.xml @@ -0,0 +1,51 @@ + + + psad + psad + PSAD group + + + + 53700 + scan detected + PSAD group scan detected + + + 53700 + added iptables + PSAD group added iptables + + + + 53701 + DL: 4|DL: 5 + PSAD portscan + + + 53702 + auto-block against + PSAD auto-block + + + + 53701 + DL: 3 + PSAD level 3 warning + + + 53713 + + many PSAD level 3 warnings from same source + + + 53713 + + many PSAD level 3 warnings from same source (slow scan) + + + + 53700 + signature match: + PSAD signature match + + diff --git a/etc/rules/pure-ftpd_rules.xml b/etc/rules/pure-ftpd_rules.xml new file mode 100644 index 000000000..8579e7d81 --- /dev/null +++ b/etc/rules/pure-ftpd_rules.xml @@ -0,0 +1,91 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + \[INFO\] New connection from + New FTP connection. + connection_attempt, + + + + 11300 + \[WARNING\] Authentication failed for user + FTP Authentication failed. + authentication_failed, + + + + 11300 + \[INFO\] Logout| \[INFO\] Timeout + FTP user logout/timeout + + + + 11300 + \[NOTICE\] + FTP notice messages + + + + 11300 + \[INFO\] Can't change directory to + Attempt to access invalid directory + + + + 11302 + + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + 11300 + is now logged in + FTP Authentication success. + authentication_success, + + + + pure-transfer + Rule grouping for pure ftpd transfers. + + + + 11310 + PUT + File added to ftpd. + + + + 11310 + GET + File retrieved from ftpd. + + + + + + + + diff --git a/etc/rules/racoon_rules.xml b/etc/rules/racoon_rules.xml new file mode 100644 index 000000000..a045baff6 --- /dev/null +++ b/etc/rules/racoon_rules.xml @@ -0,0 +1,71 @@ + + + + + + + + racoon + Grouping of racoon rules. + + + + racoon-failed + VPN authentication failed. + authentication_failed, + + + + 14100 + INFO + Racoon informational message. + + + + 14100 + ERROR + Racoon error message. + + + + 14100 + WARNING + Racoon warning message. + + + + 14110 + ISAKMP-SA established + authentication_success + VPN established. + + + + 14111 + such policy does not already exist + Roadwarrior configuration (ignored error). + + + + 14112 + ignore INITIAL-CONTACT notification + Roadwarrior configuration (ignored warning). + + + + 14111 + ERROR: invalid attribute|ERROR: rejected + Invalid configuration settings (ignored error). + + + + 14101 + + Multiple failed VPN logins. + + diff --git a/etc/rules/roundcube_rules.xml b/etc/rules/roundcube_rules.xml new file mode 100644 index 000000000..45d00645f --- /dev/null +++ b/etc/rules/roundcube_rules.xml @@ -0,0 +1,44 @@ + + + + + roundcube + Roundcube messages grouped. + + + + 9400 + failed \(LOGIN\)| Login failed | Authentication failed| Failed login + Roundcube authentication failed. + authentication_failed, + + + + 9400 + Successful login + Roundcube authentication succeeded. + authentication_success, + + + + 9401 + + Roundcube brute force (multiple failed logins). + authentication_failures, + + + + + diff --git a/etc/rules/rules_config.xml b/etc/rules/rules_config.xml new file mode 100644 index 000000000..c9ab28996 --- /dev/null +++ b/etc/rules/rules_config.xml @@ -0,0 +1,69 @@ + + + + + + syslog + Generic template for all syslog rules. + + + + + + firewall + Generic template for all firewall rules. + + + + + + ids + Generic template for all ids rules. + + + + + + web-log + Generic template for all web rules. + + + + + + squid + Generic template for all web proxy rules. + + + + + + windows + Generic template for all windows rules. + + + + + + openarmor + Generic template for all openarmor rules. + + + + + diff --git a/etc/rules/sendmail_rules.xml b/etc/rules/sendmail_rules.xml new file mode 100644 index 000000000..8e8bb77ff --- /dev/null +++ b/etc/rules/sendmail_rules.xml @@ -0,0 +1,150 @@ + + + + + + sendmail-reject + Grouping of the sendmail rules. + + + + 3100 + reject= + Grouping of the sendmail reject rules. + + + + 3101 + reject=451 4\.1\.8 + Sender domain does not have any valid + MX record (Requested action aborted). + spam, + + + + 3101 + reject=550 5\.0\.0 |reject=553 5\.3\.0 + Rejected by access list + (55x: Requested action not taken). + spam, + + + + 3101 + reject=550 5\.7\.1 + Attempt to use mail server as relay + (550: Requested action not taken). + spam, + + + + 3101 + reject=553 5\.1\.8 + Sender domain is not found + (553: Requested action not taken). + spam, + + + + 3101 + reject=553 5\.5\.4 + Sender address does not have domain + (553: Requested action not taken). + spam, + + + + 3101 + Sendmail rejected message. + + + + 3100 + rejecting commands from + Sendmail rejected due to pre-greeting. + spam, + + + + 3100 + savemail panic + Sendmail save mail panic. + system_error, + + + + 3102 + + Sender domain has bogus MX record. + It should not be sending e-mail. + multiple_spam, + + + + 3103 + + Multiple attempts to send e-mail from a + previously rejected sender (access). + multiple_spam, + + + + 3104 + + Multiple relaying attempts of spam. + multiple_spam, + + + + 3105 + + Multiple attempts to send e-mail + from invalid/unknown sender domain. + multiple_spam, + + + + 3106 + + Multiple attempts to send e-mail from + invalid/unknown sender. + multiple_spam, + + + + 3107 + + Multiple rejected e-mails from same source ip. + multiple_spam, + + + + 3108 + + Multiple pre-greetings rejects. + multiple_spam, + + + + + + smf-sav-reject + Grouping of the smf-sav sendmail milter rules. + smf-sav, + + + + 3190 + ^sender check failed|^sender check tempfailed + SMF-SAV sendmail milter unable to verify + address (REJECTED). + smf-sav,spam, + + + diff --git a/etc/rules/smbd_rules.xml b/etc/rules/smbd_rules.xml new file mode 100644 index 000000000..28b1b4b59 --- /dev/null +++ b/etc/rules/smbd_rules.xml @@ -0,0 +1,97 @@ + + + + + + + smbd + Grouping for the smbd rules. + + + + 13100 + getpeername failed\. Error was Transport endpoint + Samba network problems. + + + + 13100 + Denied connection from|Connection denied from + Samba connection denied. + access_denied, + + + + 13100 + Connection reset by peer + Samba network problems. + + + + 13100 + Permission denied-- + User action denied by configuration. + access_denied, + + + + 13100 + Unable to connect to CUPS server + Samba network problems (unable to connect). + + + + nmbd + + + + 13100 + smbd is already running + An attempt has been made to start smbd but the process is already running. + + + + 13106 + nmbd is already running + An attempt has been made to start nmbd but the process is already running. + + + + 13100 + Connection denied from + Connection was denied. + + + + 13100 + Socket is not connected + Socket is not connected, write failed. + + + + iptables + gvfsd-smb.* segfault at \S+ ip \S+ sp \S+ error \d+ in + Segfault in gvfs-smb. + + + + + + + + diff --git a/etc/rules/solaris_bsm_rules.xml b/etc/rules/solaris_bsm_rules.xml new file mode 100644 index 000000000..c08f41f28 --- /dev/null +++ b/etc/rules/solaris_bsm_rules.xml @@ -0,0 +1,65 @@ + + + + + + + solaris_bsm + Solaris BSM Auditing messages grouped. + + + + 6100 + ^failed + Auditing session failed. + + + + 6100 + ^ok + Auditing session succeeded. + + + + 6102 + ^login + Login session succeeded. + authentication_success, + + + + 6101 + ^login + Login session failed. + authentication_failed, + + + + 6102 + ^su + User successfully changed UID. + authentication_success, + + + + 6103 + ^su + User failed to change UID (user id). + authentication_failed, + + + + diff --git a/etc/rules/sonicwall_rules.xml b/etc/rules/sonicwall_rules.xml new file mode 100644 index 000000000..dba0cf106 --- /dev/null +++ b/etc/rules/sonicwall_rules.xml @@ -0,0 +1,93 @@ + + + + + + + sonicwall + SonicWall messages grouped. + + + + 4800 + ^1 + SonicWall critical message. + + + + 4800 + ^2 + SonicWall critical message. + + + + 4800 + ^3 + SonicWall error message. + + + + 4800 + ^4 + SonicWall warning message. + + + + 4800 + ^5 + SonicWall notice message. + + + + 4800 + ^6 + SonicWall informational message. + + + + 4800 + ^7 + SonicWall debug message. + + + + 4806 + ^236$ + Firewall administrator login. + authentication_success, + + + + 4801 + ^30$|^32$ + Firewall authentication failure. + authentication_failed, + + + + 4804 + Multiple firewall warning messages. + service_availability, + + + + 4803 + Multiple firewall error messages. + service_availability, + + + + diff --git a/etc/rules/spamd_rules.xml b/etc/rules/spamd_rules.xml new file mode 100644 index 000000000..ca1eecbb8 --- /dev/null +++ b/etc/rules/spamd_rules.xml @@ -0,0 +1,31 @@ + + + + + + + ^spamd + Grouping for the spamd rules + + + + 3500 + : result: + SPAMD result message (not very usefull here). + + + + 3500 + checking message | processing message + Spamd debug event (reading message). + + + + + diff --git a/etc/rules/squid_rules.xml b/etc/rules/squid_rules.xml new file mode 100644 index 000000000..14d2a3ba0 --- /dev/null +++ b/etc/rules/squid_rules.xml @@ -0,0 +1,212 @@ + + + + + + + +8 + + + + + squid + Squid messages grouped. + + + + + + 35000 + ^4|^5|^6 + Squid generic error codes. + + + + 35002 + ^400 + Bad request/Invalid syntax. + + + + 35002 + ^401 + Unauthorized: Failed attempt to access + authorization-required file or directory. + + + + 35002 + ^403 + Forbidden: Attempt to access forbidden file + or directory. + + + + 35002 + ^404 + Not Found: Attempt to access non-existent + file or directory. + + + + 35002 + ^407 + Proxy Authentication Required: User is not + authorized to use proxy. + + + + 35002 + ^4 + Squid 400 error code (request failed). + + + + 35002 + ^5|^6 + Squid 500/600 error code (server error). + + + + 35009 + ^503 + Squid 503 error code (server unavailable). + + + + + 35006 + blst\.php|xxx3\.php|ngr7\.php|ngr2\.php|/nul\.php$|/mul\.php$|/444\.php + Attempt to access a Beagle worm (or variant) + file. + http://www.symantec.com/avcenter/venc/data/w32.beagle.dp.html + W32.Beagle.DP is a Worm that drops Trojan.Lodear and opens a back door on the compromised computer. + automatic_attack, + + + + + 35006 + /jk/exp\.wmf$|/PopupSh\.ocx$ + Attempt to access a worm/trojan related site. + automatic_attack, + + + + + 35004, 35005, 35006, 35009 + \.jpg|\.gif|favicon\.ico$|\.png$|\.swf|\.txt$|\.zip|\.css|\.xml|\.js|\.bmp$| + windowsupdate/redir/wuredir\.cab| + ^http://codecs\.microsoft\.com/isapi/ocget\.dll| + ^http://activex\.microsoft\.com/objects/ocget\.dll| + ^http://webmessenger\.msn\.com/session/null| + ^http://sqm\.msn\.com/sqm/wmp/sqmserver\.dll| + ^http://config\.messenger\.msn\.com/Config/MsgrConfig\.asmx| + kaspersky-labs\.com/| + ^http://liveupdate\.symantecliveupdate\.com/| + _vti_bin/owssvr\.dll|MSOffice/cltreq\.asp| + google\.com/mt\?| + google\.com/kh\?| + ^http://kh\.google\.com/flatfile + + + + Ignored files on a 40x error. + + + + + 35005 + + + Multiple attempts to access forbidden file + or directory from same source ip. + + + + 35007 + + Multiple unauthorized attempts to use proxy. + + + + 35003 + + + Multiple Bad requests/Invalid syntax. + + + + 35021 + + Infected machine with W32.Beagle.DP. + http://www.symantec.com/avcenter/venc/data/w32.beagle.dp.html + W32.Beagle.DP is a Worm that drops Trojan.Lodear and opens a back door on the compromised computer. + + + + 35006 + + + Multiple attempts to access a non-existent file. + + + + 35022 + + Multiple attempts to access a worm/trojan/virus + related web site. System probably infected. + + + + 35008 + + + Multiple 400 error codes (requests failed). + + + + 35009 + + + Multiple 500/600 error codes (server error). + + + + 35055 + + Ignoring multiple attempts from same source ip + (alert only once). + + + + + + diff --git a/etc/rules/sshd_rules.xml b/etc/rules/sshd_rules.xml new file mode 100644 index 000000000..fb791feb5 --- /dev/null +++ b/etc/rules/sshd_rules.xml @@ -0,0 +1,404 @@ + + + + + + + sshd + SSHD messages grouped. + + + + 5700 + Bad protocol version identification|error: Protocol major versions differ + Possible attack on the ssh server + (or version gathering). + + + + 5700 + ^reverse mapping.*failed - POSSIBLE BREAK + Reverse lookup error (bad ISP or attack). + + + + 5702 + Possible breakin attempt + (high number of reverse lookup errors). + + + + 5700 + fatal: Timeout before authentication for + Timeout while logging in (sshd). + + + + 5704 + Possible scan or breakin attempt + (high number of login timeouts). + + + + 5700 + Did not receive identification string from + SSH insecure connection attempt (scan). + recon, + + + + 5700 + fatal: buffer_get_string: bad string + OpenSSH challenge-response exploit. + exploit_attempt, + + + + 5700 + error: Could not get shadow information for NOUSER| + fatal: Read from socket failed: |error: ssh_msg_send: write| + ^syslogin_perform_logout: |^pam_succeed_if\(sshd:auth\): error retrieving information about user|can't verify hostname: getaddrinfo + Useless SSHD message without an user/ip and context. + + + + 5700 + illegal user|invalid user + Attempt to login using a non-existent user + invalid_login,authentication_failed, + + + + 5700 + authentication failure; logname= uid=0 euid=0 tty=ssh| + input_userauth_request: invalid user| + PAM: User not known to the underlying authentication module for illegal user| + error retrieving information about user + Useless/Duplicated SSHD message without a user/ip. + + + + 5710 + SSHD brute force trying to get access to + the system. + + authentication_failures, + + + + 5700 + Corrupted check bytes on + Corrupted bytes on SSHD. + + + + 5713 + Local: crc32 compensation attack + SSH CRC-32 Compensation attack + 2001-0144 + http://www.securityfocus.com/bid/2347/info/ + exploit_attempt, + + + + 5700 + ^Accepted|authenticated\.$ + SSHD authentication success. + authentication_success, + + + + 5700 + ^Failed|^error: PAM: Authentication + SSHD authentication failed. + authentication_failed, + + + + 5700 + error: Bad prime description in line + SSHD configuration error (moduli). + + + + 5700 + not allowed because + Attempt to login using a denied user. + invalid_login, + + + + 5718 + Multiple access attempts using a denied user. + invalid_login, + + + + 5716 + + Multiple SSHD authentication failures. + authentication_failures, + + + + 5700 + Received disconnect from + System disconnected from sshd. + + + + 5700 + Connection closed + ssh connection closed. + + + + 5700 + error: buffer_get_bignum2_ret: negative numbers not supported + This maybe a bad key in authorized_keys. + SSHD key error. + + + + 5700 + fatal: buffer_get_bignum2: buffer error + This error may relate to ssh key handling. + SSHD key error. + + + + 5700 + fatal: Write failed: Host is down + Host ungracefully disconnected. + + + + 5700 + error: PAM: Module is unknown for + Unknown PAM module, PAM misconfiguration. + + + + 5700 + failed: Address already in use\. + Attempt to start sshd when something already bound to the port. + + + + 5700 + Authentication service cannot retrieve user credentials + May be related to PAM module errors. + Authentication services were not able to retrieve user credentials. + authentication_failed + + + + 5700 + debug1: attempt + Debug message. + + + + 5700 + error: connect to \S+ port \d+ failed: Connection refused + SSHD is not accepting connections. + + + + 5700 + AKASSH_Version_Mapper1\. + SSH Scanning. + recon, + + + + 5700 + error: connect_to + Possible port forwarding failure. + + + + 5700 + Invalid credentials + User entered incorrect password. + authentication_failures, + + + + 5700 + Could not load host key + sshd could not load one or more host keys. + This may be related to an upgrade to OpenSSH. + + + + 5700 + Write failed: Broken pipe + Failed write due to one host disappearing. + + + + 5700 + ^error: setsockopt SO_KEEPALIVE: Connection reset by peer$| + ^error: accept: Software caused connection abort$ + Connection reset or aborted. + + + + 5700 + ^fatal: Cannot bind any address\.$ + sshd cannot bind to configured address. + + + + 5700 + set_loginuid failed opening loginuid$ + pam_loginuid could not open loginuid. + authentication_failed, + + + + 5700 + ^error: Could not stat AuthorizedKeysCommand + SSHD configuration error (AuthorizedKeysCommand) + + + + 5700 + Connection reset by peer$ + ssh connection reset by peer + + + + 5700 + Connection refused$ + ssh connection refused + + + + 5700 + Connection timed out$ + ssh connection timed out + + + + 5700 + No route to host$ + ssh no route to host + + + + 5700 + failure direct-tcpip$ + ssh port forwarding issue + + + + 5700 + Transport endpoint is not connected$ + ssh transport endpoint is not connected + + + + 5700 + get_remote_port failed$ + ssh get_remote_port failed + + + + + 5700 + bad client public DH value + ssh bad client public DH value + + + + + 5700 + Corrupted MAC on input\. + ssh corrupted MAC on input + + + + 5700 + ^Bad packet length + ssh bad packet length + + + + sshd + 5700 + Unable to negotiate with |Unable to negotiate a key + sshd could not negotiate with client. + + + + sshd + 5700 + no hostkey alg \[preauth\] + No hostkey alg. + + + + 5750 + no matching key exchange method found\.|Unable to negotiate a key exchange method + Client did not offer an acceptable key exchange method. + + + + 5750 + no matching cipher found\. + sshd could not negotiate with client, no matching cipher. + + + + 5700 + Failed to create session: + sshd failed to create a session. + + + + 5700 + bad ownership or modes for file + Authentication refused due to owner/permissions of authorized_keys. + authentication_failed, + + + + 5700 + failed, subsystem not found$ + sshd subsystem request failed. + + + + sshd + but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!$ + Bad DNS mapping. + + + + sshd + ^error: maximum authentication attempts exceeded + Maximum authentication attempts exceeded. + authentication_failed, + + + + + diff --git a/etc/rules/symantec-av_rules.xml b/etc/rules/symantec-av_rules.xml new file mode 100644 index 000000000..227566a8a --- /dev/null +++ b/etc/rules/symantec-av_rules.xml @@ -0,0 +1,51 @@ + + + + + + + + + symantec-av + Grouping of Symantec AV rules. + + + + windows + ^Symantec AntiVirus + Grouping of Symantec AV rules from eventlog. + + + + 7300, 7301 + ^5$|^17$ + virus + Virus detected. + + + + 7300, 7301 + ^2$|^3$|^4$|^13$ + Virus scan updated,started or stopped. + + + + + + diff --git a/etc/rules/symantec-ws_rules.xml b/etc/rules/symantec-ws_rules.xml new file mode 100644 index 000000000..bc8781735 --- /dev/null +++ b/etc/rules/symantec-ws_rules.xml @@ -0,0 +1,64 @@ + + + + + + + + + + symantec-websecurity + Grouping of Symantec Web Security rules. + + + + 7400 + ^3=2,2=1 + Login failed accessing the web proxy. + authentication_failed, + + + + 7400 + ^3=1,2=1 + Login success accessing the web proxy. + authentication_success, + + + + 7415 + virtadmin + Admin Login success to the web proxy. + authentication_success, + + + + + + + + diff --git a/etc/rules/syslog_rules.xml b/etc/rules/syslog_rules.xml new file mode 100644 index 000000000..8ac832a7f --- /dev/null +++ b/etc/rules/syslog_rules.xml @@ -0,0 +1,725 @@ + + + + + + +core_dumped|failure|error|attack| bad |illegal |denied|refused|unauthorized|fatal|failed|Segmentation Fault|Corrupted + + + + + + ^Couldn't open /etc/securetty + File missing. Root access unrestricted. + + + + $BAD_WORDS + alert_by_email + Unknown problem somewhere in the system. + + + + Non standard syslog message (size too large). + + + + ^exiting on signal + Syslogd exiting (logging stopped). + + + + syslogd + ^restart + Syslogd restarted. + + + + ^syslogd \S+ restart + Syslogd restarted. + + + + file system full|No space left on device + File system full. + low_diskspace, + + + + killed by SIGTERM + Process exiting (killed). + service_availability, + + + + 1002 + terminated without error|can't verify hostname: getaddrinfo| + PPM exceeds tolerance + Ignoring known false positives on rule 1002.. + + + + segfault at + Process segfaulted. + service_availability, + + + + + + + + + + ^automount|^mount + NFS rules grouped. + + + + 2100 + nfs: mount failure + Unable to mount the NFS share. + + + + 2100 + reason given by server: Permission denied + Unable to mount the NFS directory. + + + + ^rpc\.mountd: refused mount request from + Unable to mount the NFS directory. + + + + 2100 + lookup for \S+ failed + Automount informative message + + + + + + + + + ^Deactivating service + Excessive number connections to a service. + + + + + + + + + FAILED LOGIN |authentication failure| + Authentication failed for|invalid password for| + LOGIN FAILURE|auth failure: |authentication error| + authinternal failed|Failed to authorize| + Wrong password given for|login failed|Auth: Login incorrect| + Failed to authenticate user + authentication_failed, + User authentication failure. + + + + more authentication failures;|REPEATED login failures + User missed the password more than one time + authentication_failed, + + + + ^refused connect from| + ^libwrap refused connection| + Connection from \S+ denied + Connection blocked by Tcp Wrappers. + access_denied, + + + + ILLEGAL ROOT LOGIN|ROOT LOGIN REFUSED + Illegal root login. + invalid_login, + + + + ^ROOT LOGIN on + Physical root login. + + + + ^Authentication passed + Pop3 Authentication passed. + + + + openldap + OpenLDAP group. + + + + 2507 + ACCEPT from + OpenLDAP connection open. + + + + 2507 + 2508 + + RESULT tag=97 err=49 + OpenLDAP authentication failed. + + + + + + + + + + rshd + rshd messages grouped. + + + + 2550 + ^Connection from \S+ on illegal port$ + Connection to rshd from unprivileged port. Possible network scan. + connection_attempt, + + + + + + + + + ^procmail + Ignoring procmail messages. + + + + + + + + + ^smart + Pre-match rule for smartd. + + + + 2800 + No configuration file /etc/smartd\.conf found + Smartd Started but not configured + + + + 2800 + Unable to register ATA device + Smartd configuration problem + + + + 2800 + No such device or address + Device configured but not available to Smartd + + + + + + + + + ^kernel + Pre-match rule for kernel messages + + + + 5100 + PCI: if you experience problems, try using option + Informative message from the kernel. + + + + 5100 + modprobe: Can't locate module sound + Informative message from the kernel + + + + 5100 + Oversized packet received from + Error message from the kernel. + Ping of death attack. + + + + 5100 + Promiscuous mode enabled| + device \S+ entered promiscuous mode + Interface entered in promiscuous(sniffing) mode. + promisc, + + + + 5100 + end_request: I/O error, dev fd0, sector 0| + Buffer I/O error on device fd0, logical block 0 + Invalid request to /dev/fd0 (bug on the kernel). + + + + 5100 + svc: unknown program 100227 \(me 100003\) + NFS incompatibility between Linux and Solaris. + + + + 5100 + svc: bad direction + NFS incompatibility between Linux and Solaris. + + + + 5100 + Out of Memory: + System running out of memory. + Availability of the system is in risk. + service_availability, + + + + 5100 + I/O error: dev |end_request: I/O error, dev + Kernel Input/Output error + + + + 5100 + Forged DCC command from + IRC misconfiguration + + + + 5100 + ipw2200: Firmware error detected\.| ACPI Error + Kernel device error. + + + + 5100 + usbhid: probe of + Kernel usbhid probe error (ignored). + + + + 5100 + Kernel log daemon terminating + system_shutdown, + System is shutting down. + + + + 5100 + ADSL line is down + Monitor ADSL line is down. + + + + 5100 + ADSL line is up + Monitor ADSL line is up. + + + + ^hpiod: unable to ParDevice + Ignoring hpiod for producing useless logs. + + + + + + + + + crond|crontab + Crontab rule group. + + + + 2830 + ^unable to exec + Wrong crond configuration + + + + 2830 + BEGIN EDIT + Crontab opened for editing. + + + + 2830 + REPLACE + Crontab entry changed. + + + + 2832 + ^\(root\) + Root's crontab entry changed. + + + + + + + + + + su + Initial grouping for su messages. + + + + 5300 + authentication failure; |failed|BAD su|^- + User missed the password to change UID (user id). + authentication_failed, + + + + 5301 + ^root + User missed the password to change UID to root. + authentication_failed, + + + + 5300 + session opened for user root|^'su root'| + ^\+ \S+ \S+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]root$|^\S+ to root on|^SU \S+ \S+ \+ \S+ \S+-root$ + User successfully changed UID to root. + authentication_success, + + + + 5300 + session opened for user|succeeded for| + ^\+|^\S+ to |^SU \S+ \S+ \+ + User successfully changed UID. + authentication_success, + + + + 5303, 5304 + + alert_by_email + First time (su) is executed by user. + + + + 5300 + unknown class + OpenBSD uses login classes, and an inappropriate login class was used. + A user has attempted to su to an unknown class. + + + + + + + + + + Integrity Check failed: File could not + Problems with the tripwire checking + + + + + + + + + ^new group + New group added to the system + + + + ^new user|^new account added + New user added to the system + + + + ^delete user|^account deleted|^remove group + Group (or user) deleted from the system + + + + ^changed user + Information from the user was changed + + + + useradd + failed adding user + useradd failed. + + + + + + + + + + sudo + Initial group for sudo messages + + + + 5400 + incorrect password attempt + Failed attempt to run sudo + + + + 5400 + ; USER=root ; COMMAND=| ; USER=root ; TSID=\S+ ; COMMAND= + Successful sudo to ROOT executed + + + + 5400 + alert_by_email + + First time user executed sudo. + + + + 5401 + 3 incorrect password attempts + Three failed attempts to run sudo + + + + 5400 + user NOT in sudoers + Unauthorized user attempted to use sudo. + + + + + + + + + ^pptpd + PPTPD messages grouped + + + + 9100 + ^GRE: \S+ from \S+ failed: status = -1 + PPTPD failed message (communication error) + http://poptop.sourceforge.net/dox/gre-protocol-unavailable.phtml + + + + 9100 + ^tcflush failed: Bad file descriptor + PPTPD communication error + + + + + + + + + authentication_success + alert_by_email + + authentication_success + First time user logged in. + + + + + + + ^squid + Squid syslog messages grouped + + + + 9200 + ^ctx: enter level|^sslRead|^urlParse: Illegal | + ^httpReadReply: Request not yet |^httpReadReply: Excess data + Squid debug message + + + + + + + windows-date-format + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} startup | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} status | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} remove | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} configure | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} install | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} purge | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} trigproc | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} conffile | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} upgrade + Dpkg (Debian Package) log. + + + + 2900 + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} install + New dpkg (Debian Package) requested to install. + + + + 2900 + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} status installed + New dpkg (Debian Package) installed. + config_changed, + + + + 2900 + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} remove| + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} purge + Dpkg (Debian Package) removed. + config_changed, + + + + + + + ^yum + Yum logs. + + + + yum\.log$ + ^Installed|^Updated|^Erased + Yum logs. + + + + 2930,2931 + ^Installed + config_changed, + New Yum package installed. + + + + 2930,2931 + ^Updated + config_changed, + Yum package updated. + + + + 2930,2931 + ^Erased + config_changed, + Yum package deleted. + + + + + 5100 + mptscsih + Grouping for the mptscrih rules. + + + + 5100 + mptbase + Grouping for the mptbase rules. + + + + 2935 + FAILED + Possible Disk failure. SCSI controller error. + + + + 2936 + failed + SCSI RAID ARRAY ERROR, drive failed. + + + + 2936 + degraded + SCSI RAID is now in a degraded status. + + + + ^NetworkManager + NetworkManager grouping. + + + + 2940 + No chain/target/match by that name\.$ + Incorrect chain/target/match. + + + + 1002 + g_slice_set_config: assertion `sys_page_size == 0' failed + Uninteresting gnome error. + + + + ^nouveau + nouveau driver grouping + + + + 2943 + DATA_ERROR BEGIN_END_ACTIVE$| DATA_ERROR$ + Uninteresting nouveau error. + + + + ^rsyslogd + ^imuxsock begins to drop messages + https://isc.sans.edu/diary/Are+you+losing+system+logging+information+%28and+don%27t+know+it%29%3F/15106 + rsyslog may be dropping messages due to rate-limiting. + + + + + + diff --git a/etc/rules/sysmon_rules.xml b/etc/rules/sysmon_rules.xml new file mode 100644 index 000000000..bb1c32a1e --- /dev/null +++ b/etc/rules/sysmon_rules.xml @@ -0,0 +1,173 @@ + + + + + + + + + 18100 + svchost\.exe + Sysmon - Suspicious Process - svchost.exe + + + + 18501 + \\services\.exe + Sysmon - Legitimate Parent Image - svchost.exe + + + + + 18100 + lsm\.exe + Sysmon - Suspicious Process - lsm.exe + + + + 18511 + wininit\.exe + Sysmon - Legitimate Parent Image - lsm.exe + + + + 18100 + lsm\.exe + Sysmon - Suspicious Process - lsm.exe is a Parent Image + + + + + 18100 + csrss\.exe + Sysmon - Suspicious Process - csrss.exe + + + + 18521 + smss\.exe + Sysmon - Legitimate Parent Image - csrss.exe + + + + + 18100 + lsass\.exe + Sysmon - Suspicious Process - lsass + + + + 18531 + wininit\.exe + Sysmon - Legitimate Parent Image - lsass.exe + + + + 18100 + lsass\.exe + Sysmon - Suspicious Process - lsass.exe is a Parent Image + + + + + 18100 + winlogon\.exe + Sysmon - Suspicious Process - winlogon.exe + + + + 18541 + smss\.exe + Sysmon - Legitimate Parent Image - winlogon.exe + + + + + 18100 + wininit\.exe + Sysmon - Suspicious Process - wininit + + + + 18551 + smss\.exe + Sysmon - Legitimate Parent Image - wininit.exe + + + + + 18100 + smss\.exe + Sysmon - Suspicious Process - smss.exe + + + + 18561 + system + Sysmon - Legitimate Parent Image - smss.exe + + + + + 18100 + taskhost\.exe + Sysmon - Suspicious Process - taskhost.exe + + + + 18571 + services\.exe|svchost\.exe + Sysmon - Legitimate Parent Image - taskhost.exe + + + + + 18100 + /services\.exe + Sysmon - Suspicious Process - services.exe + + + + 18581 + wininit\.exe + Sysmon - Legitimate Parent Image - services.exe + + + + + 18100 + dllhost\.exe + Sysmon - Suspicious Process - dllhost.exe + + + + 18591 + svchost\.exe|services\.exe + Sysmon - Legitimate Parent Image - dllhost.exe + + + + + 18100 + \\explorer\.exe + Sysmon - Suspicious Process - explorer.exe + + + + 18601 + userinit\.exe + Sysmon - Legitimate Parent Image - explorer.exe + + + + diff --git a/etc/rules/systemd_rules.xml b/etc/rules/systemd_rules.xml new file mode 100644 index 000000000..f8cec7714 --- /dev/null +++ b/etc/rules/systemd_rules.xml @@ -0,0 +1,27 @@ + + + + ^systemd$|^systemctl$ + Systemd rules + + + + 40700 + Stale file handle$ + Stale file handle. + + + + 40700 + Failed to get unit file state for + Failed to get unit state for service. This means that the .service file is missing + + + + 40700 + entered failed state + Service has entered a failed state, and likely has not started. + + + + diff --git a/etc/rules/telnetd_rules.xml b/etc/rules/telnetd_rules.xml new file mode 100644 index 000000000..711a43426 --- /dev/null +++ b/etc/rules/telnetd_rules.xml @@ -0,0 +1,45 @@ + + + + + + telnetd + Grouping for the telnetd rules + + + + 5600 + refused connect from + Connection refused by TCP Wrappers. + + + + 5600 + : connect from + Remote host established a telnet connection. + + + + ttloop: peer died:|ttloop: read: + 5602 + Remote host invalid connection. + + + + warning: can't verify hostname: + Reverse lookup error (bad hostname config). + + + + 5602 + + Multiple connection attempts from same source + (possible scan). + + + diff --git a/etc/rules/topleveldomain_rules.xml b/etc/rules/topleveldomain_rules.xml new file mode 100644 index 000000000..18813763a --- /dev/null +++ b/etc/rules/topleveldomain_rules.xml @@ -0,0 +1,14 @@ + + + + + + + + + 31100 + \.top:|\.to:|\.gq:|\.cf:|\.men:|\.loan:|\.ml:|\.work:|\.click:|\.tk:|\.country:|\.pw:|\.party:|\.trade:|\.review:|\.club:|\.bid:|\.country:|\.stream:|\.download:|\.xin:|\.gdn:|\.racing:|\.jetzt:|\.win:|\.vip:|\.ren:|\.kim:|\.mom:|\.date:|\.wang:|\.accountants:|\.science:|\.work:|\.ninja:|\.xyz:|\.faith:|\.zip:|\.racing:|\.cricket:|\.space:|\.realtor:|\.christmas:|\.gdn:|\.pro: + Maybe critical URL access attempt + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_da.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_da.xml new file mode 100644 index 000000000..17523fe63 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_da.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Ny forbindelse fra + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Godkendelse mislykkedes for + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout| [INFO] Timeout + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Kan ikke ændre mappen til + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ er logget på nu + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_de.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_de.xml new file mode 100644 index 000000000..51f04b01a --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_de.xml @@ -0,0 +1,69 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Neue Verbindung von + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Authentifizierung fehlgeschlagen + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout | [INFO] Zeitüberschreitung + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Kann nicht ins Verzeichnis \S+ wechseln + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ ist jetzt eingeloggt + FTP Authentication success. + authentication_success, + + + + + \ No newline at end of file diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_en.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_en.xml new file mode 100644 index 000000000..1e418011d --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_en.xml @@ -0,0 +1,69 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] New connection from + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Authentication failed for user + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout| [INFO] Timeout + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Can't change directory to + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ is now logged in + FTP Authentication success. + authentication_success, + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_es.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_es.xml new file mode 100644 index 000000000..a374663ed --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_es.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nueva conexión desde + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Autentificación fallida para el usuario + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Fin de sesión.| [INFO] Timeout + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] No puedo cambiar al directorio + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ está ahora dentro del sistema + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_fr.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_fr.xml new file mode 100644 index 000000000..b4e69acb9 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_fr.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nouvelle connexion de + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Erreur d'authentification pour l'utilisateur + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Deloggue.| [INFO] Temps de reponse depasse + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Ne peut changer le repertoire en + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ est maintenant loggue + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_fr_funny.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_fr_funny.xml new file mode 100644 index 000000000..f45fbc883 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_fr_funny.xml @@ -0,0 +1,69 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] \S+ ramene son cul + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] \S+ c'est un batard, il connait pas son code + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Cassos | [INFO] Putain mais achete-toi des doigts + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] C'est quoi ce delire, je peux pas aller dans + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ vient de debarquer + FTP Authentication success. + authentication_success, + + + + + \ No newline at end of file diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_it.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_it.xml new file mode 100644 index 000000000..13ff08e70 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_it.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nuova connessione da + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Autenticazione falita per l'utente + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout.| [INFO] Timeout + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Impossibile cambiare la directory in + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ è ora loggato + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_nl.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_nl.xml new file mode 100644 index 000000000..6a63b1a6f --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_nl.xml @@ -0,0 +1,69 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nieuwe verbinding vanaf + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Autorisatie faalde voor gebruiker + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout | [INFO] Onderbreking + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Kan de directory niet veranderen naar + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ is nu ingelogd + FTP Authentication success. + authentication_success, + + + + + \ No newline at end of file diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_no.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_no.xml new file mode 100644 index 000000000..5b16a44fc --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_no.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Ny tilkobling fra + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Godkjennelse mislyktes for + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logg ut.| [INFO] Timeout + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Kan ikke skifte katalog til + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ er nå logget inn + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_pt_br.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_pt_br.xml new file mode 100644 index 000000000..f157c6dd0 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_pt_br.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nova conexão a partir de + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Autenticação falhou para usuário + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Fim de sessão.| [INFO] Tempo expirado + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Não foi possível entrar no diretório + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ agora está logado + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_ro.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_ro.xml new file mode 100644 index 000000000..cdd9e4dc4 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_ro.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Conexiune noua de la + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Autentificare esuata pentru utilizatorul + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Iesire.| [INFO] Temporizare expirata + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Nu pot intra in directorul + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ este acum logat + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_sk.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_sk.xml new file mode 100644 index 000000000..2ad28267b --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_sk.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nove spojenie z + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Autentifikacia uzivatela zlyhala + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout.| [INFO] Cas vyprsal + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Nemozem prejst do adresara + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ je prave prihlaseny + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_sv.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_sv.xml new file mode 100644 index 000000000..a95e397d3 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_sv.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] Nyanslutning från + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] Behörighetskontroll misslyckas för användare + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Logout| [INFO] Timeout + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Kan ej ändra bibliotek till + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ har loggat in + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/translated/pure_ftpd/pure-ftpd_rules_tr.xml b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_tr.xml new file mode 100644 index 000000000..99a83f2e4 --- /dev/null +++ b/etc/rules/translated/pure_ftpd/pure-ftpd_rules_tr.xml @@ -0,0 +1,70 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + [INFO] \S+ den yeni baðlantý + New FTP connection. + connection_attempt, + + + + 11300 + [WARNING] \S+ kullanýcýsý için giriþ hatalý + FTP Authentication failed. + authentication_failed, + + + + 11300 + [INFO] Çýkýþ.| [INFO] Zaman Aþýmý + FTP user logout/timeout + + + + 11300 + [NOTICE] + FTP notice messages + + + + 11300 + [INFO] Klasör deðiþtirilemedi + Attempt to access invalid directory + + + + 11302 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + [INFO] \S+ giriþ yaptý + FTP Authentication success. + authentication_success, + + + + + + diff --git a/etc/rules/trend-osce_rules.xml b/etc/rules/trend-osce_rules.xml new file mode 100644 index 000000000..0f54ab252 --- /dev/null +++ b/etc/rules/trend-osce_rules.xml @@ -0,0 +1,56 @@ + + + + + + + + + trend-osce + Grouping of Trend OSCE rules. + + + + 7600 + ^0|$|^1$|^2$|^33|^10$|^11$|^12$ + virus + Virus detected and cleaned/quarantined/removed + + + + 7600 + ^5$|^6$|^7$|^8$|^14$|^15$|^16$ + virus + Virus detected and unable to clean up. + + + + 7600 + ^4$|^13$ + Virus scan completed with no errors detected. + + + + 7600 + ^25$ + Virus scan passed by found potential security risk. + + + + + diff --git a/etc/rules/unbound_rules.xml b/etc/rules/unbound_rules.xml new file mode 100644 index 000000000..9bf089b35 --- /dev/null +++ b/etc/rules/unbound_rules.xml @@ -0,0 +1,65 @@ + + + + + + unbound + Unbound grouping. + + + + 53760 + notice: + Notice grouping. + + + + 53760 + info: + Info grouping. + + + + 53761 + sendto failed: Can't assign requested address + Can't assign requested address. + + + + 53762 + A IN$ + DNS A request. + + + + 53762 + AAAA IN$ + DNS AAAA request. + + + + 53771,53772 + \.top\.|\.to\.|\.gq\.|\.cf\.|\.men\.|\.loan\.|\.ml\.|\.work\.|\.click\.|\.tk\.|\.country\.|\.pw\.|\.party\.|\.trade\.|\.review\.|\.club\.|\.bid\.|\.country\.|\.stream\.|\.download\.|\.xin\.|\.gdn\.|\.racing\.|\.jetzt\.|\.win\.|\.vip\.|\.ren\.|\.kim\.|\.mom\.|\.date\.|\.wang\.|\.accountants\.|\.science\.|\.work\.|\.ninja\.|\.xyz\.|\.faith\.|\.zip\.|\.racing\.|\.cricket\.|\.space\.|\.realtor\.|\.christmas\.|\.gdn\.|\.pro\. + Maybe critical URL requested + + + + 53760 + info: validation failure + DNSSEC validation failure + + + + 53774 + no keys have a DS with algorithm + Algorithm mismatch. + + + diff --git a/etc/rules/vmpop3d_rules.xml b/etc/rules/vmpop3d_rules.xml new file mode 100644 index 000000000..361e919cb --- /dev/null +++ b/etc/rules/vmpop3d_rules.xml @@ -0,0 +1,32 @@ + + + + + + vm-pop3d + Grouping for the vm-pop3d rules. + + + + 9800 + failed auth + authentication_failed, + Login failed accessing the pop3 server. + + + + 9801 + + POP3 brute force (multiple failed logins). + authentication_failures, + + + + + + diff --git a/etc/rules/vmware_rules.xml b/etc/rules/vmware_rules.xml new file mode 100644 index 000000000..e27e7be7a --- /dev/null +++ b/etc/rules/vmware_rules.xml @@ -0,0 +1,157 @@ + + + + + + + vmware + VMWare messages grouped. + + + + vmware-syslog + VMWare ESX syslog messages grouped. + + + + 19100 + ^crit|^fatal + VMware ESX critical message. + + + + 19100 + ^error + VMware ESX error message. + + + + 19100 + ^warn + VMware ESX warning message. + + + + 19100 + ^notice + VMware ESX notice message. + + + + 19100 + ^info + VMware ESX informational message. + + + + 19100 + ^verbose + VMware ESX verbose message. + + + + + + + 19106 + logged in$ + VMWare ESX authentication success. + authentication_success, + + + + 19106 + Failed login attempt for + VMWare ESX authentication failure. + authentication_failed, + + + + 19101 + vmware-hostd|vmware-authd + Accepted password for|login from + VMWare ESX user login. + authentication_success, + + + + 19101 + vmware-hostd|vmware-authd + Rejected password for + VMWare ESX user authentication failure. + authentication_failed, + + + + + + 19106 + -> VM_STATE_OFF + Virtual machine state changed to OFF. + service_availability, + + + + 19106 + -> VM_STATE_POWERING_ON + Virtual machine being turned ON. + + + + 19106 + -> VM_STATE_ON + Virtual machine state changed to ON. + alert_by_email + + + + 19106 + -> VM_STATE_RECONFIGURING + Virtual machine being reconfigured. + config_changed, + alert_by_email + + + + + + + 19104 + Multiple VMWare ESX warning messages. + service_availability, + + + + 19103 + Multiple VMWare ESX error messages. + service_availability, + + + + 19111 + Multiple VMWare ESX authentication failures. + authentication_failures, + + + + 19113 + Multiple VMWare ESX user authentication failures. + authentication_failures, + + + + + diff --git a/etc/rules/vpn_concentrator_rules.xml b/etc/rules/vpn_concentrator_rules.xml new file mode 100644 index 000000000..86d44c687 --- /dev/null +++ b/etc/rules/vpn_concentrator_rules.xml @@ -0,0 +1,60 @@ + + + + + + + + + cisco-vpn-concentrator + Grouping of Cisco VPN concentrator rules + + + + 14200 + ^IKE/52$ + VPN authentication successful. + authentication_success, + + + + 14200 + ^AUTH/5$|^AUTH/9$|^IKE/167$|^PPP/9$|^SSH/33$|^PSH/23$ + VPN authentication failed. + authentication_failed, + + + + 14200 + ^HTTP/47$|^SSH/16$ + alert_by_email + VPN Admin authentication successful. + authentication_success, + + + + 14202 + + Multiple VPN authentication failures. + authentication_failures, + + + + + diff --git a/etc/rules/vpopmail_rules.xml b/etc/rules/vpopmail_rules.xml new file mode 100644 index 000000000..8a33e455a --- /dev/null +++ b/etc/rules/vpopmail_rules.xml @@ -0,0 +1,68 @@ + + + + + + vpopmail + Grouping for the vpopmail rules. + + + + 9900 + password fail + authentication_failed, + Login failed for vpopmail. + + + + 9900 + vpopmail user not found + invalid_login, + Attempt to login to vpopmail with invalid username. + + + + 9900 + null password given + authentication_failed, + Attempt to login to vpopmail with empty password. + + + + 9900 + login success + authentication_success, + Vpopmail successful login. + + + + + 9901 + + Vpopmail brute force (multiple failed logins). + authentication_failures, + + + + 9902 + + Vpopmail brute force (email harvesting). + authentication_failures, + + + + 9903 + + VPOPMAIL brute force (empty password). + authentication_failures, + + + + + diff --git a/etc/rules/vsftpd_rules.xml b/etc/rules/vsftpd_rules.xml new file mode 100644 index 000000000..ef63b2bd5 --- /dev/null +++ b/etc/rules/vsftpd_rules.xml @@ -0,0 +1,62 @@ + + + + + + vsftpd + Grouping for the vsftpd rules. + + + + 11400 + CONNECT: Client + connection_attempt + FTP session opened. + + + + 11400 + OK LOGIN: + FTP Authentication success. + authentication_success, + + + + 11400 + FAIL LOGIN: + Login failed accessing the FTP server. + authentication_failed, + + + + 11400 + OK UPLOAD: + FTP server file upload. + + + + 11403 + + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11401 + + Multiple FTP connection attempts from + same source IP. + recon, + + + + + + diff --git a/etc/rules/web_appsec_rules.xml b/etc/rules/web_appsec_rules.xml new file mode 100644 index 000000000..ba77c64a5 --- /dev/null +++ b/etc/rules/web_appsec_rules.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + 31100 + POST /.*(?:Googlebot|MSNBot|BingBot) + /wp-comments-post\.php + WordPress Comment Spam (coming from a fake search engine UA). + + + + + 31100 + thumb\.php|timthumb\.php + "GET \S+thumb\.php\?src=\S+\.php + TimThumb vulnerability exploit attempt. + + + + + 31100 + login\.php + "POST /\S+\.php/login\.php\?cPath= + osCommerce login.php bypass attempt. + + + + + 31100 + login\.php + /admin/[A-Za-z0-9@_-]+\.php/login\.php + osCommerce file manager login.php bypass attempt. + + + + + 31100 + /cache/external + "GET /\S+/cache/external\S+\.php + TimThumb backdoor access attempt. + + + + + 31100 + cart\.php + "GET /\S+cart\.php\?\S+templatefile=\.\./ + Cart.php directory transversal attempt. + + + + + 31100 + DECLARE%20@S%20CHAR|%20AS%20CHAR + MSSQL Injection attempt (ur.php, urchin.js). + + + + + 31100 + "ZmEu"| "libwww-perl/|"the beast"|"Morfeus|"ZmEu|"Nikto|"w3af\.sourceforge\.net|MJ12bot/v| Jorgee"|"Proxy Gear Pro|"DataCha0s + Blacklisted user agent (known malicious user agent). + + + + + 31108 + wp-login\.php|/administrator + \] "POST \S+wp-login\.php| "POST /administrator + CMS (WordPress or Joomla) login attempt. + + + + + 31509 + + CMS (WordPress or Joomla) brute force attempt. + + + + + 31100 + " "Wget/ + Blacklisted user agent (wget). + + + + + 31100 + uploadify\.php + "GET /\S+/uploadify\.php\?src=http://\S+\.php + Uploadify vulnerability exploit attempt. + + + + + 31100 + delete\.php + "GET \S+/delete\.php\?board_skin_path=http://\S+\.php + BBS delete.php exploit attempt. + + + + + 31100 + shell\.php + "GET \S+/shell\.php\?cmd= + Simple shell.php command execution. + + + + + 31100 + phpMyAdmin/scripts/setup\.php + PHPMyAdmin scans (looking for setup.php). + + + + + 31100 + \.swp$|\.bak$|/\.htaccess|/server-status|/\.ssh|/\.history|/wallet\.dat + Suspicious URL access. + + + + + 31100 + \] "POST + no_log + POST request received. + + + + 31530 + /wp-admin/|/administrator/|/admin/ + Ignoring often post requests inside /wp-admin and /admin. + + + + 31530 + + High amount of POST requests in a small period of time (likely bot). + + + + + 31100 + %00 + "GET /\S+\.php\?\S+%00 + Anomaly URL query (attempting to pass null termination). + + + + diff --git a/etc/rules/web_rules.xml b/etc/rules/web_rules.xml new file mode 100644 index 000000000..54cdeb777 --- /dev/null +++ b/etc/rules/web_rules.xml @@ -0,0 +1,225 @@ + + + + + + web-log + Access log messages grouped. + + + + 31100 + ^2|^3 + is_simple_http_request + Ignored URLs (simple queries). + + + + 31100 + ^4 + Web server 400 error code. + + + + 31101 + \.jpg$|\.gif$|favicon\.ico$|\.png$|robots\.txt$|\.css$|\.js$|\.jpeg$ + is_simple_http_request + Ignored extensions on 400 error codes. + + + + 31100,31108 + =select%20|select\+|insert%20|%20from%20|%20where%20|union%20| + union\+|where\+|null,null|xp_cmdshell + SQL injection attempt. + attack,sql_injection, + + + + 31100 + + + %027|%00|%01|%7f|%2E%2E|%0A|%0D|\.\./\.\.|\.\.\\\.\.|echo;| + cmd\.exe|root\.exe|_mem_bin|msadc|/winnt/|/boot\.ini| + /x90/|default\.ida|/sumthin|nsiislog\.dll|chmod%|wget%|cd%20| + exec%20|\.\./\.\.//|%5C\.\./%5C|\./\./\./\./|2e%2e%5c%2e|\\x5C\\x5C + Common web attack. + attack, + + + + 31100 + %3Cscript|%3C%2Fscript|script>|script%3E|SRC=javascript|IMG%20| + %20ONLOAD=|INPUT%20|iframe%20 + XSS (Cross Site Scripting) attempt. + attack, + + + + 31103, 31104, 31105 + ^200 + A web attack returned code 200 (success). + attack, + + + + 31100 + \?-d|\?-s|\?-a|\?-b|\?-w + PHP CGI-bin vulnerability attempt. + attack, + + + + 31100 + \+as\+varchar + %2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\) + MSSQL Injection attempt (/ur.php, urchin.js) + attack, + + + + + + 31103, 31104, 31105 + ^/search\.php\?search=|^/index\.php\?searchword= + Ignored URLs for the web attacks + + + + 31100 + URL too long. Higher than allowed on most + browsers. Possible attack. + invalid_access, + + + + + + 31100 + ^50 + Web server 500 error code (server error). + + + + 31120 + ^501 + Web server 501 error code (Not Implemented). + + + + 31120 + ^500 + alert_by_email + Web server 500 error code (Internal Error). + system_error, + + + + 31120 + ^503 + alert_by_email + Web server 503 error code (Service unavailable). + + + + + + 31101 + is_valid_crawler + Ignoring google/msn/yahoo bots. + + + + + 31101 + ^499 + Ignored 499's on nginx. + + + + + 31101 + + Multiple web server 400 error codes + from same source ip. + web_scan,recon, + + + + 31103 + + Multiple SQL injection attempts from same + source ip. + attack,sql_injection, + + + + 31104 + + Multiple common web attacks from same source ip. + attack, + + + + 31105 + + Multiple XSS (Cross Site Scripting) attempts + from same source ip. + attack, + + + + 31121 + + Multiple web server 501 error code (Not Implemented). + web_scan,recon, + + + + 31122 + + Multiple web server 500 error code (Internal Error). + system_error, + + + + 31123 + + Multiple web server 503 error code (Service unavailable). + web_scan,recon, + + + + 31100 + =%27|select%2B|insert%2B|%2Bfrom%2B|%2Bwhere%2B|%2Bunion%2B + SQL injection attempt. + attack,sqlinjection, + + + + 31100 + %EF%BC%87|%EF%BC%87|%EF%BC%87|%2531|%u0053%u0045 + SQL injection attempt. + attack,sqlinjection, + + + diff --git a/etc/rules/wordpress_rules.xml b/etc/rules/wordpress_rules.xml new file mode 100644 index 000000000..686d6f299 --- /dev/null +++ b/etc/rules/wordpress_rules.xml @@ -0,0 +1,69 @@ + + + + + wordpress + Wordpress messages grouped. + + + + 9500 + User authentication failed + Wordpress authentication failed. + authentication_failed, + + + + 9500 + User logged in + Wordpress authentication succeeded. + authentication_success, + + + + 9500 + WPsyslog was successfully initiali + WPsyslog was successfully initialized. + + + + 9500 + Plugin deactivated + Wordpress plugin deactivated. + + + + 9500 + Warning: Comment flood attempt + Wordpress Comment Flood Attempt. + + + + 9500 + Warning: IDS: + Attack against Wordpress detected. + + + + 9501 + + Multiple wordpress authentication failures. + authentication_failures, + + + + + + diff --git a/etc/rules/zeus_rules.xml b/etc/rules/zeus_rules.xml new file mode 100644 index 000000000..768719408 --- /dev/null +++ b/etc/rules/zeus_rules.xml @@ -0,0 +1,75 @@ + + + + + + + + + zeus + Grouping of Zeus rules. + + + + 31200 + ^\[\S+ \S+\] INFO:|^\[\S+ \S+\] SSL: + Grouping of Zeus informational logs. + + + + 31200 + ^\[\S+ \S+\] WARN: + Zeus warning log. + + + + 31200 + ^\[\S+ \S+\] SERIOUS: + Zeus serious log. + + + + 31200 + ^\[\S+ \S+\] FATAL: + Zeus fatal log. + + + + 31202 + admin:Authentication failure + Admin authentication failed. + authentication_failed, + + + + 31202 + Unknown directive + Configuration warning (ignored). + + + + 31202 + Multiple Zeus warnings. + + + + + diff --git a/etc/templates/br/errors/0x1-location.txt b/etc/templates/br/errors/0x1-location.txt new file mode 100644 index 000000000..2cceba108 --- /dev/null +++ b/etc/templates/br/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Erro 0x1. + Este script só pode ser executado a partir do mesmo diretório. + Altere o diretório para onde está este script antes de rodá-lo. + Você deve rodá-lo como "./install.sh" + diff --git a/etc/templates/br/errors/0x2-beroot.txt b/etc/templates/br/errors/0x2-beroot.txt new file mode 100644 index 000000000..68c6d8cd3 --- /dev/null +++ b/etc/templates/br/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Erro 0x2. + Você necessita ser root para rodar este script. + diff --git a/etc/templates/br/errors/0x3-dependencies.txt b/etc/templates/br/errors/0x3-dependencies.txt new file mode 100644 index 000000000..a9352fb63 --- /dev/null +++ b/etc/templates/br/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Erro 0x3. + Você necessita de um compilador (como gcc ou cc) para continuar + a instalação. + diff --git a/etc/templates/br/errors/0x4-installtype.txt b/etc/templates/br/errors/0x4-installtype.txt new file mode 100644 index 000000000..f75b6dcfc --- /dev/null +++ b/etc/templates/br/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Erro 0x4. + Modalidade de instalação errada. Deve ser apenas [S]ervidor, [A]gente ou [L]ocal. + diff --git a/etc/templates/br/errors/0x5-build.txt b/etc/templates/br/errors/0x5-build.txt new file mode 100644 index 000000000..fe6615513 --- /dev/null +++ b/etc/templates/br/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Erro 0x5. + Erro na Compilação. Não foi possível finalizar a instalação. + diff --git a/etc/templates/br/language.txt b/etc/templates/br/language.txt new file mode 100644 index 000000000..b98a3fb04 --- /dev/null +++ b/etc/templates/br/language.txt @@ -0,0 +1 @@ + ** Para instalação em português, escolha [br]. diff --git a/etc/templates/br/messages.txt b/etc/templates/br/messages.txt new file mode 100644 index 000000000..8f5d782e2 --- /dev/null +++ b/etc/templates/br/messages.txt @@ -0,0 +1,111 @@ +# Configuração +yes="s" +no="n" +yesmatch="s" +nomatch="n" +server="servidor" +agent="cliente" +local="local" +help="ajuda" + + +# Global +moreinfo="Maiores informações em: " +starting="Iniciando o openarmor HIDS" +systemis="O Sistema é" +modifiedinit="O script de inicialização foi modificado para executar o openarmor HIDS durante o boot." +noboot="Sistema desconhecido. Nenhum script de incialização foi adicionado." + +# Parte 1 +installscript="Script de instalação" +system="Sistema" +user="Usuário" +host="Host" +hitanyorabort="Aperte ENTER para continuar ou Ctrl+C para abortar." +whattoinstall="Que tipo de instalação você deseja (servidor, cliente, local ou ajuda)?" +serverchose="Escolhida instalação servidor" +clientchose="Escolhida instalação cliente" +localchose="Escolhida instalação local" + +# Parte 2 +settingupenv="Configurando o ambiente de instalação" +wheretoinstall="Escolha onde instalar o openarmor HIDS" +installat="A instalação será feita no diretório" +deletedir="O diretório de instalação já existe. Deseja removê-lo?" + +# Parte 3 +configuring="Configurando o" +mailnotify="Deseja receber notificações por e-mail?" +nomail="Notificação por e-mail desabilitada" +whatsemail="Qual é o seu endereço de e-mail?" +yoursmtp="Seu servidor SMTP foi encontrado como" +usesmtp="Deseja usá-lo?" +usingsmtp="Usando servidor SMTP: " +whatsmtp="Qual é o ip/host de seu servidor SMTP?" + +# Parte 3.1/agente +serverip="Qual é o endereço de IP do servidor openarmor HIDS?" +serveraddr="Qual é o endereço de IP/hostname do servidor openarmor HIDS?" +addingip="Adicionando IP do servidor" +addingname="Adicionando hostname do servidor" + + +# Parte 3.2 +runsyscheck="Deseja habilitar o sistema de verificação de integridade?" +nosyscheck="Syscheck (Sistema de verificação de integridade) desabilitado" +yessyscheck="Syscheck (Sistema de verificação de integridade) habilitado" + +# Parte 3.3 +runrootcheck="Deseja habilitar o sistema de detecção de rootkis?" +norootcheck="Rootcheck (Sistema de detecção de rootkits) desabilitado" +yesrootcheck="Rootcheck (Sistema de detecção de rootkits) habilitado" + +# Parte 3.4/servidor/local +enable_ar="Deseja habilitar o sistema de respostas automáticas?" +noactive="Sistema de respostas automáticas desabilitado" +nohosts="host-deny desabilitado" +yeshosts="host-deny habilitado (local) para niveis >= 6" +firewallar="Deseja habilitar o firewall-drop?" +nofirewall="firewall-drop desabilitado." +yesfirewall="firewall-drop habilitado (local) para níveis >= 6" +defaultwhitelist="Lista de endereços que não serão bloqueados pela resposta automática:" +addwhite="Deseja adicionar mais algum endereço a essa lista?" +ipswhite="Endereços de IP (separados por espaço): " + + +# Parte 3.5/servidor/local +syslog="Deseja habilitar o syslog remoto (514 udp)?" +nosyslog="Syslog desabilitado" +yessyslog="Syslog habilitado" + +# Parte 3.4/3.5 +readlogs="Ajustando a configuração para analisar os seguintes logs:" + +# Parte 5 +installing="Instalando o sistema" +runningmake="Executando o Makefile" + +# Final +configurationdone="Configuração finalizada corretamente" +tostart="Para iniciar o openarmor HIDS" +tostop="Para parar o openarmor HIDS" +configat="A configuração pode ser vista ou modificada em" +addserveragent="Você precisa adicionar cada um dos clientes antes que estejam autorizados a acessar o servidor." +runma="Execute o 'manage_agents' para adicioná-los ou removê-los" +presskey="Pressione ENTER para continuar." + +# Update +wanttoupdate="openarmor ja esta instalado. Deseja atualiza-lo?" +unabletoupdate="Error na atualizacao. Sera necessario reinstala-lo." +updatecompleted="Atualizacao completada." +updatefailed="Erro na atualizacao." +updaterules="Voce deseja atualizar as regras?" +updatingrules="Atualizando as regras." +notupdatingrules="Nao atualizando as regras." + +# Pf support +pfenable="Deseja utilizar o firewall PF nas respostas automaticas?" +nopf="Respostas automaticas com o PF desabilitadas." +pftablename="Qual o nome da tabela no PF que deseja utilizar?" +pfmessage="Adicione as seguintes linhas na configuracao do seu firewall" + diff --git a/etc/templates/br/messages/0x101-initial.txt b/etc/templates/br/messages/0x101-initial.txt new file mode 100644 index 000000000..f17ffb5c9 --- /dev/null +++ b/etc/templates/br/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Você está iniciando o processo de instalação do openarmor HIDS. + Você precisará de um compilador C pré-instalado em seu sistema. + diff --git a/etc/templates/br/messages/0x102-installhelp.txt b/etc/templates/br/messages/0x102-installhelp.txt new file mode 100644 index 000000000..2b57f24cb --- /dev/null +++ b/etc/templates/br/messages/0x102-installhelp.txt @@ -0,0 +1,26 @@ + + - Você tem três opções de instalação: servidor, cliente ou local. + + - Se você escolher 'servidor', você poderá analizar todos os logs, + criar notificações de e-mail e respostas, e também receber + logs de máquinas remotas e de sistemas com 'clientes' rodando + (de onde o tráfego é enviado criptografado para o servidor). + + - Se você escolher 'cliente'(agente), você poderá ler arquivos + locais (do syslog, snort, apache, etc) e encaminhá-los + (criptografados) ao servidor para análise. + + - Se você escolher 'local', você poderá fazer tudo o que o + o servidor faz, exceto receber mensagens dos clientes. + + - Utilize 'servidor' se você estiver configurando um servidor de análise de logs. + + - Utilize 'cliente' se você tiver outra máquina rodando como servidor de logs + e quiser encaminhar os logs ao servidor para análise. + (ideal para webservers, servidores de banco de dados, etc) + + - Utilize 'local' se você apenas tem um sistema para monitorar. + + - Maiores informações: http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/br/messages/0x103-thanksforusing.txt b/etc/templates/br/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..1496ae29b --- /dev/null +++ b/etc/templates/br/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Obrigado por usar o openarmor HIDS. + Se você tiver alguma pergunta, sugestão ou encontrar algum + "bug", nos contate através do e-mail contact@theopenarmor.org ou + utilize nossa lista de e-mail: + ( http://www.theopenarmor.org/main/support/ ). + + Maiores informações podem ser encontradas em http://www.theopenarmor.org + + --- Pressione ENTER para continuar --- + diff --git a/etc/templates/br/messages/0x104-client.txt b/etc/templates/br/messages/0x104-client.txt new file mode 100644 index 000000000..60bee9d50 --- /dev/null +++ b/etc/templates/br/messages/0x104-client.txt @@ -0,0 +1,6 @@ + + - Para se comunicar com o servidor, você primeiro precisa + adicionar este cliente a ele. Quando você tiver terminado, + use a ferramenta 'manage_agents' para importar a chave de + autenticação do servidor. + diff --git a/etc/templates/br/messages/0x105-noboot.txt b/etc/templates/br/messages/0x105-noboot.txt new file mode 100644 index 000000000..2b1762267 --- /dev/null +++ b/etc/templates/br/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - Nenhuma ação foi tomada para que openarmor HIDS inicie + durrante o 'boot'. Adicione a seguinte linha em seu + script de inicialização: + diff --git a/etc/templates/br/messages/0x106-logs.txt b/etc/templates/br/messages/0x106-logs.txt new file mode 100644 index 000000000..8286422eb --- /dev/null +++ b/etc/templates/br/messages/0x106-logs.txt @@ -0,0 +1,7 @@ + - Se quiser monitorar qualquer outro arquivo, modifique + o openarmor.conf e adicione uma nova entrada para o arquivo. + Qualquer dúvida sobre a configuração, visite http://www.theopenarmor.org/hids/ . + + + --- Pressione ENTER para continuar --- + diff --git a/etc/templates/br/messages/0x107-ar.txt b/etc/templates/br/messages/0x107-ar.txt new file mode 100644 index 000000000..ed48007d0 --- /dev/null +++ b/etc/templates/br/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- Respostas automáticas permitem você executar um comando + específico baseado nos eventos recebidos. Você pode + bloquear um endereço de IP ou desabilitar o acesso de + um usuário específico, por exemplo. + Maiores informações: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/br/messages/0x108-ar-enabled.txt b/etc/templates/br/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..1938f72dd --- /dev/null +++ b/etc/templates/br/messages/0x108-ar-enabled.txt @@ -0,0 +1,11 @@ + - Sistema de respostas automáticas habilitado. + + - Por padrão, nós podemos habilitar o 'host-deny' e + o 'firewall-drop'. O primeiro adicionará um host + ao /etc/hosts.deny e o segundo bloqueará o host + no 'iptables' (se linux) ou no ipfilter (se Solaris, + FreeBSD ou NetBSD). + - Eles podem ser usados para parar 'SSHD brute force + scans', portscans e outras formas de ataque. + Você pode também realizar bloqueios baseados nos + alertas do snort, por exemplo. diff --git a/etc/templates/cn/errors/0x1-location.txt b/etc/templates/cn/errors/0x1-location.txt new file mode 100644 index 000000000..51d232578 --- /dev/null +++ b/etc/templates/cn/errors/0x1-location.txt @@ -0,0 +1,5 @@ + + 错误代码 0x1. + 该脚本只能在安装文件的同目录运行. + 请到脚本所在目录运行它. + 你必须以 ./install.sh 的形式运行他. diff --git a/etc/templates/cn/errors/0x2-beroot.txt b/etc/templates/cn/errors/0x2-beroot.txt new file mode 100644 index 000000000..5278e755b --- /dev/null +++ b/etc/templates/cn/errors/0x2-beroot.txt @@ -0,0 +1,3 @@ + + 错误代码 0x2. + 你必须以 root 的身份运行该脚本. diff --git a/etc/templates/cn/errors/0x3-dependencies.txt b/etc/templates/cn/errors/0x3-dependencies.txt new file mode 100644 index 000000000..3b713e0bd --- /dev/null +++ b/etc/templates/cn/errors/0x3-dependencies.txt @@ -0,0 +1,3 @@ + + 错误代码 0x3. + 在继续安装之前,您必须安装并配置好编译器(如 gcc 或 cc). diff --git a/etc/templates/cn/errors/0x4-installtype.txt b/etc/templates/cn/errors/0x4-installtype.txt new file mode 100644 index 000000000..51fc00403 --- /dev/null +++ b/etc/templates/cn/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + 错误代码 0x4. + 错误的安装类型. 安装类型只能是代理端安装(agent), 服务器端安装(server) + 或本地安装(local). diff --git a/etc/templates/cn/errors/0x5-build.txt b/etc/templates/cn/errors/0x5-build.txt new file mode 100644 index 000000000..d607a73dd --- /dev/null +++ b/etc/templates/cn/errors/0x5-build.txt @@ -0,0 +1,6 @@ + + Error 0x5. + Building error. Unable to finish the installation. + + 错误代码 0x5. + 编译错误. 不能完成安装. diff --git a/etc/templates/cn/language.txt b/etc/templates/cn/language.txt new file mode 100644 index 000000000..3c4fe180c --- /dev/null +++ b/etc/templates/cn/language.txt @@ -0,0 +1 @@ + ** 要使用中文进行安装, 请选择 [cn]. diff --git a/etc/templates/cn/messages.txt b/etc/templates/cn/messages.txt new file mode 100644 index 000000000..45a4210a3 --- /dev/null +++ b/etc/templates/cn/messages.txt @@ -0,0 +1,108 @@ +# Configuration +yes="y" +no="n" +yesmatch="y" +nomatch="n" +agent="agent" +local="local" +server="server" +help="help" + +# Global +moreinfo="详细信息请参考: " +starting="正在启动 openarmor HIDS " +systemis="系统类型是 " +modifiedinit="修改启动脚本使 openarmor HIDS 在系统启动时自动运行 " +noboot="未知系统,启动脚本未能添加." + +# Part 1 +installscript="安装脚本" +system="系统类型" +user="用户" +host="主机" +hitanyorabort="按 ENTER 继续或 Ctrl-C 退出." +whattoinstall="您希望哪一种安装 (server, agent, local or help)?" +serverchose="选择了 Server 类型的安装" +clientchose="选择了 Agent(client) 类型的安装" +localchose="选择了 Local 类型的安装" + +# Part 2 +settingupenv="正在初始化安装环境" +wheretoinstall="请选择 openarmor HIDS 的安装路径" +installat="openarmor HIDS 将安装在 " +deletedir="安装路径已存在. 要删除它吗?" + +# Part 3 +configuring="正在配置" +mailnotify="您希望收到e-mail告警吗?" +nomail="Email告警没有启用 " +whatsemail="请输入您的 e-mail 地址?" +yoursmtp="我们找到您的 SMTP 服务器为" +usesmtp="您希望使用它吗?" +usingsmtp="使用 SMTP 服务器: " +whatsmtp="请输入您的 SMTP 服务器IP或主机名 ?" + +# Part 3.1/agent +serverip="请输入 openarmor HIDS 服务器的IP地址" +serveraddr="请输入 openarmor HIDS 服务器的IP地址或主机名" +addingip="添加服务器IP " +addingname="添加服务器主机名 " + + +# Part 3.2 +runsyscheck="您希望运行系统完整性检测模块吗?" +nosyscheck="系统完整性检测模块将不被部署" +yessyscheck="系统完整性检测模块将被部署" + +# Part 3.3 +runrootcheck="您希望运行 rootkit检测吗?" +norootcheck="rootkit检测将不被部署" +yesrootcheck="rootkit检测将被部署" + +# Part 3.4/server/local +enable_ar="您希望开启联动(active response)功能吗?" +noactive="联动功能(Active response)被关闭" +nohosts="主机联动(host-deny) 被关闭" +yeshosts="主机联动(host-deny) 当事件级别 >= 6 时被启动" +firewallar="您希望开启防火墙联动(firewall-drop)功能吗?" +nofirewall="防火墙联动(firewall-drop)被关闭." +yesfirewall="防火墙联动(firewall-drop)当事件级别 >= 6 时被启动" +defaultwhitelist="联动功能默认的白名单是:" +addwhite="您希望添加更多的IP到白名单吗?" +ipswhite="请输入IP (用空格进行分隔): " + +# Part 3.5/server/local +syslog="您希望接收远程机器syslog吗 (port 514 udp)?" +nosyslog="远程机器syslog将不被接收" +yessyslog="远程机器syslog将被接收" + +# Part 3.4/3.5 +readlogs="设置配置文件以分析一下日志:" + +# Part 5 +installing="正在安装系统" +runningmake="正在运行Makefile" + +# Final +configurationdone="已正确完成系统配置" +tostart="要启动 openarmor HIDS" +tostop="要停止 openarmor HIDS" +configat="要查看或修改系统配置,请编辑 " +addserveragent="为使代理能够联接服务器端, 您需要将每个代理添加到服务器." +runma="允许'manage_agents'来添加活删除代理" +presskey="请按ENTER继续" + +# Update +wanttoupdate="您已经安装过 openarmor ,要升级它吗?" +unabletoupdate="不能对原版本进行升级. 必须进行全新安装." +updatecompleted="升级完成." +updatefailed="升级失败." +updaterules="您希望升级规则(rules文件)吗?" +updatingrules="升级规则(rules文件)." +notupdatingrules="不升级规则(rules文件)." + +# Pf support +pfenable="你希望在联动功能中使用 PF 防火墙吗?" +nopf="PF 防火墙联动被禁止." +pftablename="请输入希望使用的 PF 表?" +pfmessage="请将以下几行添加到 PF 规则的前面" diff --git a/etc/templates/cn/messages/0x101-initial.txt b/etc/templates/cn/messages/0x101-initial.txt new file mode 100644 index 000000000..392e58ca4 --- /dev/null +++ b/etc/templates/cn/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + 您将开始 openarmor HIDS 的安装. + 请确认在您的机器上已经正确安装了 C 编译器. + diff --git a/etc/templates/cn/messages/0x102-installhelp.txt b/etc/templates/cn/messages/0x102-installhelp.txt new file mode 100644 index 000000000..1663ded21 --- /dev/null +++ b/etc/templates/cn/messages/0x102-installhelp.txt @@ -0,0 +1,22 @@ + + - 您可以有三种安装选项:服务器端安装(server),代理端(agent)或本地安装(local). + + -如果选择'服务器端安装(server)', 您将可以分析所有日志, + 发送e-mail告警及联动,接收远端机器的syslog日志, + 接收代理端发回的日志(代理端发回的日志是经过加密的). + + -如果您选择'代理端安装(agent)', 您将可以读取本机文件(syslog, snort, + apache等)并将它们发送给服务器端(加密过后)进行分析. + + -如果选择'本地安装(local)',除了不能接收远程机器或代理端发回的信息外,你可以 + 作服务器(server)安装能做的任何事情. + + - 如果您希望安装一个日志分析服务器,请选择'server'. + + - 如果您已经有一台日志分析服务器并且希望将本机的日志传送给它,请选择'agent'. + (这是web服务器, 数据库服务器等的理想配置方法) + + - 如果您只有一台机器要监控,那么请选择'local'. + + - 要获得更多的信息, 请访问: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html diff --git a/etc/templates/cn/messages/0x103-thanksforusing.txt b/etc/templates/cn/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..c7bfb7bf6 --- /dev/null +++ b/etc/templates/cn/messages/0x103-thanksforusing.txt @@ -0,0 +1,10 @@ + + + 感谢使用 openarmor HIDS. + 如果您有任何疑问,建议或您找到任何bug, + 请通过 contact@theopenarmor.org 或邮件列表 openarmor-list@theopenarmor.org 联系我们. + ( http://www.theopenarmor.org/en/mailing_lists.html ). + + 您可以在 http://www.theopenarmor.org 获得更多信息 + + --- 请按 ENTER 结束安装 (下面可能有更多信息). --- diff --git a/etc/templates/cn/messages/0x104-client.txt b/etc/templates/cn/messages/0x104-client.txt new file mode 100644 index 000000000..eeb7badad --- /dev/null +++ b/etc/templates/cn/messages/0x104-client.txt @@ -0,0 +1,4 @@ + + - 您必须首先将该代理添加到服务器端以使他们能够相互通信. + 这样做了以后,您可以运行'manage_agents'工具导入 + 服务器端产生的认证密匙. diff --git a/etc/templates/cn/messages/0x105-noboot.txt b/etc/templates/cn/messages/0x105-noboot.txt new file mode 100644 index 000000000..291892e74 --- /dev/null +++ b/etc/templates/cn/messages/0x105-noboot.txt @@ -0,0 +1,3 @@ + + - 未能配置 openarmor HIDS 在系统启动时自动允许. + 请将以下行添加到启动脚本. diff --git a/etc/templates/cn/messages/0x106-logs.txt b/etc/templates/cn/messages/0x106-logs.txt new file mode 100644 index 000000000..0ec050d2b --- /dev/null +++ b/etc/templates/cn/messages/0x106-logs.txt @@ -0,0 +1,7 @@ + + -如果你希望监控其他文件, 只需要在配置文件openarmor.conf中 + 添加新的一项. + 任何关于配置的疑问您都可以在 http://www.theopenarmor.org 找到答案. + + + --- 按 ENTER 以继续 --- diff --git a/etc/templates/cn/messages/0x107-ar.txt b/etc/templates/cn/messages/0x107-ar.txt new file mode 100644 index 000000000..44be4104a --- /dev/null +++ b/etc/templates/cn/messages/0x107-ar.txt @@ -0,0 +1,6 @@ + + 3.4- 关联响应允许您在分析已接收事件的基础上执行一个 + 已定义的命令. + 例如,你可以阻止某个IP地址的访问或禁止某个用户的访问权限. + 更多的信息,您可以访问: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html diff --git a/etc/templates/cn/messages/0x108-ar-enabled.txt b/etc/templates/cn/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..6c1d8de92 --- /dev/null +++ b/etc/templates/cn/messages/0x108-ar-enabled.txt @@ -0,0 +1,10 @@ + + - 关联响应已开启 + + - 默认情况下, 我们开启了主机拒绝和防火墙拒绝两种响应. + 第一种情况将添加一个主机到 /etc/hosts.deny. + 第二种情况将在iptables(linux)或ipfilter(Solaris, + FreeBSD 或 NetBSD)中拒绝该主机的访问. + - 该功能可以用以阻止 SSHD 暴力攻击, 端口扫描和其他 + 一些形式的攻击. 同样你也可以将他们添加到其他地方, + 例如将他们添加为 snort 的事件. diff --git a/etc/templates/config/active-response.template b/etc/templates/config/active-response.template new file mode 100644 index 000000000..c3ba8b1be --- /dev/null +++ b/etc/templates/config/active-response.template @@ -0,0 +1,23 @@ + + + + host-deny + local + 6 + 600 + + + + + firewall-drop + local + 6 + 600 + diff --git a/etc/templates/config/apache-logs.template b/etc/templates/config/apache-logs.template new file mode 100644 index 000000000..0306cd2a6 --- /dev/null +++ b/etc/templates/config/apache-logs.template @@ -0,0 +1,12 @@ +/var/log/apache/error.log +/var/log/apache/error_log +/var/log/apache/access.log +/var/log/apache/access_log +/var/www/logs/access_log +/var/www/logs/error_log +/var/log/httpd/error_log +/var/log/httpd/access_log +/var/log/nginx/access.log +/var/log/nginx/error.log +/var/log/apache2/error.log +/var/log/apache2/access.log diff --git a/etc/templates/config/ar-disable-account.template b/etc/templates/config/ar-disable-account.template new file mode 100644 index 000000000..a438bc101 --- /dev/null +++ b/etc/templates/config/ar-disable-account.template @@ -0,0 +1,13 @@ + + disable-account + disable-account.sh + user + yes + + + + restart-openarmor + restart-openarmor.sh + + + diff --git a/etc/templates/config/ar-firewall-drop.template b/etc/templates/config/ar-firewall-drop.template new file mode 100644 index 000000000..b11d11f86 --- /dev/null +++ b/etc/templates/config/ar-firewall-drop.template @@ -0,0 +1,6 @@ + + firewall-drop + firewall-drop.sh + srcip + yes + diff --git a/etc/templates/config/ar-host-deny.template b/etc/templates/config/ar-host-deny.template new file mode 100644 index 000000000..7b1b7bcaa --- /dev/null +++ b/etc/templates/config/ar-host-deny.template @@ -0,0 +1,6 @@ + + host-deny + host-deny.sh + srcip + yes + diff --git a/etc/templates/config/ar-routenull.template b/etc/templates/config/ar-routenull.template new file mode 100644 index 000000000..dbd9775eb --- /dev/null +++ b/etc/templates/config/ar-routenull.template @@ -0,0 +1,6 @@ + + route-null + route-null.sh + srcip + yes + diff --git a/etc/templates/config/pgsql-logs.template b/etc/templates/config/pgsql-logs.template new file mode 100644 index 000000000..4d4fafad2 --- /dev/null +++ b/etc/templates/config/pgsql-logs.template @@ -0,0 +1,2 @@ +/var/log/postgresql/postgresql-8.1-main.log +/var/log/postgresql/postgresql.log diff --git a/etc/templates/config/rootcheck.template b/etc/templates/config/rootcheck.template new file mode 100644 index 000000000..2b831bbce --- /dev/null +++ b/etc/templates/config/rootcheck.template @@ -0,0 +1,18 @@ + + + 36000 + + + /var/openarmor/etc/shared/rootkit_files.txt + /var/openarmor/etc/shared/rootkit_trojans.txt + /var/openarmor/etc/shared/system_audit_rcl.txt + /var/openarmor/etc/shared/cis_rhel5_linux_rcl.txt + /var/openarmor/etc/shared/cis_rhel6_linux_rcl.txt + /var/openarmor/etc/shared/cis_rhel7_linux_rcl.txt + /var/openarmor/etc/shared/cis_debian_linux_rcl.txt + /var/openarmor/etc/shared/cis_rhel_linux_rcl.txt + /var/openarmor/etc/shared/cis_sles11_linux_rcl.txt + /var/openarmor/etc/shared/cis_sles12_linux_rcl.txt + /var/openarmor/etc/shared/system_audit_ssh.txt + + diff --git a/etc/templates/config/rules.template b/etc/templates/config/rules.template new file mode 100644 index 000000000..0dfc56dc0 --- /dev/null +++ b/etc/templates/config/rules.template @@ -0,0 +1,71 @@ + + rules_config.xml + pam_rules.xml + sshd_rules.xml + telnetd_rules.xml + syslog_rules.xml + arpwatch_rules.xml + symantec-av_rules.xml + symantec-ws_rules.xml + pix_rules.xml + named_rules.xml + smbd_rules.xml + vsftpd_rules.xml + pure-ftpd_rules.xml + proftpd_rules.xml + ms_ftpd_rules.xml + ftpd_rules.xml + hordeimp_rules.xml + roundcube_rules.xml + wordpress_rules.xml + cimserver_rules.xml + vpopmail_rules.xml + vmpop3d_rules.xml + courier_rules.xml + web_rules.xml + web_appsec_rules.xml + apache_rules.xml + nginx_rules.xml + php_rules.xml + mysql_rules.xml + postgresql_rules.xml + ids_rules.xml + squid_rules.xml + firewall_rules.xml + apparmor_rules.xml + cisco-ios_rules.xml + netscreenfw_rules.xml + sonicwall_rules.xml + postfix_rules.xml + sendmail_rules.xml + imapd_rules.xml + mailscanner_rules.xml + dovecot_rules.xml + ms-exchange_rules.xml + racoon_rules.xml + vpn_concentrator_rules.xml + spamd_rules.xml + msauth_rules.xml + mcafee_av_rules.xml + trend-osce_rules.xml + ms-se_rules.xml + + zeus_rules.xml + solaris_bsm_rules.xml + vmware_rules.xml + ms_dhcp_rules.xml + asterisk_rules.xml + openarmor_rules.xml + attack_rules.xml + openbsd_rules.xml + clam_av_rules.xml + dropbear_rules.xml + sysmon_rules.xml + opensmtpd_rules.xml + exim_rules.xml + openbsd-dhcpd_rules.xml + dnsmasq_rules.xml + nsd_rules.xml + unbound_rules.xml + local_rules.xml + diff --git a/etc/templates/config/snort-logs.template b/etc/templates/config/snort-logs.template new file mode 100644 index 000000000..30b1bc63e --- /dev/null +++ b/etc/templates/config/snort-logs.template @@ -0,0 +1 @@ +/var/log/snort/alert diff --git a/etc/templates/config/syscheck.template b/etc/templates/config/syscheck.template new file mode 100644 index 000000000..d4cd4f3c3 --- /dev/null +++ b/etc/templates/config/syscheck.template @@ -0,0 +1,37 @@ + + + 79200 + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/mnttab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/adjtime + /etc/httpd/logs + /etc/utmpx + /etc/wtmpx + /etc/cups/certs + /etc/dumpdates + /etc/svc/volatile + + + C:\WINDOWS/System32/LogFiles + C:\WINDOWS/Debug + C:\WINDOWS/WindowsUpdate.log + C:\WINDOWS/iis6.log + C:\WINDOWS/system32/wbem/Logs + C:\WINDOWS/system32/wbem/Repository + C:\WINDOWS/Prefetch + C:\WINDOWS/PCHEALTH/HELPCTR/DataColl + C:\WINDOWS/SoftwareDistribution + C:\WINDOWS/Temp + C:\WINDOWS/system32/config + C:\WINDOWS/system32/spool + C:\WINDOWS/system32/CatRoot + diff --git a/etc/templates/config/syslog-logs.template b/etc/templates/config/syslog-logs.template new file mode 100644 index 000000000..8c43c4efd --- /dev/null +++ b/etc/templates/config/syslog-logs.template @@ -0,0 +1,31 @@ +/var/log/messages +/var/log/authlog +/var/log/auth.log +/var/log/secure +/var/log/secure.log +/var/log/system.log +/var/log/syslog +/var/log/ipfilter.log +/var/adm/ipsec.log +/var/adm/syslog +/var/adm/auth.log +/var/adm/syslog.log +/var/adm/messages +/var/adm/syslog/syslog.log +/var/log/userlog +/var/log/security +/var/log/xferlog +/var/log/proftpd.log +/var/log/vsftpd.log +/var/log/radius.log +/var/log/radius/radius.log +/var/log/mail.info +/var/log/mail.notice +/var/log/maillog +/usr/local/squid/var/logs/access.log +/var/log/squid/access.log +/var/log/horde.log +/var/log/asl.log +/var/log/dpkg.log +/var/log/vmware/hostd.log +/var/log/proftpd/proftpd.log diff --git a/etc/templates/de/errors/0x1-location.txt b/etc/templates/de/errors/0x1-location.txt new file mode 100644 index 000000000..9dbcd20f3 --- /dev/null +++ b/etc/templates/de/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Fehler 0x1. + Dieses Script kann nur aus dem gleichen Verzeichniss ausgefhrt + werden. Wechseln Sie in das Verzeichniss in dem das Script liegt + und fhren Sie ./install.sh als root aus." + diff --git a/etc/templates/de/errors/0x2-beroot.txt b/etc/templates/de/errors/0x2-beroot.txt new file mode 100644 index 000000000..cbc99798e --- /dev/null +++ b/etc/templates/de/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Fehler 0x2. + Dieses Script kann nur mit root Rechten ausgefhrt werden. + diff --git a/etc/templates/de/errors/0x3-dependencies.txt b/etc/templates/de/errors/0x3-dependencies.txt new file mode 100644 index 000000000..c05e1d63c --- /dev/null +++ b/etc/templates/de/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Fehler 0x3. + Sie bentigen einen Compiler (zB gcc or cc) um mit der Installation + fortzufahren. + diff --git a/etc/templates/de/errors/0x4-installtype.txt b/etc/templates/de/errors/0x4-installtype.txt new file mode 100644 index 000000000..ad3573450 --- /dev/null +++ b/etc/templates/de/errors/0x4-installtype.txt @@ -0,0 +1,5 @@ + + Fehler 0x4. + Falscher Installationstyp. Bitte whlen Sie zwischen agent, server + und local. + diff --git a/etc/templates/de/errors/0x5-build.txt b/etc/templates/de/errors/0x5-build.txt new file mode 100644 index 000000000..ce045420f --- /dev/null +++ b/etc/templates/de/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Fehler 0x5. + Fehler beim compilieren. Das Paket kann nicht installiert werden. + diff --git a/etc/templates/de/language.txt b/etc/templates/de/language.txt new file mode 100644 index 000000000..4db52d722 --- /dev/null +++ b/etc/templates/de/language.txt @@ -0,0 +1 @@ + ** Fur eine deutsche Installation wohlen Sie [de]. diff --git a/etc/templates/de/messages.txt b/etc/templates/de/messages.txt new file mode 100644 index 000000000..6d1028724 --- /dev/null +++ b/etc/templates/de/messages.txt @@ -0,0 +1,112 @@ +# Configuration +yes="j" +no="n" +yesmatch="j" +nomatch="n" +agent="agent" +local="lokal" +server="server" +help="hilfe" + + +# Global +moreinfo="Weitere Informationen unter: " +starting="Starte openarmor HIDS" +systemis="Erkanntes System " +modifiedinit="Init script wurde ver�ndert uopenarmorEC HIDS beim boot zu starten." +noboot="Unbekanntes system. Es wurde kein Init-Script kopiert." + +# Part 1 +installscript="Installations Script" +system="System" +user="User" +host="Host" +hitanyorabort="Drücken Sie eine Taste zum fortfahren oder Ctrl-C zum abbrechen" +whattoinstall="Welche Art der Installation möchten Sie starten (server,agent,lokal oder hilfe)?" +serverchose="Server installation ausgewählt" +clientchose="Agent(client) installation ausgewählt" +localchose="Lokale installation ausgewählt" + +# Part 2 +settingupenv="Die Installation wird vorbereitet" +wheretoinstall="Bitte w�hlen Sie wopenarmorEC HIDS installiert werden soll" +installat="Die Installation wird kopiert nach " +deletedir="Das Installationsverzeichniss existiert bereits. Soll es gel�scht werden? " + +# Part 3 +configuring="Konfiguration " +mailnotify="M�chten Sie Benachrichtigungen per E-Mail? " +nomail="E-Mail Benachrichtigung wird �bersprungen " +whatsemail="Wie lautet die E-Mail Adresse? " +yoursmtp="Es wurde dieser SMTP Server gefunden" +usesmtp="Soll er benutzt werden?" +usingsmtp="Benutze SMTP Server: " +whatsmtp="Wie lautet die Adresse des SMTP Servers? (IP/Host) " + +# Part 3.1/agent +serverip="Wie lautet die IP Adresse des openarmor HIDS Servers?" +serveraddr="Wie lautet die IP Adresse/Host des openarmor HIDS Servers?" +addingip="Server IP hinzugef�gt" +addingname="Server Host hinzugef�gt" + + +# Part 3.2 +runsyscheck="M�chten Sie den syscheck (integrity check daemon) benutzen?" +nosyscheck="Syscheck (integrity check daemon) wird nicht benutzt" +yessyscheck="Syscheck (integrity check daemon) wird gestartet" + +# Part 3.3 +runrootcheck="M�chten Sie die rootkit detection engine benutzen?" +norootcheck="Rootcheck (rootkit detection) wird nicht benutzt" +yesrootcheck="Rootcheck (rootkit detection) wird gestartet" + +# Part 3.4/server/local +enable_ar="M�chten Sie active response benutzen?" +noactive="Active response wird nicht benutzt" +nohosts="host-deny ausgeschaltet" +yeshosts="host-deny (local) f�r level >= 6 eingeschaltet " +firewallar="M�chten Sie firewall-drop benutzen?" +nofirewall="firewall-drop ausgeschaltet" +yesfirewall="firewall-drop (local) f�r level >= 6 eingeschaltet" +defaultwhitelist="Standard Ausnahmeliste (White-list) für active response:" +addwhite="Möchten Sie weitere IPs zur White-list hinzufügen?" +ipswhite="IPs (Durch Leerzeichen getrennt): " + + +# Part 3.5/server/local +syslog="M�chten Sie Nachrichten von einem remote syslog (514 udp) empfangen?" +nosyslog="Remote syslog empfang ausgeschaltet" +yessyslog="Remote syslog empfang eingeschaltet" + +# Part 3.4/3.5 +readlogs="Die folgenden Log-Files werden analysiert:" + +# Part 5 +installing="Installiere das System" +runningmake="make wird ausgef�hrt" + +# Final +configurationdone="Konfguration erfolgreich durchgef�hrt " +tostart="Um openarmor HIDS zu starten" +tostop="Um openarmor HIDS zu stoppen" +configat="Die Konfiguration kann angesehen oder ver�ndert werden unter: " +addserveragent="Agenten m�ssen hinzugef�gt werden bevor sie zugreifen k�nnen. " +runma="Run the 'Benutzen Sie manage_agents um Agenten hinzuzuf�gen oder zu entfernen" +presskey="Dr�cken Sie eine Taste" + +# Update +wanttoupdate="openarmor ist bereits installiert. M�chten Sie es updaten?" +unabletoupdate="Update nicht m�glich. Es mu� eine Neuinstallation durchgef�hrt werden." +updatecompleted="Update durchgef�hrt." +updatefailed="Update fehlgeschlagen." +updaterules="M�chten Sie die Regeln updaten?" +updatingrules="Regeln werden upgedated." +notupdatingrules="Regeln werden nicht ver�ndert." + +# Pf support +pfenable="Moechten Sie die PF Firewall f�r active response benutzen?" +nopf="active response fuer PF Firewall ausgeschaltet." +pftablename="Name der PF Tabelle die benutzt werden soll?" +pfmessage="Fuegen Sie die folgende Zeile am Anfang Ihrer Regeln ein " + + diff --git a/etc/templates/de/messages/0x101-initial.txt b/etc/templates/de/messages/0x101-initial.txt new file mode 100644 index 000000000..726b0c3c0 --- /dev/null +++ b/etc/templates/de/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Um openarmor HIDS zu installieren mu� auf Ihrem System ein C-Compiler + installiert sein. + diff --git a/etc/templates/de/messages/0x102-installhelp.txt b/etc/templates/de/messages/0x102-installhelp.txt new file mode 100644 index 000000000..ef388086c --- /dev/null +++ b/etc/templates/de/messages/0x102-installhelp.txt @@ -0,0 +1,28 @@ + + - Es gibt drei Arten der Installation: agent, local oder server. + + - Wenn Sie Server w�hlen, k�nnen Logfiles analysiert werden, + es werden Benachrichtigungen per E-Mail verschickt und es + k�nnen Logs von Agenten auf entfernten Rechnern empfangen + werden. + + - Wenn Sie Agent ausw�hlen, k�nnen Logfiles ausgelesen werden + (zb syslog, snort, apache) und verschl�sselt an einen + Server zur analyse geschickt werden. + + - Wenn Sie local ausw�hlen, k�nnen alle Funktionen eines + Servers, bis auf den Empfang von Agentennachrichten ausge- + f�hrt werden. + + - W�hlen Sie 'Server' wenn Sie Nachrichten von fremden Agenten + empfangen und verarbeiten m�chten. + + - W�hlen Sie 'Agent' wenn Sie einen anderen Rechner haben, der + als Server dient und an den die Logs zur Analyse geschickt + werden (sinnvoll zb f�r Webserver, Datenbankserver usw). + + - W�hlen Sie 'Local' wenn nur ein System analysiert werden soll. + + - weitere Informationen unter: http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/de/messages/0x103-thanksforusing.txt b/etc/templates/de/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..a57ebff95 --- /dev/null +++ b/etc/templates/de/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Danke das Sie openarmor HIDS benutzen. + Bei Fragen, Anregungen oder wenn Sie einen Fehler gefunden + haben, k�nnen Sie die Entwickler per E-Mail contacopenarmorec.net + oder �ber die Mailingliste unteopenarmorec-lisopenarmorec.net erreichen + ( http://www.theopenarmor.org/en/mailing_lists.html ). + + Weitere Informtionen finden Sie unter http://www.theopenarmor.org/hids/ + + --- Dr�cken Sie eine Taste um fortzufahren --- + diff --git a/etc/templates/de/messages/0x104-client.txt b/etc/templates/de/messages/0x104-client.txt new file mode 100644 index 000000000..afb44385a --- /dev/null +++ b/etc/templates/de/messages/0x104-client.txt @@ -0,0 +1,5 @@ + + - Um mit dem Server zu kommunizieren mssen Sie erst den + Agent auf dem Server hinzufgen. Danach kann der Schlssel + mit dem Tool 'manage_agents' importiert werden. + diff --git a/etc/templates/de/messages/0x105-noboot.txt b/etc/templates/de/messages/0x105-noboot.txt new file mode 100644 index 000000000..6d51b73c3 --- /dev/null +++ b/etc/templates/de/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - Es wurde kein Startup Script erstellt. Um openarmor HIDS beim + booten automatisch zu starten, sollten Sie die folgende Zeile + in ein init Script aufnehmen: + diff --git a/etc/templates/de/messages/0x106-logs.txt b/etc/templates/de/messages/0x106-logs.txt new file mode 100644 index 000000000..0769cd2bc --- /dev/null +++ b/etc/templates/de/messages/0x106-logs.txt @@ -0,0 +1,8 @@ + - Wenn Sie weitere Files �berwachen m�chten, f�gen Sie + einen weiteren 'localfile' Eintrag in der Datei + openarmor.conf hinzu. Alle Konfigurationsoptionen werden + unter http://www.theopenarmor.org/hids/ beschrieben. + + + --- Dr�cken Sie eine Taste um fortzufahren --- + diff --git a/etc/templates/de/messages/0x107-ar.txt b/etc/templates/de/messages/0x107-ar.txt new file mode 100644 index 000000000..ab199c164 --- /dev/null +++ b/etc/templates/de/messages/0x107-ar.txt @@ -0,0 +1,7 @@ + + 3.4- Mit 'Active Response' k�nnen Befehle abh�ngig von + Events ausf�hren. Dadurch k�nnen zB IP-Adressen + geblockt werden oder der Zugriff f�r bestimmte + Benutzer abgeschaltet werden. + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/de/messages/0x108-ar-enabled.txt b/etc/templates/de/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..50cf39620 --- /dev/null +++ b/etc/templates/de/messages/0x108-ar-enabled.txt @@ -0,0 +1,11 @@ + - Active response eingeschaltet." + + - Standardmssig kann 'host-deny' und 'firewall-drop' + aktiviert werden. 'host-deny' fgt eine IP in die + Datei /etc/hosts.deny ein. 'firewall-response' fgt + eine IP per iptables (Linux) oder ipfilter (Solaris, + FreeBSD usw) in die Firewall Regeln ein. + + - Beide knnen benutzt werden um SSH Brute-Force scans, + Portscans oder andere Attacken zu verhindern. Es kann + auch durch einen Snort-Event geblockt werden. diff --git a/etc/templates/el/errors/0x1-location.txt b/etc/templates/el/errors/0x1-location.txt new file mode 100644 index 000000000..b20887e57 --- /dev/null +++ b/etc/templates/el/errors/0x1-location.txt @@ -0,0 +1,7 @@ + + Σφάλμα 0x1. + Το αρχείο αυτό μπορεί να εκτελεστεί μόνο από τον κατάλογο + στον οποίο βρίσκεται. + Μεταβείτε στον κατάλογο που βρίσκεται αυτό το αρχείο και + τρέξτε την εντολή ./install.sh + diff --git a/etc/templates/el/errors/0x2-beroot.txt b/etc/templates/el/errors/0x2-beroot.txt new file mode 100644 index 000000000..997c6163d --- /dev/null +++ b/etc/templates/el/errors/0x2-beroot.txt @@ -0,0 +1,5 @@ + + Σφάλμα 0x2. + Πρέπει να είστε συνδεδεμένος ως root + για να εγκαταστήσετε αυτό το πρόγραμμα. + diff --git a/etc/templates/el/errors/0x3-dependencies.txt b/etc/templates/el/errors/0x3-dependencies.txt new file mode 100644 index 000000000..054079e9a --- /dev/null +++ b/etc/templates/el/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Σφάλμα 0x3. + Χρειάζεστε έναν μεταγλωττιστή (όπως gcc ή cc) για να + συνεχίσετε με την εγκατάσταση. + diff --git a/etc/templates/el/errors/0x4-installtype.txt b/etc/templates/el/errors/0x4-installtype.txt new file mode 100644 index 000000000..0a02b8fd4 --- /dev/null +++ b/etc/templates/el/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Σφάλμα 0x4. + Λάθος τύπος εγκατάστασης. Μπορεί μόνο να είναι agent, server ή local. + diff --git a/etc/templates/el/errors/0x5-build.txt b/etc/templates/el/errors/0x5-build.txt new file mode 100644 index 000000000..030ae347e --- /dev/null +++ b/etc/templates/el/errors/0x5-build.txt @@ -0,0 +1,5 @@ + + Σφάλμα 0x5. + Λάθος στην δημιουργία του εκτελέσιμου προγράμματος. + Δεν είναι δυνατό να ολοκληρωθεί η εγκατάσταση. + diff --git a/etc/templates/el/language.txt b/etc/templates/el/language.txt new file mode 100644 index 000000000..c4f27ef0a --- /dev/null +++ b/etc/templates/el/language.txt @@ -0,0 +1 @@ + ** Για εγκατάσταση στα Ελληνικά, επιλέξτε [el]. diff --git a/etc/templates/el/messages.txt b/etc/templates/el/messages.txt new file mode 100644 index 000000000..ca69c6fe2 --- /dev/null +++ b/etc/templates/el/messages.txt @@ -0,0 +1,108 @@ +# Configuration +yes="y" +no="n" +yesmatch="y" +nomatch="n" +agent="agent" +local="local" +server="server" +help="help" + +# Global +moreinfo="Περισσότερες πληροφορίες στο: " +starting="Εκκινώντας το openarmor HIDS" +systemis="Το σύστημα είναι" +modifiedinit="To init script τροποποιήθηκε προκειμένου να ξεκινάει το openarmor HIDS κατά την εκκίνηση του συστήματος." +noboot="Άγνωστο σύστημα. Το init script δεν προστέθηκε." + +# Part 1 +installscript="πρόγραμμα εγκατάστασης" +system="Σύστημα" +user="Χρήστης" +host="Υπολογιστής" +hitanyorabort="Πατήστε ENTER για να συνεχίσετε ή Ctrl-C για ακύρωση." +whattoinstall="Τι τύπου εγκατάσταση επιθυμείτε (server, agent, local ή help);" +serverchose="Επιλέχθηκε η εγκατάσταση διακομιστή (server)" +clientchose="Επιλέχθηκε η εγκατάσταση πελάτη (agent)" +localchose="Επιλέχθηκε η τοπική (local) εγκατάσταση" + +# Part 2 +settingupenv="Ρυθμίζεται το περιβάλλον εγκατάστασης" +wheretoinstall="Επιλέξτε την τοποθεσία εγκατάστασης του openarmor HIDS" +installat="Η εγκατάσταση θα γίνει στο " +deletedir="Ο κατάλογος εγκατάστασης υπάρχει ήδη. Θέλετε να διαγραφεί;" + +# Part 3 +configuring="Ρυθμίζοντας το" +mailnotify="Θέλετε να ειδοποιήστε μέσω e-mail;" +nomail="Οι ειδοποιήσεις με e-mail απενεργοποιήθηκαν" +whatsemail="Ποιά είναι η διεύθυνση του ηλεκτρονικού σας ταχυδρομείου;" +yoursmtp="Βρήκαμε ότι ο διακομιστής της εξερχόμενης αλληλογραφίας σας είναι ο " +usesmtp="Θέλετε να τον χρησιμοποιήσετε;" +usingsmtp="Διακομιστής εξερχόμενης αλληλογραφίας: " +whatsmtp="Ποιά είναι η διεύθυνση του διακομιστή της εξερχόμενης αλληλογραφίας σας ip/host?" + +# Part 3.1/agent +serverip="Ποιά είναι η διεύθυνση IP του διακομιστή openarmor HIDS;" +serveraddr="Ποιά είναι η διεύθυνση IP/Host του διακομιστή openarmor HIDS;" +addingip="Προστέθηκε η διεύθυνση διακομιστή" +addingname="Προστέθηκε η διεύθυνση διακομιστή" + + +# Part 3.2 +runsyscheck="Θέλετε να εκτελέσετε τον δαίμονα ελέγχου ακεραιότητας (integrity check daemon);" +nosyscheck="Ο δαίμονας ελέγχου ακεραιότητας (integrity check daemon) δεν εκτελέστηκε" +yessyscheck="Ο δαίμονας ελέγχου ακεραιότητας (integrity check daemon) ξεκίνησε" + +# Part 3.3 +runrootcheck="Θέλετε να εκτελέσετε την μηχανή ανίχνευσης rootkit;" +norootcheck="Η μηχανή ανίχνευσης rootkit δεν εκτελέστηκε" +yesrootcheck="Η μηχανή ανίχνευσης rootkit ξεκίνησε" + +# Part 3.4/server/local +enable_ar="Θέλετε να ενεργοποιήσετε την ενεργή αντίδραση (active response);" +noactive="Η ενεργή αντίδραση (active response) απενεργοποιήθηκε" +nohosts="Το host-deny απενεργοποιήθηκε" +yeshosts="Το host-deny ενεργοποιήθηκε (local) για επίπεδα >= 6" +firewallar="Θέλετε να ενεργοποιήσετε την αντίδραση firewall-drop;" +nofirewall="Η αντίδραση firewall-drop απενεργοποιήθηκε." +yesfirewall="Η αντίδραση firewall-drop ενεργοποιήθηκε (local) για επίπεδα >= 6" +defaultwhitelist="Προεπιλεγμένη white list για την ενεργή αντίδραση (active response):" +addwhite="Θέλετε να προσθέσετε περισσότερες IPs στην white list;" +ipswhite="Διευθύνσεις IPs (χωρισμένες με κενό): " + +# Part 3.5/server/local +syslog="Θέλετε να ενεργοποιήσετε την καταγραφή συμβάντων σε απομακρυσμένο syslog διακομιστή (port 514 udp);" +nosyslog="Η απομακρυσμένη καταγραφή συμβάντων απενεργοποιήθηκε" +yessyslog="Η απομακρυσμένη καταγραφή συμβάντων ενεργοποιήθηκε" + +# Part 3.4/3.5 +readlogs="Ρυθμίζοντας το αρχείο ρυθμίσεων για να αναλυθούν τα παρακάτω αρχεία καταγραφής (logs):" + +# Part 5 +installing="Το σύστημα εγκαθίσταται" +runningmake="Το Makefile εκτελείται" + +# Final +configurationdone="Οι ρυθμίσεις πραγματοποιήθηκαν με επιτυχία" +tostart="Για να ξεκινήσετε το openarmor HIDS" +tostop="Για να σταματήσετε το openarmor HIDS" +configat="Το αρχείο ρυθμίσεων μπορεί να αναγνωστεί ή να τροποποιηθεί στην τοποθεσία" +addserveragent="Προκειμένου να διασυνδέσετε τον agent με τον server, πρέπει να προσθέσετε κάθε agent στο server." +runma="Εκτελέστε το αρχείο 'manage_agents' για να τους προσθέσετε ή να τους αφαιρέσετε" +presskey="Πατήστε ENTER για να συνεχίσετε" + +# Update +wanttoupdate="Βρέθηκε εγκατεστημένο openarmor. Θέλετε να το ενημερώσετε;" +unabletoupdate="Η ενημέρωση απέτυχε. Απαιτείται νέα πλήρης εγκατάσταση." +updatecompleted="Η ενημέρωση ολοκληρώθηκε." +updatefailed="Η ενημέρωσε απέτυχε." +updaterules="Θέλετε να ενημερώσετε τους κανόνες (rules);" +updatingrules="Οι κανόνες (rules) ενημερώνονται." +notupdatingrules="Οι κανόνες (rules) δεν ενημερώνονται." + +# Pf support +pfenable="Θέλετε να χρησιμοποιήσετε το PF firewall για ενεργή αντίδραση (active response);" +nopf="Η αντίδραση (response) με το PF απενεργοποιήθηκε." +pftablename="Πιό είναι το όνομα του πίνακα (table) PF που θέλετε να χρησιμοποιήσετε;" +pfmessage="Προσθέστε τις παρακάτω γραμμές στην αρχή των PF κανόνων σας" diff --git a/etc/templates/el/messages/0x101-initial.txt b/etc/templates/el/messages/0x101-initial.txt new file mode 100644 index 000000000..212cd945a --- /dev/null +++ b/etc/templates/el/messages/0x101-initial.txt @@ -0,0 +1,5 @@ + + Πρόκειται να ξεκινήσετε τη διαδικασία εγκατάστασης του openarmor HIDS. + Για την εγκατάσταση θα πρέπει να έχετε προ-εγκατεστημένο + ένα μεταγλωττιστή της γλώσσας C στον υπολογιστή σας. + diff --git a/etc/templates/el/messages/0x102-installhelp.txt b/etc/templates/el/messages/0x102-installhelp.txt new file mode 100644 index 000000000..9501aafc5 --- /dev/null +++ b/etc/templates/el/messages/0x102-installhelp.txt @@ -0,0 +1,30 @@ + - Έχετε τρείς επιλογές εγκατάστασης: server, agent ή local. + + - Αν επιλέξετε 'server', θα έχετε τη δυνατότητα να αναλύετε + τα αρχεία συμβάντων (logs), να δημιουργείτε ειδοποιήσεις μέσω email + και αντιδράσεις (responses), καθώς επίσης και να λαμβάνετε logs από + απομακρυσμένους syslog υπολογιστές και συστήματα τα οποία τρέχουν + τους 'agents' (από τους οποίους η δικτυακή κίνηση αποστέλλεται + κρυπτογραφημένα στον διακομιστή). + + - Αν επιλέξετε 'agent'(client), θα έχετε τη δυνατότητα να διαβάσετε + τοπικά αρχεία (από syslog, snort, apache, κλπ) καθώς επίσης και να + τα προωθήσετε (κρυπτογραφημένα) στον διακομιστή (server) για ανάλυση. + + - Αν επιλέξετε 'local', θα έχετε τη δυνατότητα να κάνετε οτιδήποτε κάνει + ο server, εκτός από το να λαμβάνετε απομακρυσμένα μηνύματα από + 'agents' ή εξωτερικές συσκευές syslog. + + + - Επιλέξτε 'server' αν εγκαθιστάτε log/analysis server. + + - Επιλέξτε 'agent' αν έχετε άλλο υπολογιστή ο οποίος τρέχει ως + log server και θέλετε να προωθείτε εκεί τα logs για ανάλυση + (ιδανικό για webservers, database servers, κλπ). + + - Επιλέξτε 'local' αν έχετε μόνο ένα υπολογιστή για να παρακολουθείτε. + + - Περισσότερες πληροφορίες στη διεύθυνση: + http://www.theopenarmor.org/el/manual.html#starting + + diff --git a/etc/templates/el/messages/0x103-thanksforusing.txt b/etc/templates/el/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..5e3e95c38 --- /dev/null +++ b/etc/templates/el/messages/0x103-thanksforusing.txt @@ -0,0 +1,13 @@ + + Ευχαριστούμε για τη χρησιμοποίηση του openarmor HIDS. + Αν έχετε κάποια ερώτηση, πρόταση ή αν βρείτε κάποιο bug, + επικοινωνήστε μαζί μας στο contact@theopenarmor.org ή χρησιμοποιώντας + την λίστα ταχυδρομείου (maillist) στο openarmor-list@theopenarmor.org + ( http://www.theopenarmor.org/main/support/ ). + + Περισσότερες πληροφορίες στη διεύθυνση: + http://www.theopenarmor.org/ + + --- Πατήστε ENTER για να ολοκληρωθεί η εγκατάσταση + (μπορεί να ακολουθούν περισσότερες πληροφορίες) + diff --git a/etc/templates/el/messages/0x104-client.txt b/etc/templates/el/messages/0x104-client.txt new file mode 100644 index 000000000..d3a512428 --- /dev/null +++ b/etc/templates/el/messages/0x104-client.txt @@ -0,0 +1,7 @@ + + - Αρχικά πρέπει να προσθέσετε αυτόν τον agent στο server + προκειμένου να μπορέσουν να επικοινωνήσουν μεταξύ τους. + Όταν το κάνετε, μπορείτε να εκτελέσετε το εργαλείο + 'manage_agents' προκειμένου να εισαγάγετε το authentication key + από τον server. + diff --git a/etc/templates/el/messages/0x105-noboot.txt b/etc/templates/el/messages/0x105-noboot.txt new file mode 100644 index 000000000..cd1cdb623 --- /dev/null +++ b/etc/templates/el/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - Δεν έγινε καμία ενέργεια για να ρυθμιστεί το openarmor HIDS + να ξεκινάει κατά της εκκίνηση του υπολογιστή. + Προσθέστε την ακόλουθη γραμμή στο init script: + diff --git a/etc/templates/el/messages/0x106-logs.txt b/etc/templates/el/messages/0x106-logs.txt new file mode 100644 index 000000000..8c1fd3f4e --- /dev/null +++ b/etc/templates/el/messages/0x106-logs.txt @@ -0,0 +1,9 @@ + - Αν θέλετε να ελέγξετε οποιοδήποτε άλλο αρχείο, αλλάξτε + το openarmor.conf και προσθέστε μια νέα εγγραφή για τοπικό + αρχείο (localfile). + Για να λάβετε απαντήσεις σχετικά με τις ρυθμίσεις, + επισκευθείτε μας στη διεύθυνση http://www.theopenarmor.org/ . + + + --- Πατήστε ENTER για να συνεχίσετε --- + diff --git a/etc/templates/el/messages/0x107-ar.txt b/etc/templates/el/messages/0x107-ar.txt new file mode 100644 index 000000000..0d1179073 --- /dev/null +++ b/etc/templates/el/messages/0x107-ar.txt @@ -0,0 +1,10 @@ + + 3.4- Η ενεργή αντίδραση (active response) σας επιτρέπει + να εκτελέσετε μια συγκεκριμένη εντολή βασισμένη στα + γεγονότα (events) που λήφθησαν. Για παράδειγμα, + μπορείτε να μπλοκάρετε μια διεύθυνση IP ή να + απενεργοποιήσετε την πρόσβαση για ένα συγκεκριμένο + χρήστη. + Περισσότερες πληροφορίες στη διεύθυνση: + http://www.theopenarmor.org/el/manual.html#active-response + diff --git a/etc/templates/el/messages/0x108-ar-enabled.txt b/etc/templates/el/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..f56d97c2f --- /dev/null +++ b/etc/templates/el/messages/0x108-ar-enabled.txt @@ -0,0 +1,14 @@ + - Η ενεργή αντίδραση (active response) ενεργοποιήθηκε. + + - Εξ ορισμού, μπορούμε να ενεργοποιήσουμε τις host-deny + και firewall-drop αντιδράσεις (responses). Η πρώτη θα + προσθέσει ένα υπολογιστή στο αρχείο /etc/hosts.deny. + Η δεύτερη θα μπλοκάρει τον υπολογιστή μέσω + iptables (για linux) ή μέσω ipfilter + (για Solaris, FreeBSD ή NetBSD). + + - Μπορούν να χρησιμοποιηθούν για να σταματήσουν + SSHD brute force scans, portscans και κάποιων άλλων + ειδών επιθέσεις. Μπορείτε επίσης να τις προσθέσετε + για να μπλοκάρετε γενονότα που παράγονται από το + snort, για παράδειγμα. diff --git a/etc/templates/en/errors/0x1-location.txt b/etc/templates/en/errors/0x1-location.txt new file mode 100644 index 000000000..ca78c3f00 --- /dev/null +++ b/etc/templates/en/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Error 0x1. + This script can only be executed from the same directory. + Change directory to where this script is before running it. + You must run it as ./install.sh ." + diff --git a/etc/templates/en/errors/0x2-beroot.txt b/etc/templates/en/errors/0x2-beroot.txt new file mode 100644 index 000000000..c976eb642 --- /dev/null +++ b/etc/templates/en/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Error 0x2. + You must be root to use this script. + diff --git a/etc/templates/en/errors/0x3-dependencies.txt b/etc/templates/en/errors/0x3-dependencies.txt new file mode 100644 index 000000000..e14762893 --- /dev/null +++ b/etc/templates/en/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Error 0x3. + You need a compiler (like gcc or cc) to continue with the + with the installation. + diff --git a/etc/templates/en/errors/0x4-installtype.txt b/etc/templates/en/errors/0x4-installtype.txt new file mode 100644 index 000000000..eef890695 --- /dev/null +++ b/etc/templates/en/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Error 0x4. + Wrong installation type. It can only be agent, server or local. + diff --git a/etc/templates/en/errors/0x5-build.txt b/etc/templates/en/errors/0x5-build.txt new file mode 100644 index 000000000..caa15bbdd --- /dev/null +++ b/etc/templates/en/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Error 0x5. + Building error. Unable to finish the installation. + diff --git a/etc/templates/en/language.txt b/etc/templates/en/language.txt new file mode 100644 index 000000000..d5548a89f --- /dev/null +++ b/etc/templates/en/language.txt @@ -0,0 +1 @@ + ** For installation in English, choose [en]. diff --git a/etc/templates/en/messages.txt b/etc/templates/en/messages.txt new file mode 100644 index 000000000..2cdd7132f --- /dev/null +++ b/etc/templates/en/messages.txt @@ -0,0 +1,109 @@ +# Configuration +yes="y" +no="n" +yesmatch="y" +nomatch="n" +agent="agent" +local="local" +server="server" +help="help" + +# Global +moreinfo="More information at: " +starting="Starting openarmor HIDS" +systemis="System is" +modifiedinit="Init script modified to start openarmor HIDS during boot." +noboot="Unknown system. No init script added." + +# Part 1 +installscript="Installation Script" +system="System" +user="User" +host="Host" +hitanyorabort="Press ENTER to continue or Ctrl-C to abort." +whattoinstall="What kind of installation do you want (server, agent, local, hybrid or help)?" +serverchose="Server installation chosen" +clientchose="Agent(client) installation chosen" +localchose="Local installation chosen" + +# Part 2 +settingupenv="Setting up the installation environment" +wheretoinstall="Choose where to install the openarmor HIDS" +installat="Installation will be made at " +deletedir="The installation directory already exists. Should I delete it?" + +# Part 3 +configuring="Configuring the" +mailnotify="Do you want e-mail notification?" +nomail="Email notification disabled" +whatsemail="What's your e-mail address?" +yoursmtp="We found your SMTP server as" +usesmtp="Do you want to use it?" +usingsmtp="Using SMTP server: " +whatsmtp="What's your SMTP server ip/host?" + +# Part 3.1/agent +serveraddr="What's the IP Address or hostname of the openarmor HIDS server?" +addingip="Adding Server IP" +addingname="Adding Hostname" +configprofile="Enter the agent's config profile name (default: blank)" +addingcfg="Setting agent's config profile name" + + +# Part 3.2 +runsyscheck="Do you want to run the integrity check daemon?" +nosyscheck="Not running syscheck (integrity check daemon)" +yessyscheck="Running syscheck (integrity check daemon)" + +# Part 3.3 +runrootcheck="Do you want to run the rootkit detection engine?" +norootcheck="Not running rootcheck (rootkit detection)" +yesrootcheck="Running rootcheck (rootkit detection)" + +# Part 3.4/server/local +enable_ar="Do you want to enable active response?" +noactive="Active response disabled" +nohosts="host-deny disabled" +yeshosts="host-deny enabled (local) for levels >= 6" +firewallar="Do you want to enable the firewall-drop response?" +nofirewall="firewall-drop disabled." +yesfirewall="firewall-drop enabled (local) for levels >= 6" +defaultwhitelist="Default white list for the active response:" +addwhite="Do you want to add more IPs to the white list?" +ipswhite="IPs (space separated): " + +# Part 3.5/server/local +syslog="Do you want to enable remote syslog (port 514 udp)?" +nosyslog="Remote syslog disabled" +yessyslog="Remote syslog enabled" + +# Part 3.4/3.5 +readlogs="Setting the configuration to analyze the following logs:" + +# Part 5 +installing="Installing the system" +runningmake="Running the Makefile" + +# Final +configurationdone="Configuration finished properly" +tostart="To start openarmor HIDS" +tostop="To stop openarmor HIDS" +configat="The configuration can be viewed or modified at" +addserveragent="In order to connect agent and server, you need to add each agent to the server." +runma="Run the 'manage_agents' to add or remove them" +presskey="Press ENTER to continue" + +# Update +wanttoupdate="You already have openarmor installed. Do you want to update it?" +unabletoupdate="Unable to perform update. A full new install will be required." +updatecompleted="Update completed." +updatefailed="Update failed." +updaterules="Do you want to update the rules?" +updatingrules="Updating rules." +notupdatingrules="Not updating rules." + +# Pf support +pfenable="Do you want to use the PF firewall in the active response?" +nopf="PF response disabled." +pftablename="Name of the PF table to use?" +pfmessage="Add the following lines to the beginning of your PF rules" diff --git a/etc/templates/en/messages/0x101-initial.txt b/etc/templates/en/messages/0x101-initial.txt new file mode 100644 index 000000000..9f9b8f9a6 --- /dev/null +++ b/etc/templates/en/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + You are about to start the installation process of the openarmor HIDS. + You must have a C compiler pre-installed in your system. + diff --git a/etc/templates/en/messages/0x102-installhelp.txt b/etc/templates/en/messages/0x102-installhelp.txt new file mode 100644 index 000000000..3c4dbb563 --- /dev/null +++ b/etc/templates/en/messages/0x102-installhelp.txt @@ -0,0 +1,35 @@ + + - You have these installation options: server, agent, local, or hybrid. + + - If you choose 'server', you will be able to analyze all + the logs, create e-mail notifications and responses, + and also receive logs from remote syslog machines and + from systems running the 'agents' (from where traffic + is sent encrypted to the server). + + - If you choose 'agent'(client), you will be able to read + local files (from syslog, snort, apache, etc) and forward + them (encrypted) to the server for analysis. + + - If you choose 'local', you will be able to do everything + the server does, except receiving remote messages from + the agents or external syslog devices. + + - If you choose 'hybrid', you get the 'local' installation + plus the 'agent' installation. + + - Choose 'server' if you are setting up a log/analysis server. + + - Choose 'agent' if you have another machine to run as a log + server and want to forward the logs to the server for analysis. + (ideal for webservers, database servers ,etc) + + - Choose 'local' if you only have one system to monitor. + + - Choose 'hybrid' if you want this standalone system to analyze + local logs before forwarding alerts to another server. + + - More information at: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/en/messages/0x103-thanksforusing.txt b/etc/templates/en/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..68bed3933 --- /dev/null +++ b/etc/templates/en/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Thanks for using the openarmor HIDS. + If you have any question, suggestion or if you find any bug, + contact us at https://github.com/openarmor/openarmor-hids or using + our public maillist at + https://groups.google.com/forum/#!forum/openarmor-list + + More information can be found at http://www.theopenarmor.org + + --- Press ENTER to finish (maybe more information below). --- + diff --git a/etc/templates/en/messages/0x104-client.txt b/etc/templates/en/messages/0x104-client.txt new file mode 100644 index 000000000..eac94be10 --- /dev/null +++ b/etc/templates/en/messages/0x104-client.txt @@ -0,0 +1,6 @@ + + - You first need to add this agent to the server so they + can communicate with each other. When you have done so, + you can run the 'manage_agents' tool to import the + authentication key from the server. + diff --git a/etc/templates/en/messages/0x105-noboot.txt b/etc/templates/en/messages/0x105-noboot.txt new file mode 100644 index 000000000..ccbfcafd0 --- /dev/null +++ b/etc/templates/en/messages/0x105-noboot.txt @@ -0,0 +1,4 @@ + + - No action was made to configure the openarmor HIDS to start + during the boot. Add the following line to your init script: + diff --git a/etc/templates/en/messages/0x106-logs.txt b/etc/templates/en/messages/0x106-logs.txt new file mode 100644 index 000000000..073bd7ac6 --- /dev/null +++ b/etc/templates/en/messages/0x106-logs.txt @@ -0,0 +1,8 @@ + - If you want to monitor any other file, just change + the openarmor.conf and add a new localfile entry. + Any questions about the configuration can be answered + by visiting us online at http://www.theopenarmor.org . + + + --- Press ENTER to continue --- + diff --git a/etc/templates/en/messages/0x107-ar.txt b/etc/templates/en/messages/0x107-ar.txt new file mode 100644 index 000000000..aed0cf4ca --- /dev/null +++ b/etc/templates/en/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- Active response allows you to execute a specific + command based on the events received. For example, + you can block an IP address or disable access for + a specific user. + More information at: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/en/messages/0x108-ar-enabled.txt b/etc/templates/en/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..9f33b4411 --- /dev/null +++ b/etc/templates/en/messages/0x108-ar-enabled.txt @@ -0,0 +1,10 @@ + - Active response enabled. + + - By default, we can enable the host-deny and the + firewall-drop responses. The first one will add + a host to the /etc/hosts.deny and the second one + will block the host on iptables (if linux) or on + ipfilter (if Solaris, FreeBSD or NetBSD). + - They can be used to stop SSHD brute force scans, + portscans and some other forms of attacks. You can + also add them to block on snort events, for example. diff --git a/etc/templates/es/errors/0x1-location.txt b/etc/templates/es/errors/0x1-location.txt new file mode 100644 index 000000000..8039b5254 --- /dev/null +++ b/etc/templates/es/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Error 0x1. + El programa puede ser solo ejecutado desde el mismo directorio. + Cambie al directorio donde se encuentra el programa antes de ejecutarlo. + Debe de ejecutarlo como ./install.sh ." + diff --git a/etc/templates/es/errors/0x2-beroot.txt b/etc/templates/es/errors/0x2-beroot.txt new file mode 100644 index 000000000..ed75e34fa --- /dev/null +++ b/etc/templates/es/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Error 0x2. + Usted debe ser root para ejecutar el programa. + diff --git a/etc/templates/es/errors/0x3-dependencies.txt b/etc/templates/es/errors/0x3-dependencies.txt new file mode 100644 index 000000000..fa86e72dd --- /dev/null +++ b/etc/templates/es/errors/0x3-dependencies.txt @@ -0,0 +1,4 @@ + + Error 0x3. + Usted necesita un compilador (semejante a gcc ó cc) para continuar con la instalación. + diff --git a/etc/templates/es/errors/0x4-installtype.txt b/etc/templates/es/errors/0x4-installtype.txt new file mode 100644 index 000000000..131e0a4b6 --- /dev/null +++ b/etc/templates/es/errors/0x4-installtype.txt @@ -0,0 +1,5 @@ + + Error 0x4. + Fallo en el tipo de instalación. Unicamente puede ser 'agente', 'servidor' o 'local'. + + diff --git a/etc/templates/es/errors/0x5-build.txt b/etc/templates/es/errors/0x5-build.txt new file mode 100644 index 000000000..fed4d1189 --- /dev/null +++ b/etc/templates/es/errors/0x5-build.txt @@ -0,0 +1,5 @@ + + Error 0x5. + Error durante la construcción. No se ha podido finalizar la instalación. + + diff --git a/etc/templates/es/language.txt b/etc/templates/es/language.txt new file mode 100644 index 000000000..471191ba2 --- /dev/null +++ b/etc/templates/es/language.txt @@ -0,0 +1 @@ + ** Para instalar en Español , eliga [es]. diff --git a/etc/templates/es/messages.txt b/etc/templates/es/messages.txt new file mode 100644 index 000000000..23fec4f88 --- /dev/null +++ b/etc/templates/es/messages.txt @@ -0,0 +1,107 @@ +# Configuration +yes="s" +no="n" +yesmatch="s" +nomatch="n" +agent="agente" +local="local" +server="servidor" +help="ayuda" + +# Global +moreinfo="Más información en: " +starting="Comenzando openarmor HIDS" +systemis="El sistema es" +modifiedinit="Init script modificado para empezar openarmor HIDS durante el arranque." +noboot="Sistema desconocido. El guión init no fué agregado" + +# Part 1 +installscript="Guión de instalación" +system="Sistema" +user="Usuario" +host="servidor" +hitanyorabort="Presione ENTER para continuar ó Ctrl-C para abortar." +whattoinstall="Que tipo de instalación desea (servidor, agente, local ó ayuda)?" +serverchose="Usted eligió instalación de Servidor" +clientchose="Usted eligió instalación de Agente(cliente)" +localchose="Usted eligió instalación Local" + +# Part 2 +settingupenv="Configurando las variables de entorno de la instalación" +wheretoinstall="Eliga donde instalar openarmor HIDS" +installat="La instalación se realizará en " +deletedir="El directorio de instalación ya existe. Desea borrarlo?" + +# Part 3 +configuring="Configurando el sistema" +mailnotify="Desea recibir notificación por correo electrónico?" +nomail="Notificación por correo electrónico deshabilitado" +whatsemail="Cuál es su dirección de correo electrónico?" +yoursmtp="Hemos encontrado su servidor de correo (SMTP)" +usesmtp="Desea usarlo?" +usingsmtp="Usando el servidor SMTP: " +whatsmtp="Cuál es la direccion ó nombre de su servidor de correo SMTP?" + +# Part 3.1/agent +serverip="Cuál es la direccion del servidor openarmor HIDS?" +serveraddr="Cuál es la direccion ó nombre de vuestro del servidor openarmor HIDS?" +addingip="Agregando el IP del servidor" +addingname="Agregando el nombre del servidor" + +# Part 3.2 +runsyscheck="Desea Usted agregar el servidor de integridad del sistema?" +nosyscheck="No se ejecutará syscheck (servidor de integridad del sistema)" +yessyscheck="Ejecutando syscheck (servidor de integridad del sistema)" + +# Part 3.3 +runrootcheck="Desea Usted agregar el sistema de detección de rootkit?" +norootcheck="No se ejecutará rootcheck (sistema de detección de rootkit)" +yesrootcheck="Ejecutando rootcheck (sistema de detección de rootkit)" + +# Part 3.4/server/local +enable_ar="Desea habilitar respuesta activa?" +noactive="Respuesta activa deshabilitada" +nohosts="host-deny deshabilitado" +yeshosts="host-deny habilitado (local) para niveles >= 6" +firewallar="Desea habilitar la respuesta desechar en el Firewall?" +nofirewall="Respuesta desechar en el Firewall deshabilitada." +yesfirewall="Respuesta desechar en el Firewall habilitada (local) para niveles >= 6" +defaultwhitelist="Lista blanca para respuesta activa por omisión:" +addwhite="Desea Usted agregar más IPs a la lista blanca?" +ipswhite="IPs (lista separada por blancos): " + +# Part 3.5/server/local +syslog="Desea Usted habilitar syslog remoto (puerto 514 udp)?" +nosyslog="Syslog remoto deshabilitado" +yessyslog="Syslog remoto habilitado" + +# Part 3.4/3.5 +readlogs="Estableciendo la configuración para analizar los siguientes registros:" + +# Part 5 +installing="Instalando el sistema" +runningmake="Ejecutando el Makefile" + +# Final +configurationdone="Configuración finalizada correctamente" +tostart="Para comenzar openarmor HIDS" +tostop="Para detener openarmor HIDS" +configat="La configuración puede ser leída ó mofificada en" +addserveragent="Para connectar el agente con el servidor, debe agregar cada uno de los agentes en el servidor." +runma="Ejecute el programa 'manage_agents' para agregarlos ó eliminarlos " +presskey="Press ENTER to continue" + +# Update +wanttoupdate="Usted ya ha instalado openarmor previamente. Desea actualizarlo?" +unabletoupdate="Ha sido imposible actualizar el sistema. Se requiere una nueva y completa instalación." +updatecompleted="Actualización completa." +updatefailed="La actualización ha fallado." +updaterules="Desea actualizar las reglas?" +updatingrules="Actualizando las reglas." +notupdatingrules="No se actualizan las reglas." + +# Pf support +pfenable="Desea Usted usar el PF firewall en la respuesta activa?" +nopf="respuesta PF deshabilitada." +pftablename="Nombre de la tabla de PF table a usar?" +pfmessage="Agregar las siguientes lineas al principio de las reglas del PF" diff --git a/etc/templates/es/messages/0x101-initial.txt b/etc/templates/es/messages/0x101-initial.txt new file mode 100644 index 000000000..7c12bd6af --- /dev/null +++ b/etc/templates/es/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Usted va a comenzar el proceso de instalación de openarmor HIDS. + Usted debe tener un compilador de C previamente instalado en el sistema. + diff --git a/etc/templates/es/messages/0x102-installhelp.txt b/etc/templates/es/messages/0x102-installhelp.txt new file mode 100644 index 000000000..72b80c87d --- /dev/null +++ b/etc/templates/es/messages/0x102-installhelp.txt @@ -0,0 +1,30 @@ + + - Tiene tres posibilidades de instalación: servidor, + agente ó local. + + - Si elige 'servidor' será capaz de analizar todo los registros, + crear notificaciónes de correo y respuestas, así como también + recibir registros desde equipos syslog remotos y otros sistemas + ejecutando el 'agente' (que transmitirá el tráfico cifrado hacia el servidor). + + - Si elige 'agente'(cliente) será capaz de leer + registros locales (syslog, snort, apache, etc) y + retrasmitirlos al servidor de analysis. + + - Si elige 'local' será capaz de todo lo que hace + la instalación de 'servidor', excepto recibir mensajes remotos de los + agentes ó fuentes externas de syslog. + + - Elija 'servidor' si desea instalar un servidor de registros + ó análisis. + + - Elija 'agente' si dispone de otra máquina ejecutando el servidor + de lectura de registros y desea transmitir los registros para su + análisis. (ideal para servidore WEB, base de datos, etc) + + -Elija 'local' si tiene que monitorizar un solo sistema . + + - Para más información dirijase a: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/es/messages/0x103-thanksforusing.txt b/etc/templates/es/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..fea4aafae --- /dev/null +++ b/etc/templates/es/messages/0x103-thanksforusing.txt @@ -0,0 +1,10 @@ + + Gracias por usar openarmor HIDS. + Si tiene alguna duda, sugerencia ó encuentra + algún desperfecto, contacte con nosotros en contact@theopenarmor.org + ó usando nuestrs lista pública de correo en openarmor-list@theopenarmor.org + + Más información puede ser encontrada en http://www.theopenarmor.org + + --- Presione ENTER para finalizar. --- + (Tal vez encuentre más información a continuación). diff --git a/etc/templates/es/messages/0x104-client.txt b/etc/templates/es/messages/0x104-client.txt new file mode 100644 index 000000000..45bde6b87 --- /dev/null +++ b/etc/templates/es/messages/0x104-client.txt @@ -0,0 +1,6 @@ + + - Debe añadir este agente en el servidor así podrán + comunicarse el úno con el ótro. Una vez culminada la tarea + podra ejecutar la herramienta 'manage_agents' para importar + la autenticación por medio de las llaves extraidas del servidor. + diff --git a/etc/templates/es/messages/0x105-noboot.txt b/etc/templates/es/messages/0x105-noboot.txt new file mode 100644 index 000000000..096f8c353 --- /dev/null +++ b/etc/templates/es/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - No realizado ninguna acción para configurar openarmor HIDS + durante el encendido de la máquina. Agrege las siguiente linea + a vuestro archivo código init: + diff --git a/etc/templates/es/messages/0x106-logs.txt b/etc/templates/es/messages/0x106-logs.txt new file mode 100644 index 000000000..5bc1bab72 --- /dev/null +++ b/etc/templates/es/messages/0x106-logs.txt @@ -0,0 +1,9 @@ + + - Si desea monitorizar algún otro registro, solo + tendrá que editar el archivo openarmor.conf y agregar una + nueva entrada de tipo localfile. + Cualquier otra pregunta de configuración podrá ser + respondida visitandonos en linea en http://www.theopenarmor.org . + + --- Presione ENTER para continuar --- + diff --git a/etc/templates/es/messages/0x107-ar.txt b/etc/templates/es/messages/0x107-ar.txt new file mode 100644 index 000000000..186519f9f --- /dev/null +++ b/etc/templates/es/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- Las respuestas activas le permitirán ejecutar un comando + específico en base a los eventos recibidos. Por ejemplo, + Usted podra bloquear una dirección IP ó deshabilitar el acceso + de un usuario específico. + Más información en: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/es/messages/0x108-ar-enabled.txt b/etc/templates/es/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..7cc42a6fe --- /dev/null +++ b/etc/templates/es/messages/0x108-ar-enabled.txt @@ -0,0 +1,15 @@ + + - Respuesta activa habilitada. + + - Por omisión podemos habilitar el bloqueo del servicio + o el descarte del paquete por medio del Firewall. + El bloqueo del servicio agregará al atacante en el archivo etc/hosts.deny + y el decarte del paquete añadirá la regla en iptables + (si el sistema fuera linux) ó ipfilter (si el sistema fuera + Solaris, FreeBSD or NetBSD). + + - Las dos repuestas pueden ser utilizadas para detener un escaneo + de fuerza bruta contra SSHD, escaneo de puertos y otras formas + de ataque. Por ejemplo se podrá agregar a los atacantes + de acuerdo a eventos registrados por medio de snort. + diff --git a/etc/templates/fr/errors/0x1-location.txt b/etc/templates/fr/errors/0x1-location.txt new file mode 100644 index 000000000..b78a0975f --- /dev/null +++ b/etc/templates/fr/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Error 0x1. + Ce script ne peut être exécuté que depuis le même répertoire. + Déplacez vous où est le script avant de l'exécuter. + Vous devez le lancer par ./install.sh ." + diff --git a/etc/templates/fr/errors/0x2-beroot.txt b/etc/templates/fr/errors/0x2-beroot.txt new file mode 100644 index 000000000..22350f35e --- /dev/null +++ b/etc/templates/fr/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Error 0x2. + Vous devez être root pour exécuter ce script. + diff --git a/etc/templates/fr/errors/0x3-dependencies.txt b/etc/templates/fr/errors/0x3-dependencies.txt new file mode 100644 index 000000000..7efa98f74 --- /dev/null +++ b/etc/templates/fr/errors/0x3-dependencies.txt @@ -0,0 +1,4 @@ + + Error 0x3. + Vous devez avoir un compilateur (gcc ou cc) pour continuer l'installation. + diff --git a/etc/templates/fr/errors/0x4-installtype.txt b/etc/templates/fr/errors/0x4-installtype.txt new file mode 100644 index 000000000..12b5aed06 --- /dev/null +++ b/etc/templates/fr/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Error 0x4. + Mauvais type d'installation. Cela ne peut être que agent, serveur ou local. + diff --git a/etc/templates/fr/errors/0x5-build.txt b/etc/templates/fr/errors/0x5-build.txt new file mode 100644 index 000000000..712e20b8b --- /dev/null +++ b/etc/templates/fr/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Error 0x5. + Erreur de compilation. Impossible de finir l'installation. + diff --git a/etc/templates/fr/language.txt b/etc/templates/fr/language.txt new file mode 100644 index 000000000..b3a9c82d8 --- /dev/null +++ b/etc/templates/fr/language.txt @@ -0,0 +1 @@ + ** Pour une installation en français, choisissez [fr] diff --git a/etc/templates/fr/messages.txt b/etc/templates/fr/messages.txt new file mode 100644 index 000000000..9aa35ddb6 --- /dev/null +++ b/etc/templates/fr/messages.txt @@ -0,0 +1,109 @@ +# Configuration +yes="o" +no="n" +yesmatch="o" +nomatch="n" +agent="agent" +local="local" +server="serveur" +help="aide" + +# Global +moreinfo="Plus d'information sur: " +starting="Démarrage de openarmor HIDS" +systemis="Le Système est" +modifiedinit="Script d'initialisation modifié pour démarrer openarmor HIDS pendant le boot." +noboot="Système inconnu. Aucun script d'initialisation ajouté." + +# Part 1 +installscript="Script d'installation" +system="Système" +user="Utilisateur" +host="Hôte" +hitanyorabort="Appuyez sur Entrée pour continuer ou Ctrl-C pour annuler." +whattoinstall="Quel type d'installation voulez-vous (serveur, agent, local ou aide) ?" +serverchose="Installation du serveur choisie" +clientchose="Installation de l'agent (client) choisie" +localchose="Installation en local choisie" + +# Part 2 +settingupenv="Définition de l'environnement d'installation" +wheretoinstall="Choisissez votre répertoire d'installation de openarmor HIDS" +installat="L'installation sera faite sur " +deletedir="Le répertoire d'installation existe déjà. Doit-on le supprimer ?" + +# Part 3 +configuring="Configuration de" +mailnotify="Voulez-vous une alerte par email ?" +nomail="Alerte par email désactivée" +whatsemail="Quel est votre adresse email ?" +yoursmtp="Nous trouvons votre serveur SMTP sur" +usesmtp="Voulez-vous l'utiliser ?" +usingsmtp="Serveur SMTP utilisé : " +whatsmtp="Quel est l'adresse IP ou le nom d'hôte de votre serveur SMTP ?" + +# Part 3.1/agent +serverip="Quelle est l'adresse IP de votre serveur openarmor HIDS ?" +serveraddr="Quelle est l'adresse IP ou le nom d'hôte de votre serveur openarmor HIDS ?" +addingip="Ajout de l'IP du Serveur" +addingname="Ajout de le nom d'hôte du Serveur" + + +# Part 3.2 +runsyscheck="Voulez-vous démarrer le démon de vérification d'intégrité ?" +nosyscheck="Syscheck non lancé (démon de vérification d'intégrité)" +yessyscheck="Lancement de syscheck (démon de vérification d'intégrité)" + +# Part 3.3 +runrootcheck="Voulez-vous démarrer le moteur de détection de rootkit ?" +norootcheck="Rootcheck non lancé (détection de rootkit)" +yesrootcheck="Lancement de rootcheck (détection de rootkit)" + +# Part 3.4/server/local +enable_ar="voulez-vous démarrer la réponse active ?" +noactive="Réponse active désactivée" +nohosts="contrôle d'hôte (host-deny) désactivé" +yeshosts="contrôle d'hôte (host-deny) activé (local) pour les levels >= 6" +firewallar="Voulez-vous activer la réponse pare-feu (firewall-drop) ?" +nofirewall="pare-feu (firewall-drop) désactivé." +yesfirewall="pare-feu (firewall-drop) activé (local) pour les levels >= 6" +defaultwhitelist="liste blanche (white list) par défaut pour la réponse active :" +addwhite="Voulez-vous d'autres adresses IP dans votre liste (white list) ?" +ipswhite="IPs (séparées par des espaces) : " + +# Part 3.5/server/local +syslog="Voulez-vous activer fonctionnalité syslog (port udp 514) ?" +nosyslog="Fonctionnalité syslog désactivé" +yessyslog="Fonctionnalité syslog activé" + +# Part 3.4/3.5 +readlogs="Mise en place de la configuration pour analyser les logs suivants :" + +# Part 5 +installing="Installation du système" +runningmake="Exécution du Makefile" + +# Final +configurationdone="Configuration correctement terminée" +tostart="Pour démarrer openarmor HIDS" +tostop="Pour arrêter openarmor HIDS" +configat="La configuration peut être visualisée ou modifiée dans" +addserveragent="Vous devez ajouter le(s) agent(s) avant qu'ils aient un accés autorisé." +runma="Lancez 'manage_agent' pour les ajouter ou les supprimer" +presskey="Appuyez sur Entrée pour continuer" + +# Update +wanttoupdate="Vous avez déjà installé openarmor. Voulez-vous le mettre à jour ?" +unabletoupdate="Impossible de mettre à jour. Une nouvelle installation est nécessaire." +updatecompleted="Mise à jour complète." +updatefailed="Echec de la mise à jour." +updaterules="Voulez-vous mettre à jour les règles ?" +updatingrules="Mise à jour des règles." +notupdatingrules="Règles non mises à jour." + +# Pf support +pfenable="Voulez-vous utiliser le firewall PF dans la réponse active ?" +nopf="Réponse par PF désactivée." +pftablename="Nom de la table PF à utiliser ?" +pfmessage="Ajouter les lignes suivantes au début de vos règles" + diff --git a/etc/templates/fr/messages/0x101-initial.txt b/etc/templates/fr/messages/0x101-initial.txt new file mode 100644 index 000000000..1c9b16743 --- /dev/null +++ b/etc/templates/fr/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Vous êtes sur le point d'installer openarmor HIDS. + Vous devez avoir une compilateur C préinstallé sur votre système. + diff --git a/etc/templates/fr/messages/0x102-installhelp.txt b/etc/templates/fr/messages/0x102-installhelp.txt new file mode 100644 index 000000000..64d1b0fbd --- /dev/null +++ b/etc/templates/fr/messages/0x102-installhelp.txt @@ -0,0 +1,29 @@ + + - Vous avez 3 installations possibles : server, agent ou local. + + - Si vous choisissez 'serveur', vous pourrez analyser tous + les logs, créer des alertes par email et leurs réponses, + et aussi recevoir les logs depuis les machines syslog + distantes et depuis les systèmes utilisant les 'agents' + (le tranfert étant codé et envoyé jusqu'au server). + + - Si vous choisissez 'agent'(client), vous pourrez lire les + fichiers locaux (de syslog, snort, apache, etc) et les + envoyer (codés) au serveur pour les analyser. + + - Si vous choisissez 'local', vous pourrez faire tout ce + que le serveur fait, à l'exception de la réception des + messages des agents ou de machines syslog externes. + + - Choisissez 'serveur' si vous installez un serveur de log ou un analyseur. + + - Choisissez 'agent' si vous avez une autre machine lancée en tant + que serveur de log et que vous voulez lui envoyer les logs pour analyse. + (idéal pour les serveurs web, de base de données, etc) + + - choisissez 'local' si vous n'avez qu'une machine à surveiller. + + - Plus d'information sur : + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/fr/messages/0x103-thanksforusing.txt b/etc/templates/fr/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..8d357016e --- /dev/null +++ b/etc/templates/fr/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Merci d'utiliser openarmor HIDS. + Si vous avez des questions, suggestions ou si vous trouvez + un bug, contactez nous sur contact@theopenarmor.org ou en utilisant la + liste de diffusion publique sur openarmor-list@theopenarmor.org + ( http://www.theopenarmor.org/en/mailing_lists.html ). + + Plus d'information peut être trouver sur http://www.theopenarmor.org + + --- Appuyez sur Entrée pour finir (peut-être plus d'info plus bas). --- + diff --git a/etc/templates/fr/messages/0x104-client.txt b/etc/templates/fr/messages/0x104-client.txt new file mode 100644 index 000000000..92194551a --- /dev/null +++ b/etc/templates/fr/messages/0x104-client.txt @@ -0,0 +1,6 @@ + + - Vous devez d'abord ajouter cet agent sur le serveur pour + qu'ils communiquent entre eux. Quand cela sera fait, + vous pourrez lancer l'outil 'manage_agents' pour + importer la clef d'authentification depuis le serveur. + diff --git a/etc/templates/fr/messages/0x105-noboot.txt b/etc/templates/fr/messages/0x105-noboot.txt new file mode 100644 index 000000000..73074adc4 --- /dev/null +++ b/etc/templates/fr/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - Aucune action n'a été faite pour configurer openarmor HIDS pour + démarrer lors du boot. Ajoutez la ligne suivante à votre script + d'initialisation : + diff --git a/etc/templates/fr/messages/0x106-logs.txt b/etc/templates/fr/messages/0x106-logs.txt new file mode 100644 index 000000000..72c493dea --- /dev/null +++ b/etc/templates/fr/messages/0x106-logs.txt @@ -0,0 +1,9 @@ + - Si vous voulez surveiller d'autres fichiers, changez + le fichier openarmor.conf en ajoutant une nouvelle valeur + de nom de fichier local. + Pour toutes vos questions sur la configuration, + consultez notre site web http://www.theopenarmor.org . + + + --- Appuyez sur Entrée pour continuer --- + diff --git a/etc/templates/fr/messages/0x107-ar.txt b/etc/templates/fr/messages/0x107-ar.txt new file mode 100644 index 000000000..9339d729b --- /dev/null +++ b/etc/templates/fr/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- La réponse active vous permet d'éxécuter des commandes + spécifiques en fonction d'évènement. Par exemple, + vous pouvez bloquer une adresse IP ou interdire + l'accès à un utilisateur spécifique. + Plus d'information sur : + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/fr/messages/0x108-ar-enabled.txt b/etc/templates/fr/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..d17ad2ccc --- /dev/null +++ b/etc/templates/fr/messages/0x108-ar-enabled.txt @@ -0,0 +1,11 @@ + - Réponse active activée. + + - Par défaut, nous pouvons activer le contrôle d'hôte + et le pare-feu (firewall-drop). Le premier ajoute + un hôte dans /etc/hosts.deny et le second bloquera + l'hôte dans iptables (sous linux) ou dans ipfilter + (sous Solaris, FreeBSD ou NetSBD). + - Ils peuvent aussi être utilisés pour arrêter les scans + en force brute de SSHD, les scans de ports ou d'autres + formes d'attaques. Vous pouvez aussi les bloquer par + rapport à des évènements snort, par exemple. diff --git a/etc/templates/hu/errors/0x1-location.txt b/etc/templates/hu/errors/0x1-location.txt new file mode 100644 index 000000000..1220711e5 --- /dev/null +++ b/etc/templates/hu/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Hiba 0x1. + Ez a script csak a saját könyvtárából futtatható. + Kérem lépjen be a kérdéses script könyvtárába mielőtt futtatná. + Úgy kell futtatnia, mint ./install.sh ." + diff --git a/etc/templates/hu/errors/0x2-beroot.txt b/etc/templates/hu/errors/0x2-beroot.txt new file mode 100644 index 000000000..364fbad91 --- /dev/null +++ b/etc/templates/hu/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Hiba 0x2. + Ezen script használatához root jogosultsággal kell remdelkeznie. + diff --git a/etc/templates/hu/errors/0x3-dependencies.txt b/etc/templates/hu/errors/0x3-dependencies.txt new file mode 100644 index 000000000..4f0dbdfae --- /dev/null +++ b/etc/templates/hu/errors/0x3-dependencies.txt @@ -0,0 +1,4 @@ + + Hiba 0x3. + A telepítés folytatásához szüksége van egy fordító programra (pl. gcc vagy cc). + diff --git a/etc/templates/hu/errors/0x4-installtype.txt b/etc/templates/hu/errors/0x4-installtype.txt new file mode 100644 index 000000000..d1226a07f --- /dev/null +++ b/etc/templates/hu/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Hiba 0x4. + Rossz telepítési típus. Csak agent(kliens), szerver vagy lokális lehet. + diff --git a/etc/templates/hu/errors/0x5-build.txt b/etc/templates/hu/errors/0x5-build.txt new file mode 100644 index 000000000..b021df23f --- /dev/null +++ b/etc/templates/hu/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Hiba 0x5. + Hiba merült fel a kompilálás közben. Nem tudtam befejezni a telepítést. + diff --git a/etc/templates/hu/language.txt b/etc/templates/hu/language.txt new file mode 100644 index 000000000..ab2dbe533 --- /dev/null +++ b/etc/templates/hu/language.txt @@ -0,0 +1 @@ + ** A Magyar nyelvű telepítéshez válassza [hu]. diff --git a/etc/templates/hu/messages.txt b/etc/templates/hu/messages.txt new file mode 100644 index 000000000..3b2ac8a3f --- /dev/null +++ b/etc/templates/hu/messages.txt @@ -0,0 +1,110 @@ +# Configuration +yes="i" +no="n" +yesmatch="i" +nomatch="n" +agent="agent" +local="lokális" +server="szerver" +help="segítség" + +# Global +moreinfo="További információk: " +starting="openarmor HIDS Indítása" +systemis="A rendszer" +modifiedinit="Init script módosítva, hogy bootoláskor automatikusan indítsa az openarmor HIDS-et." +noboot="Ismeretlen rendszer. Nincs init script hozzáadva." + +# Part 1 +installscript="Telepítő Script" +system="Rendszer" +user="Felhasználó" +host="Hoszt" +hitanyorabort="Nyomjon ENTER-t a folytatáshoz vagy Ctrl-C-t a megszakításhoz." +whattoinstall="Milyen típusú telepítést szeretne? (szerver, agent, lokális vagy segítség)?" +serverchose="Szerver telepítés kiválasztva" +clientchose="Agent(kliens) telepítés kiválasztva" +localchose="Lokális telepítés kiválasztva" + +# Part 2 +settingupenv="A telepítési környezet létrehozása" +wheretoinstall="Válassza ki az openarmor HIDS telepítési helyét" +installat="A telepítés a következő helyre történik: " +deletedir="A célkönyvtár már létezik. Törölhetem?" + +# Part 3 +configuring="A következő konfigurálása: " +mailnotify="Szeretne e-mail értesítést?" +nomail="E-mail értesítés kikapcsolva" +whatsemail="Mi az ön e-mail címe?" +yoursmtp="Az ön SMTP szerverének állapota: " +usesmtp="Szeretné használni?" +usingsmtp="SMTP szerver használata: " +whatsmtp="Mi az ön SMTP szerverének ip címe/hoszt neve?" + +# Part 3.1/agent +serverip="Mi az IP címe az openarmor HIDS szervernek?" +serveraddr="Mi az IP címe/hoszt neve az openarmor HIDS szervernek?" +addingip="Szerver IP hozzáadása" +addingname="Szerver hoszt neve hozzáadása" + + +# Part 3.2 +runsyscheck="Szeretné futtatni az integritás ellenőrző démont?" +nosyscheck="Rendszerellenőrzés mellőzése (integritás ellenőrző démon)" +yessyscheck="Rendszerellenőrzés futtatása (integritás ellenőrző démon)" + +# Part 3.3 +runrootcheck="Szeretné futtatni a rootkit detektáló motort?" +norootcheck="Gyökérellenőrzés mellőzése (rootkit detektálás)" +yesrootcheck="Gyökérellenőrzés futtatása (rootkit detektálás)" + +# Part 3.4/server/local +enable_ar="Szeretné bekapcsolni az active response funkciót?" +noactive="Active response kikapcsolva" +nohosts="host-deny kikapcsolva" +yeshosts="host-deny bekapcsolva (lokális) for levels >= 6" +firewallar="Szeretné bekapcsolni a firewall-drop response funkciót?" +nofirewall="firewall-drop kikapcsolva." +yesfirewall="firewall-drop bekapcsolva (lokális) for levels >= 6" +defaultwhitelist="Alapértelmezett fehér lista az active response számára:" +addwhite="Szeretne további IP címeket hozzáadni a fehér listához?" +ipswhite="IP-k (szóközzel elválasztva): " + +# Part 3.5/server/local +syslog="Be szeretné kapcsolni a távoli rendszernaplózást (port 514 udp)?" +nosyslog="Távoli rendszernaplózás kikapcsolva" +yessyslog="Távoli rendszernaplózás bekapcsolva" + +# Part 3.4/3.5 +readlogs="A konfiguráció beállítása a következő naplók elemzéséhez:" + +# Part 5 +installing="A rendszer telepítése" +runningmake="A Make fájl futtatása" + +# Final +configurationdone="A konfiguráció sikeresen befejeződött" +tostart="Az openarmor HIDS indítása" +tostop="Az openarmor HIDS leállítása" +configat="A konfigurációs fájl megtekinthető vagy módosítható itt: " +addserveragent="A kliens és szerver összekapcsolásához, minden egyes klienst + hozzá kell adnia a szerverhez." +runma="Futtassa a 'manage_agents' parancsot a kliensek hozzáadásához + vagy eltávolításához." +presskey="A folytatáshoz nyomja meg az ENTER-t" + +# Update +wanttoupdate="Az openarmor már telepítve van. Szeretné frissíteni?" +unabletoupdate="A frissítés nem lehetséges. Egy teljesen új installáció szükséges." +updatecompleted="A frissítés sikeresen befejeződött." +updatefailed="A frissítés meghiúsult." +updaterules="Szeretné frissíteni a szabályokat?" +updatingrules="A szabályok frissítése." +notupdatingrules="Nincs szabály frissítés." + +# Pf support +pfenable="Szeretné alkalmazni a PF tűzfalat az active response során?" +nopf="PF response kikapcsolva." +pftablename="Az alkalmazandó PF tábla neve?" +pfmessage="Adja hozzá a következő sorokat a PF szabályainak kezdetéhez" diff --git a/etc/templates/hu/messages/0x101-initial.txt b/etc/templates/hu/messages/0x101-initial.txt new file mode 100644 index 000000000..95ff4af16 --- /dev/null +++ b/etc/templates/hu/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Ön elindította az openarmor HIDS telepítési folyamatát. + Egy C fordító programnak, már előzőleg telepítve kell lennie a rendszerén. + diff --git a/etc/templates/hu/messages/0x102-installhelp.txt b/etc/templates/hu/messages/0x102-installhelp.txt new file mode 100644 index 000000000..c5214d451 --- /dev/null +++ b/etc/templates/hu/messages/0x102-installhelp.txt @@ -0,0 +1,29 @@ + + - Három féle telepítési lehetősége van: szerver, agent(kliens) vagy helyi. + + - Ha a 'szerver' opciót választja, akkor képes lesz kielemezni + minden naplót, létrehozni e-mail értesítéseket és válaszokat, + és ugyancsak lehetősége nyílik távoli syslog gépektől és + az 'agent'(kliens)-t futtató rendszerektől naplókat fogadni + (ahol a forgalom titkosított kapcsolaton keresztül zajlik a szerver felé). + + - Ha az 'agent'(kliens) opciót választja, lehetősége lesz olvasni a + helyi fájlokat (a syslog-ból, snort-ból, apache-ból, stb.) és + továbbküldeni őket (titkosítva) a szerverre elemzés céljából. + + - Ha a 'local'(helyi) opciót választja, akkor képes lesz mindazt megtenni, + amire a szerver képes, kivéve a távoli üzenetek(naplók) fogadását + a kliensektől vagy külső syslog eszközöktől. + + - Válassza a 'szerver' telepítést, ha egy + naplózó/elemző szervert szeretne létrehozni. + + - Válassza az 'agent' telepítést, ha van egy gépe, amit naplózó + szervernek használ és erre a szerverre szeretné továbbítani + a naplókat további elemzés céljából + (ideális megoldás webszervereknek, adatbázis szervereknek , stb). + + - Válassza a 'lokális' telepítést, ha csak egy rendszere van, + amit monitoroznia kell. + + - További információk: http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html diff --git a/etc/templates/hu/messages/0x103-thanksforusing.txt b/etc/templates/hu/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..ade106ae4 --- /dev/null +++ b/etc/templates/hu/messages/0x103-thanksforusing.txt @@ -0,0 +1,12 @@ + + Köszönjük, hogy az openarmor HIDS programot használja! + Ha egyéb kérdése, javaslata van, illetve valamilyen bugot talált + a programban, lépjen velünk kapcsolatba a contact@theopenarmor.org, + vagy a nyilvános levelezőlistánkat használva az + openarmor-list@theopenarmor.org e-mail címeken. + ( http://www.theopenarmor.org/main/support/ ). + + További információkért látogasson el a http://www.theopenarmor.org weboldalra. + + --- A befejezéshez nyomjon ENTER-t (alább további információkat talál). --- + diff --git a/etc/templates/hu/messages/0x104-client.txt b/etc/templates/hu/messages/0x104-client.txt new file mode 100644 index 000000000..04e92409c --- /dev/null +++ b/etc/templates/hu/messages/0x104-client.txt @@ -0,0 +1,5 @@ + + - Először hozzá kell adnia ezt a klienst a szerverhez, + így azok tudnak kommunikálni egymással. Amikor ezzel + végzett, már futtathatja a 'manage_agents' eszközt, + a hitelesítő kulcs szerverről történő importálásához. diff --git a/etc/templates/hu/messages/0x105-noboot.txt b/etc/templates/hu/messages/0x105-noboot.txt new file mode 100644 index 000000000..8db16d422 --- /dev/null +++ b/etc/templates/hu/messages/0x105-noboot.txt @@ -0,0 +1,4 @@ + + - Nem történt intézkedés az openarmor HIDS bootoláskor + történő automatikus indításának beállítása érdekében. + Adja hozzá a következő sort az ön init scriptjéhez. diff --git a/etc/templates/hu/messages/0x106-logs.txt b/etc/templates/hu/messages/0x106-logs.txt new file mode 100644 index 000000000..9227f1243 --- /dev/null +++ b/etc/templates/hu/messages/0x106-logs.txt @@ -0,0 +1,8 @@ + - Ha egyéb fájlokat is szeretne monitorozni, + csak változtassa meg az openarmor.conf-ot + és adjon hozzá egy új helyi fájl bejegyzést. + A konfigurálással kapcsolatos egyéb kérdéseire választ kaphat, + ha felkeresi weboldalunkat: http://www.theopenarmor.org . + + --- A folytatáshoz nyomja meg az ENTER billentyűt --- + diff --git a/etc/templates/hu/messages/0x107-ar.txt b/etc/templates/hu/messages/0x107-ar.txt new file mode 100644 index 000000000..97ae73072 --- /dev/null +++ b/etc/templates/hu/messages/0x107-ar.txt @@ -0,0 +1,7 @@ + + 3.4- Az active response funkció lehetővé teszi + specifikus parancsok végrehajtását a beérkezett események alapján. + Például, önnek így lehetősége van blokkolni egy IP címet + vagy egy adott felhasználó hozzáférését. + További információk: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html diff --git a/etc/templates/hu/messages/0x108-ar-enabled.txt b/etc/templates/hu/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..931a28920 --- /dev/null +++ b/etc/templates/hu/messages/0x108-ar-enabled.txt @@ -0,0 +1,13 @@ + - Active response bekapcsolva. + + - Alapértelmezés szerint engedélyezheti a host-deny és a + firewall-drop responses funkciókat. + Az első hozzá fog adni egy hosztot az /etc/hosts.deny + fájlhoz, és a második pedig blokkolni fogja a hosztot + (linux esetében) az iptables vagy (Solaris, FreeBSD + vagy NetBSD esetében) az ipfilter tűzfalakban. + - Ezek a funkciók az SSHD brute force scan-ek, + a portscan-ek és néhány egyéb támadási forma + megakadályozására használhatók. + Példának okáért ezeket a blokkolási mechanizmusokat, + akár a snort riasztásokra is alapozhatja. diff --git a/etc/templates/it/errors/0x1-location.txt b/etc/templates/it/errors/0x1-location.txt new file mode 100644 index 000000000..345e5a76b --- /dev/null +++ b/etc/templates/it/errors/0x1-location.txt @@ -0,0 +1,7 @@ + + Error 0x1. + Questo script deve essere eseguito a partire dalla directory in cui + si trova. + Prima di eseguire questo script entra nella directory in cui si trova. + Per eseguire lo script scrivi "./install.sh" + diff --git a/etc/templates/it/errors/0x2-beroot.txt b/etc/templates/it/errors/0x2-beroot.txt new file mode 100644 index 000000000..ae7b96e70 --- /dev/null +++ b/etc/templates/it/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Error 0x2. + Devi essere root per eseguire questo script. + diff --git a/etc/templates/it/errors/0x3-dependencies.txt b/etc/templates/it/errors/0x3-dependencies.txt new file mode 100644 index 000000000..d1475d5bf --- /dev/null +++ b/etc/templates/it/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Error 0x3. + E' necessario avere un compilatore installato (come gcc o cc) per proseguire + con l'installazione. + diff --git a/etc/templates/it/errors/0x4-installtype.txt b/etc/templates/it/errors/0x4-installtype.txt new file mode 100644 index 000000000..69c1835be --- /dev/null +++ b/etc/templates/it/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Error 0x4. + Tipo di installazione errata. Può essere solamente Server, Agent o Local. + diff --git a/etc/templates/it/errors/0x5-build.txt b/etc/templates/it/errors/0x5-build.txt new file mode 100644 index 000000000..2381f39e7 --- /dev/null +++ b/etc/templates/it/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Error 0x5. + Errore di compilazione. Impossibile terminare l'installazione. + diff --git a/etc/templates/it/language.txt b/etc/templates/it/language.txt new file mode 100644 index 000000000..c5a377436 --- /dev/null +++ b/etc/templates/it/language.txt @@ -0,0 +1 @@ + ** Per l'installazione in Italiano, scegli [it]. diff --git a/etc/templates/it/messages.txt b/etc/templates/it/messages.txt new file mode 100644 index 000000000..06faf9eaf --- /dev/null +++ b/etc/templates/it/messages.txt @@ -0,0 +1,108 @@ +# Configuration +yes="s" +no="n" +yesmatch="s" +nomatch="n" +agent="agent" +local="local" +server="server" +help="help" + +# Global +moreinfo="Maggiori informazioni su: " +starting="Avvio openarmor HIDS" +systemis="Il Sistema è" +modifiedinit="Script di Init modificato per eseguire openarmor HIDS in fase di boot." +noboot="Sistema sconosciuto. Nessuno script di init aggiunto." + +# Part 1 +installscript="Script di installazione" +system="Sistema" +user="User" +host="Host" +hitanyorabort="Premi ENTER per continuare o Ctrl-C per abbandonare." +whattoinstall="Che tipo di installazione vuoi fare (server, agent, local o help)?" +serverchose="Scelta installazione Server" +clientchose="Scelta installazione Agent(client)" +localchose="Scelta installazione Local" + +# Part 2 +settingupenv="Configurazione dell'ambiente di installazione" +wheretoinstall="Scegli dove installare openarmor HIDS" +installat="L'installazione verrà effettuata in " +deletedir="La directory di installazione è già presente. La devo cancellare?" + +# Part 3 +configuring="Configuro " +mailnotify="Vuoi attivare l'e-mail di notifica?" +nomail="E-mail di notifica disattivata" +whatsemail="Qual'è il tuo indirizzo e-mail?" +yoursmtp="Il tuo server SMTP è" +usesmtp="Vuoi utilizzarlo?" +usingsmtp="Utilizzo il server SMTP: " +whatsmtp="Qual'è l'ip/host del tuo server SMTP?" + +# Part 3.1/agent +serverip="Qual'è l'indirizzo IP del server openarmor HIDS?" +serveraddr="Qual'è l'indirizzo IP/host del server openarmor HIDS?" +addingip="Aggiungo l'IP del Server" +addingname="Aggiunta di host nome del Server" + +# Part 3.2 +runsyscheck="Vuoi attivare il demone di controllo dell'integrità?" +nosyscheck="Syscheck (demone di controllo dell'integrità) disattivato" +yessyscheck="Syscheck (demone di controllo dell'integrità) attivato" + +# Part 3.3 +runrootcheck="Vuoi attivare il sistema di rilevamento dei rootkit?" +norootcheck="Rootcheck (Sistema di rilevamento dei rootkit) disattivato" +yesrootcheck="Rootcheck (Sistema di rilevamento dei rootkit) attivato" + +# Part 3.4/server/local +enable_ar="Vuoi abilitare la risposta attiva?" +noactive="Risposta attiva disabilitata" +nohosts="host-deny disattivato" +yeshosts="host-deny attivato (local) per i livelli >= 6" +firewallar="Vuoi attivare la risposta firewall-drop?" +nofirewall="firewall-drop disattivata." +yesfirewall="firewall-drop attivata (local) per i livelli >= 6" +defaultwhitelist="White list di default per la risposta attiva:" +addwhite="Vuoi aggiungere altri indirizzi IP alla white list?" +ipswhite="Indirizzi IP (separati da uno spazio): " + +# Part 3.5/server/local +syslog="Vuoi attivare il syslog remoto (porta 514 udp)?" +nosyslog="Syslog remoto disattivato" +yessyslog="Syslog remoto attivato" + +# Part 3.4/3.5 +readlogs="Imposto la configurazione per l'analisi dei seguenti logs:" + +# Part 5 +installing="Installo il sistema" +runningmake="Eseguo il Makefile" + +# Final +configurationdone="Configurazione terminata correttamente" +tostart="Per avviare openarmor HIDS" +tostop="Per arrestare openarmor HIDS" +configat="La configurazione può essere vista o modificata in" +addserveragent="E' necessario aggiungere gli agent(s) prima che siano autorizzati ad accedere al server." +runma="Utilizza 'manage_agents' per aggiungerli o rimuoverli" +presskey="Premi ENTER per continuare." + +# update +wanttoupdate="openarmor è già stato installato. Vuoi aggiornarlo ?" +unabletoupdate="Impossibile eseguire l'aggiornamento. E' necessaria un'installazione completa." +updatecompleted="Aggiornamento completato." +updatefailed="Aggiornamento fallito." +updaterules="Si desidera aggiornare le regole ?" +updatingrules="Aggiornamento delle regole in corso." +notupdatingrules="Nessun aggiornamento delle regole in corso." + +# Pf support +pfenable="Do you want to use the PF firewall in the active response?" +nopf="PF response disabled." +pftablename="Name of the PF table to use?" +pfmessage="Add the following lines to the beginning of your rules" + diff --git a/etc/templates/it/messages/0x101-initial.txt b/etc/templates/it/messages/0x101-initial.txt new file mode 100644 index 000000000..1980a777a --- /dev/null +++ b/etc/templates/it/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Stai per iniziare il processo di installazione di openarmor HIDS. + Devi avere un compilatore C pre-installato sul tuo sistema. + diff --git a/etc/templates/it/messages/0x102-installhelp.txt b/etc/templates/it/messages/0x102-installhelp.txt new file mode 100644 index 000000000..da9139674 --- /dev/null +++ b/etc/templates/it/messages/0x102-installhelp.txt @@ -0,0 +1,27 @@ + - Hai tre tipi di installazione possibili: server, agent o local. + + - Se scegli 'server', sarai in grado di analizzare tutti i logs, + creare e-mail di notifica e risopsta, e ricevere i logs da + server syslog remoti e dai sistemi che eseguono gli 'agents' + (da dove il traffico viene inviato crittografato al server). + + - Se scegli 'agent' (client), sarai in grado di leggere i files + locali (di syslog, snort, apache, etc..) e inoltrarli (crittografati) + al server per l'analisi. + + - Se scegli 'local', sarai in grado di fare tutto quello che fa il + server, eccetto la ricezione di messaggi da parte degli agents + o dei sistemi di syslog remoti. + + - Scegli 'server' se desideri configurare un server di log/analisi + + - Scegli 'agent' se hai già un'altra macchina che faccia da log server + e vuoi inoltrarle i log da analizzare (ideale per webservers, + database servers, etc) + + - Scegli 'local' se hai un solo sistema da monitorare. + + - Ulteriori informazioni su: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/it/messages/0x103-thanksforusing.txt b/etc/templates/it/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..5379654f1 --- /dev/null +++ b/etc/templates/it/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Grazie per aver scelto openarmor HIDS. + Per qualsiasi domanda, suggerimento o se hai trovato qualche bug, + contattaci all'indirizzo contact@theopenarmor.org o utlizza la nostra + mailinglist pubblica: + ( http://www.theopenarmor.org/en/mailing_lists.html ). + + Puoi trovare ulteriori informazioni all'indirizzo http://www.theopenarmor.org + + --- Premi ENTER per terminare --- + diff --git a/etc/templates/it/messages/0x104-client.txt b/etc/templates/it/messages/0x104-client.txt new file mode 100644 index 000000000..cfc5a6127 --- /dev/null +++ b/etc/templates/it/messages/0x104-client.txt @@ -0,0 +1,5 @@ + + - Come prima cosa devi aggiungere questo agent al server affinchè possano comunicare + tra di loro. Una volta fatto questo, potrai utilizzare il comando 'manage_agents' + per importare la chiave di autenticazione dal server. + diff --git a/etc/templates/it/messages/0x105-noboot.txt b/etc/templates/it/messages/0x105-noboot.txt new file mode 100644 index 000000000..239445ccb --- /dev/null +++ b/etc/templates/it/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - Non è stata effettuata alcuna modifica per avviare openarmor HIDS + in fase di boot. + Aggiungi la seguente riga al tuo script di init: + diff --git a/etc/templates/it/messages/0x106-logs.txt b/etc/templates/it/messages/0x106-logs.txt new file mode 100644 index 000000000..11d66a892 --- /dev/null +++ b/etc/templates/it/messages/0x106-logs.txt @@ -0,0 +1,8 @@ + - Se desideri monitorare qualsiasi altro file, modifica openarmor.conf + e aggiungi una nuova, specifica, sezione. + Per qualsiasi dubbio sulla configurazione visita il sito del progetto + all'indirizzo http://www.theopenarmor.org . + + + --- Premi ENTER per continuare --- + diff --git a/etc/templates/it/messages/0x107-ar.txt b/etc/templates/it/messages/0x107-ar.txt new file mode 100644 index 000000000..884bcfe6c --- /dev/null +++ b/etc/templates/it/messages/0x107-ar.txt @@ -0,0 +1,7 @@ + + 3.4- La risposta attiva consente di eseguire uno specifico comando in + conseguenza di un evento. Ad esempio, puoi bloccare un indrizzo IP o + disabilitare l'accesso ad uno specifico user. + Ulteriori informazioni su: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/it/messages/0x108-ar-enabled.txt b/etc/templates/it/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..8ac99cd24 --- /dev/null +++ b/etc/templates/it/messages/0x108-ar-enabled.txt @@ -0,0 +1,8 @@ + - Risposta attiva abilitata. + + - Per default, si possono abilitare le risposte di + tipo host-deny e firewall-drop. La prima aggiunge + un host a /etc/host.deny e la seconda blocca l'host + con iptables (Linux) o con ipfilter (Solaris, FreeBSD o NetBSD). + - Possono essere utilizzate per interrompere attacchi brute-force + a SSHD, portscans e diverse altre forme di attacchi. diff --git a/etc/templates/jp/errors/0x1-location.txt b/etc/templates/jp/errors/0x1-location.txt new file mode 100644 index 000000000..534241a6c --- /dev/null +++ b/etc/templates/jp/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + エラー 0x1. + このスクリプトは同じディレクトリからのみ実行できます. + スクリプトを実行させる前にディレクトリを変更してください. + そして,./install.sh として実行してください." + diff --git a/etc/templates/jp/errors/0x2-beroot.txt b/etc/templates/jp/errors/0x2-beroot.txt new file mode 100644 index 000000000..5012a67b8 --- /dev/null +++ b/etc/templates/jp/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + エラー 0x2. + このスクリプトはルート権限で動作させてください. + diff --git a/etc/templates/jp/errors/0x3-dependencies.txt b/etc/templates/jp/errors/0x3-dependencies.txt new file mode 100644 index 000000000..625c2ac9c --- /dev/null +++ b/etc/templates/jp/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + エラー 0x3. + インストールを続けるにはコンパイラ(gcc または cc 等)が + 必要です. + diff --git a/etc/templates/jp/errors/0x4-installtype.txt b/etc/templates/jp/errors/0x4-installtype.txt new file mode 100644 index 000000000..881612cff --- /dev/null +++ b/etc/templates/jp/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + エラー 0x4. + インストールに選んだ種類が間違っています. + agent,server あるいは local のみです. diff --git a/etc/templates/jp/errors/0x5-build.txt b/etc/templates/jp/errors/0x5-build.txt new file mode 100644 index 000000000..6683d6345 --- /dev/null +++ b/etc/templates/jp/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + エラー 0x5. + 構築エラー.インストールを完了できませんでした. + diff --git a/etc/templates/jp/language.txt b/etc/templates/jp/language.txt new file mode 100644 index 000000000..ad74c8a5f --- /dev/null +++ b/etc/templates/jp/language.txt @@ -0,0 +1 @@ + ** 日本語でインストールします.選択して下さい.[jp]. diff --git a/etc/templates/jp/messages.txt b/etc/templates/jp/messages.txt new file mode 100644 index 000000000..1cd7c1035 --- /dev/null +++ b/etc/templates/jp/messages.txt @@ -0,0 +1,115 @@ +# Configuration +yes="y" +no="n" +yesmatch="y" +nomatch="n" +agent="agent" +local="local" +server="server" +help="help" + + +# Global +moreinfo="詳細な情報は以下にあります: " +starting="openarmor HIDS を起動します" +systemis="システムは" +modifiedinit="Init script modified to start openarmor HIDS during boot." +modifiedinit="初期スクリプトはブート中に openarmor HIDS を起動するよう修正しました." +noboot="不明なシステムです.初期スクリプトは追加されません." + +# Part 1 +installscript="インストールスクリプト" +system="システム" +user="ユーザ" +host="ホスト" +hitanyorabort="続けるには ENTER を押してください.また,Ctrl-C で中止します." +whattoinstall="どの種類のインストールを選択しますか (server,agent,local または help)?" +serverchose="Server インストールを選択しました" +clientchose="Agent(client) インストールを選択しました" +localchose="Local インストールを選択しました" + +# Part 2 +settingupenv="インストール環境を設定しています" +wheretoinstall="Choose where to install the openarmor HIDS" +wheretoinstall="openarmor HIDS のインストール先を選択してください" +installat="インストール先を以下に作成します " +deletedir="インストール先のディレクトリが既に存在します.削除してよろしいですか?" + +# Part 3 +configuring="設定" +mailnotify="メール通知を希望しますか?" +nomail="メール通知を無効にしました" +whatsemail="メールアドレスは何ですか?" +yoursmtp="あなたの SMTP サーバを発見しました" +usesmtp="このサーバを使用しますか?" +usingsmtp="この SMTP サーバを使用します: " +whatsmtp="使用する SMTP サーバの ip/host は何ですか?" + +# Part 3.1/agent +serverip="openarmor HIDS サーバの IP アドレスは何ですか?" +serveraddr="openarmor HIDS サーバの IP/hostname アドレスは何ですか?" +addingip="サーバの IP を加えています" +addingname="サーバの hostname を加えています" + + +# Part 3.2 +runsyscheck="整合性検査を行うデーモンを実行させますか?" +nosyscheck="syscheck (整合性検査デーモン) は実行させません" +yessyscheck="syscheck (整合性検査デーモン) を実行させます" + +# Part 3.3 +runrootcheck="rootkit 検知エンジンを実行させますか?" +norootcheck="rootcheck (rootkit 検知) は実行させません" +yesrootcheck="rootcheck (rootkit 検知) を実行させます" + +# Part 3.4/server/local +enable_ar="アクティブレスポンスを有効にしますか?" +noactive="アクティブレスポンスを無効にしました" +nohosts="host-deny を無効にしました" +yeshosts="host-deny enabled (local) for levels >= 6" +yeshosts="local での levels >= に対する host-deny を有効にしました" +firewallar="firewall-drop レスポンスを有効にしますか?" +nofirewall="firewall-drop を無効にしました." +yesfirewall="local での levels >= 6 に対する firewall-drop を有効にしました" +defaultwhitelist="アクティブレスポンスでの初期ホワイトリスト:" +addwhite="ホワイトリストへ IP を追加しますか?" +ipswhite="IP を入力してください (スペース区切り): " + +# Part 3.5/server/local +syslog="Do you want to enable remote syslog (port 514 udp)?" +syslog="リモート syslog (port 514 udp) を有効にしますか?" +nosyslog="リモート syslog を無効にしました" +yessyslog="リモート syslog を有効にしました" + +# Part 3.4/3.5 +readlogs="以下のログを解析するための設定を準備しています:" + +# Part 5 +installing="システムをインストールします" +runningmake="Makefile を実行します" + + +# Final +configurationdone="設定が完全に終了しました" +tostart="openarmor HIDS を開始させます" +tostop="openarmor HIDS を停止させます" +configat="以下のファイルで設定についての確認と変更ができます" +addserveragent="エージェントを追加する前にアクセスするための認証が必要になります." +runma="エージェントを追加するか削除する際は 'manage_agents' を実行してください" +presskey="続けるには ENTER を押してください" + +# Update +wanttoupdate="既に openarmor がインストールされています.アップデートしますか?" +unabletoupdate="アップデート作業を行えません.新しくインストールする必要があります." +updatecompleted="アップデートは完了しました." +updatefailed="アップデートは失敗しました." +updaterules="ルールをアップデートしますか?" +updatingrules="ルールをアップデートしています" +notupdatingrules="ルールはアップデートしません." + + +# Pf support +pfenable="アクティブレスポンスを PF ファイヤーウォールで使用しますか?" +nopf="PF レスポンスを無効にしました." +pftablename="使用する PF テーブル名は?" +pfmessage="以下にあなたのルールを最初から追加してください." diff --git a/etc/templates/jp/messages/0x101-initial.txt b/etc/templates/jp/messages/0x101-initial.txt new file mode 100644 index 000000000..43eff9d6b --- /dev/null +++ b/etc/templates/jp/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + openarmor HIDS のインストール作業を始めます. + 事前に C コンパイラがシステムにインストールされてる必要があります. + diff --git a/etc/templates/jp/messages/0x102-installhelp.txt b/etc/templates/jp/messages/0x102-installhelp.txt new file mode 100644 index 000000000..bd517a1d6 --- /dev/null +++ b/etc/templates/jp/messages/0x102-installhelp.txt @@ -0,0 +1,28 @@ + + - 三種類のインストールオプションがあります.: server,agent または local. + + - 'server' を選択した場合,全てのログ解析,通知メールの作成, + 対応,遠隔の syslog 計算機と 'agents' が動作しているシステム + からのログ受信(トラフィックは暗号化されてサーバに送られます) + ができます. + + - 'agents' を選択した場合,計算機上のファイル(syslog,snort, + apache,等)を読みこみ,それらを解析のために暗号化してサーバ + に送ることができます. + + - 'local' を選択した場合,agents や外部の syslog デバイスから + 遠隔メッセージを受信することを除き, サーバの機能を全て使用 + できます. + + - log/analysis サーバを設定するなら 'server' を選択してください. + + - 他の計算機でログサーバを実行しており,解析のためにログをサーバに + 転送したいなら 'agent' を選択してください. + (ウェブサーバやデータベースサーバ等に適しています) + + - 単一システムを監視するためならば 'local' を選択してください. + + - 詳細な情報は以下のサイトから得られます: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/jp/messages/0x103-thanksforusing.txt b/etc/templates/jp/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..b2cebf351 --- /dev/null +++ b/etc/templates/jp/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + openarmor HIDS の使用に感謝します. + あなたが何らかの質問,提案したいときや,バグを発見したときは, + contact@theopenarmor.org まで連絡するか openarmor-list@theopenarmor.org にある + 我々の公開メーリングリストを使ってください. + (http://www.theopenarmor.org/main/support/). + + 詳細な情報は http://www.theopenarmor.org にあります. + + --- ENTER を押すと終了します (以下,詳細な情報が続きます).--- + diff --git a/etc/templates/jp/messages/0x104-client.txt b/etc/templates/jp/messages/0x104-client.txt new file mode 100644 index 000000000..6c206aa82 --- /dev/null +++ b/etc/templates/jp/messages/0x104-client.txt @@ -0,0 +1,5 @@ + + - 最初に,このエージェントをサーバに追加する必要があります. + それにより互いに通信が可能となります.その後,サーバから + の認証鍵を取り入れるために 'manage_agents' ツールを実行 + することができます. diff --git a/etc/templates/jp/messages/0x105-noboot.txt b/etc/templates/jp/messages/0x105-noboot.txt new file mode 100644 index 000000000..8f3e77600 --- /dev/null +++ b/etc/templates/jp/messages/0x105-noboot.txt @@ -0,0 +1,6 @@ + + - 起動中において,openarmor HIDS を開始し設定する動作が行われませんでした. + 以下のラインをあなたの初期スクリプトに加えてください: + + + diff --git a/etc/templates/jp/messages/0x106-logs.txt b/etc/templates/jp/messages/0x106-logs.txt new file mode 100644 index 000000000..fbf0888c6 --- /dev/null +++ b/etc/templates/jp/messages/0x106-logs.txt @@ -0,0 +1,7 @@ + - 他のファイルを監視したい場合は,openarmor.conf を変更し + 新しいエントリーを追加してください. + 設定に関するどんな質問にも我々の Web サイト http://www.theopenarmor.org + を訪れることで答えることができます. + + + --- 続けるには ENTER を押してください --- diff --git a/etc/templates/jp/messages/0x107-ar.txt b/etc/templates/jp/messages/0x107-ar.txt new file mode 100644 index 000000000..a217fde74 --- /dev/null +++ b/etc/templates/jp/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- アクティブレスポンスによりイベントが発生した際に特定の + コマンドを実行することができます. + 例えば,ある IP アドレスを遮断することや特定のユーザ + に対してアクセスを無効にすることができます. + 詳細な情報は以下にあります: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/jp/messages/0x108-ar-enabled.txt b/etc/templates/jp/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..0ef29ab5a --- /dev/null +++ b/etc/templates/jp/messages/0x108-ar-enabled.txt @@ -0,0 +1,12 @@ + - アクティブレスポンスを有効にしました. + + - デフォルトでは,host-deny と firewall-drop レスポンス + が有効化することができます.一つ目は /etc/hosts.deny + にホストを加えます.二つ目は iptable (linux) か + ipfilter (Solaris, FreeBSD または NetBSD) によりホストを + 遮断します. + + - SSHD への総当たりスキャン,ポートスキャンや他の何らかの + 攻撃手法を停止することに使うことができます. + また,例えば,snort のイベントに基づいてそれらを遮断する + こともできます. diff --git a/etc/templates/nl/errors/0x1-location.txt b/etc/templates/nl/errors/0x1-location.txt new file mode 100644 index 000000000..f25f9800f --- /dev/null +++ b/etc/templates/nl/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Fout 0x1. + Dit script kan enkel uit dezelfde map worden uitgevoerd. + Wijzig de map naar de scriptmap alvorens u de installatie uitvoert. + U dient het script zo aan te roepen ./install.sh ." + diff --git a/etc/templates/nl/errors/0x2-beroot.txt b/etc/templates/nl/errors/0x2-beroot.txt new file mode 100644 index 000000000..bed7fa9ed --- /dev/null +++ b/etc/templates/nl/errors/0x2-beroot.txt @@ -0,0 +1,5 @@ + + Fout 0x2. + Je moet administratie rechten bekeomen om dit script + uit te voeren. + diff --git a/etc/templates/nl/errors/0x3-dependencies.txt b/etc/templates/nl/errors/0x3-dependencies.txt new file mode 100644 index 000000000..821b66417 --- /dev/null +++ b/etc/templates/nl/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Fout 0x3. + U heeft een compiler (zoals gcc of cc) nodig om door + te kunnen gaan met de installatie. + diff --git a/etc/templates/nl/errors/0x4-installtype.txt b/etc/templates/nl/errors/0x4-installtype.txt new file mode 100644 index 000000000..3b0050781 --- /dev/null +++ b/etc/templates/nl/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Fout 0x4. + Onjuist installatie type. Het kan enkel agent, server of local zijn. + diff --git a/etc/templates/nl/errors/0x5-build.txt b/etc/templates/nl/errors/0x5-build.txt new file mode 100644 index 000000000..bf22e2275 --- /dev/null +++ b/etc/templates/nl/errors/0x5-build.txt @@ -0,0 +1,5 @@ + + Fout 0x5. + Tijdens het bouwen trad er een fout op. Kan de installatie niet + voortzetten. + diff --git a/etc/templates/nl/language.txt b/etc/templates/nl/language.txt new file mode 100644 index 000000000..12f9f15a6 --- /dev/null +++ b/etc/templates/nl/language.txt @@ -0,0 +1 @@ + ** Voor installatie in het Nederlands, kies [nl]. diff --git a/etc/templates/nl/messages.txt b/etc/templates/nl/messages.txt new file mode 100644 index 000000000..2e787909b --- /dev/null +++ b/etc/templates/nl/messages.txt @@ -0,0 +1,108 @@ +# Configuration +yes="j" +no="n" +yesmatch="j" +nomatch="n" +agent="agent" +local="local" +server="server" +help="help" + +# Global +moreinfo="Meer informatie op: " +starting="Bezig met starten van openarmor HIDS" +systemis="Systeem is" +modifiedinit="Init script aangepast om openarmor HIDS te laden tijdens opstarten." +noboot="Onbekend systeem. Geen init script toegevoegd." + +# Part 1 +installscript="Installatie Script" +system="Systeem" +user="Gebruiker" +host="Host" +hitanyorabort="Druk op ENTER om door te gaan of Ctrl-C om af te breken." +whattoinstall="Wat voor soort installatie wilt u doen (server, agent, local of help)?" +serverchose="Gekozen voor server installatie" +clientchose="Gekozen voor agent(client) installatie" +localchose="Gekozen voor lokale installatie" + +# Part 2 +settingupenv="Opzetten van installatie omgeving" +wheretoinstall="Waar wilt u openarmor HIDS installaren" +installat="Installatie word geplaatst in " +deletedir="De installatie map bestaat reeds. Zal ik deze verwijderen?" + +# Part 3 +configuring="Configureren van" +mailnotify="Wilt u email notificatie inschakelen?" +nomail="Email notificatie uitgeschakeld" +whatsemail="Wat is uw emailadres?" +yoursmtp="We hebben uw SMTP server gevonden als: " +usesmtp="Wilt u deze gebruiken ?" +usingsmtp="Gebruik maken van SMTP server: " +whatsmtp="Wat is uw SMTP server ip/host?" + +# Part 3.1/agent +serverip="Wat is het IP adres van uw openarmor HIDS host?" +serveraddr="Wat is het IP adres/host van uw openarmor HIDS host?" +addingip="Toevoegen van server IP" +addingname="Toevoegen van server host" + + +# Part 3.2 +runsyscheck="Wilt u de integriteits controle proces?" +nosyscheck="Geen syscheck (integriteits controle proces)" +yessyscheck="Starten van syscheck (integriteits controle proces)" + +# Part 3.3 +runrootcheck="Wilt u de rootkit detectie engine?" +norootcheck="Geen rootcheck (rootkit detectie)" +yesrootcheck="Starten van rootcheck (rootkit detectie)" + +# Part 3.4/server/local +enable_ar="Wilt u actief handelen?" +noactive="Actief handelen uitgeschakeld" +nohosts="host-deny uitgeschakeld" +yeshosts="host-deny ingeschakeld (lokaal) voor niveaus >= 6" +firewallar="Wilt u de firewall-drop handeling inschakelen?" +nofirewall="firewall-drop uitgeschakeld." +yesfirewall="firewall-drop ingeschakeld (lokaal) voor niveaus >= 6" +defaultwhitelist="Standaard witte lijst voor actief handelen:" +addwhite="Wilt u meer IPs toevoegen aan de witte lijst?" +ipswhite="IPs (spatie gescheiden): " + +# Part 3.5/server/local +syslog="Wilt u externe systeem logging (syslog) inschakelen (poort 514 udp)?" +nosyslog="Externe systeem logging uitgeschakeld" +yessyslog="Externe systeem logging ingeschakeld" + +# Part 3.4/3.5 +readlogs="Systeem instellen om de volgende logbestanden te controleren:" + +# Part 5 +installing="Bezig met installeren van het systeem" +runningmake="Uitvoeren van Makefile" + +# Final +configurationdone="Configuratie is succesvol afgesloten" +tostart="Om openarmor HIDS te starten" +tostop="Om openarmor HIDS te stoppen" +configat="De configuratie kan worden bekeken en gewijzigd in" +addserveragent="Om verbinding te maken tussen agent en server, moet je alle agenten aan de server toevoegen." +runma="Voer 'manage_agents' uit om ze toe te voegen of te verwijderen" +presskey="Druk op ENTER om door te gaan" + +# Update +wanttoupdate="U heeft openarmor reeds geinstalleerd. Wilt u actualiseren?" +unabletoupdate="Kan geen actualisatie uitvoeren. Een volledig nieuwe installatie is vereist." +updatecompleted="Actualisatie succesvol uitgevoerd." +updatefailed="Actualisatie is gefaald." +updaterules="Wilt u de regels actualiseren?" +updatingrules="Actualiseren van regels." +notupdatingrules="Regels worden niet geactualiseerd." + +# Pf support +pfenable="Wilt u de PF firewall gebruiken bij actief handelen?" +nopf="PF respons is uitgeschakeld." +pftablename="Naam van de PF tabel om te gebruiken?" +pfmessage="Voeg de volgende regels toe aan het begin van uw PF regels" diff --git a/etc/templates/nl/messages/0x101-initial.txt b/etc/templates/nl/messages/0x101-initial.txt new file mode 100644 index 000000000..841c9f37e --- /dev/null +++ b/etc/templates/nl/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + U staat op het punt om het installatie proces te starten van openarmor HIDS. + U heeft een C compiler nodig voorgeinstalleerd op uw systeem. + diff --git a/etc/templates/nl/messages/0x102-installhelp.txt b/etc/templates/nl/messages/0x102-installhelp.txt new file mode 100644 index 000000000..48b5faa57 --- /dev/null +++ b/etc/templates/nl/messages/0x102-installhelp.txt @@ -0,0 +1,31 @@ + + - U heeft 3 installatie typen: server, agent or local. + + - Als u kiest voor 'server', kunt u alle logs analyseren, + email notificaties en handelingen aanmaken en tevens + externe systeem logs ontvangen van externe machines + en systemen met 'agents' (waarweg gegevens beveiligd + worden verzonden). + + - Als u kiest voor 'agent'(client), kunt u alle lokale + bestanden lezen (van syslog, snort, apache, etc) en + deze (beveiligd) doorsturen naar de server voor + analyse. + + - Als u kiest voor 'local', kunt u alles doen wat de + server kan, behalve het ontvangen van externe berichten + vanaf agenten of externe systeemloggende apparaten. + + - Kies voor 'server' als u een log/analyze server opzet. + + - Kies voor 'agent' als u een andere machine als log server + heeft opgezet en hier naar toe voor analyze wilt doorsturen. + (ideaal voor webservers en database servers) + + - Kies voor 'local' als u een enkel systeem in de gaten + wilt houden. + + - Meer informatie vindt u op: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/nl/messages/0x103-thanksforusing.txt b/etc/templates/nl/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..0183ab3a3 --- /dev/null +++ b/etc/templates/nl/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Bedankt voor het gebruiken van openarmor HIDS. + Heeft u een vraag of suggestie of een andere vorm van opmerking, + neem contact met ons op via contact@theopenarmor.org of gebruik de mailinglijst + openarmor-list@theopenarmor.org + ( http://www.theopenarmor.org/main/support/ ). + + Meer informatie vindt u op http://www.theopenarmor.org + + --- Druk op ENTER om te finaliseren (wellicht meer informatie hieronder). --- + diff --git a/etc/templates/nl/messages/0x104-client.txt b/etc/templates/nl/messages/0x104-client.txt new file mode 100644 index 000000000..c1662638c --- /dev/null +++ b/etc/templates/nl/messages/0x104-client.txt @@ -0,0 +1,7 @@ + + - U dient eerst deze agent aan de server toe te voegen + zodat ze met elkaar kunnen communiceren. Als u dit + gedaan heeft dan kunt u de 'manage_agents' tool ge- + bruiken om de authenticatiesleutel te importeren + vanaf de server. + diff --git a/etc/templates/nl/messages/0x105-noboot.txt b/etc/templates/nl/messages/0x105-noboot.txt new file mode 100644 index 000000000..d5b923cbb --- /dev/null +++ b/etc/templates/nl/messages/0x105-noboot.txt @@ -0,0 +1,4 @@ + + - Er is geen actie ondernomen om een opstart script te maken voor + openarmor HIDS. U dient de volgede regel toe te voegen aan uw initscript: + diff --git a/etc/templates/nl/messages/0x106-logs.txt b/etc/templates/nl/messages/0x106-logs.txt new file mode 100644 index 000000000..85fc7ea6f --- /dev/null +++ b/etc/templates/nl/messages/0x106-logs.txt @@ -0,0 +1,10 @@ + - Als u een ander bestand in de gaten wilt houden, + kunt u het bestand openarmor.conf wijzigen door een + nieuwe localfile in te brengen. + Vragen over het configuratie bestand kunnen worden + beantwoord door ons online te bezoeken op + http://www.theopenarmor.org . + + + --- Druk op ENTER om door te gaan --- + diff --git a/etc/templates/nl/messages/0x107-ar.txt b/etc/templates/nl/messages/0x107-ar.txt new file mode 100644 index 000000000..b72cb4dcb --- /dev/null +++ b/etc/templates/nl/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- Actief handelen stelt u in staat om een specifiek + commando uit te voeren op basis van de ontvangen + events. Bijvoorbeeld, u kunt een IP adres blokkeren + of de toegang ontzeggen voor een bepaalde gebruiker. + Meer informatie vindt u op: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/nl/messages/0x108-ar-enabled.txt b/etc/templates/nl/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..98d462c25 --- /dev/null +++ b/etc/templates/nl/messages/0x108-ar-enabled.txt @@ -0,0 +1,12 @@ + - Actief handelen is ingeschakeld. + + - Als standaard, kunnen we de host-deny en + firewall-drop handelingen inschakelen. De + eerste voegt een host toe aan /etc/hosts.deny + en de tweede zal de host blokkeren op iptables + (bij linux) of ipfilter (bij Solaris, FreeBSD + of NetBSD). + - Ze kunnen gebruikt worden om SSHD brute force scans, + portscans of andere vormen van aanvallen te stoppen. + U kunt deze ook gebruiken om blokkeren op basis van + bijvoorbeeld snort events. diff --git a/etc/templates/pl/errors/0x1-location.txt b/etc/templates/pl/errors/0x1-location.txt new file mode 100644 index 000000000..6ab6421b8 --- /dev/null +++ b/etc/templates/pl/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Błąd 0x1. + Skrypt może być tylko uruchamiany ze swojego katalogu. + Przejdź do katalogu w którym jest skrypt. + Następnie uruchom poprzez: ./install.sh ." + diff --git a/etc/templates/pl/errors/0x2-beroot.txt b/etc/templates/pl/errors/0x2-beroot.txt new file mode 100644 index 000000000..73375481e --- /dev/null +++ b/etc/templates/pl/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Błąd 0x2. + Skrypt należy uruchamiać na prawach root'a. + diff --git a/etc/templates/pl/errors/0x3-dependencies.txt b/etc/templates/pl/errors/0x3-dependencies.txt new file mode 100644 index 000000000..e3c3afdf2 --- /dev/null +++ b/etc/templates/pl/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Błąd 0x3. + Potrzebujesz kompilatora (np. gcc lub cc) aby kontynuować + instalacje. + diff --git a/etc/templates/pl/errors/0x4-installtype.txt b/etc/templates/pl/errors/0x4-installtype.txt new file mode 100644 index 000000000..af86f0ef1 --- /dev/null +++ b/etc/templates/pl/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Błąd 0x4. + Niewłaściwy typ instalacji. Wybierz spośród: agent, serwer, lokalna. + diff --git a/etc/templates/pl/errors/0x5-build.txt b/etc/templates/pl/errors/0x5-build.txt new file mode 100644 index 000000000..fb6b313fb --- /dev/null +++ b/etc/templates/pl/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Błąd 0x5. + Błąd kompilacji. Nie można zakończyć instalacji. + diff --git a/etc/templates/pl/language.txt b/etc/templates/pl/language.txt new file mode 100644 index 000000000..4203bc679 --- /dev/null +++ b/etc/templates/pl/language.txt @@ -0,0 +1 @@ + ** Aby instalować w języku Polskim, wybierz [pl]. diff --git a/etc/templates/pl/messages.txt b/etc/templates/pl/messages.txt new file mode 100644 index 000000000..6166d0ff2 --- /dev/null +++ b/etc/templates/pl/messages.txt @@ -0,0 +1,109 @@ +# Konfiguracja +yes="y" +no="n" +yesmatch="y" +nomatch="n" +agent="agent" +local="lokalnie" +server="serwer" +help="pomoc" + +# Ogólne +moreinfo="Więcej informacji na: " +starting="Rozpoczynam openarmor HIDS" +systemis="System " +modifiedinit="Init skrypt zmodyfikowany do uruchomiania openarmor HIDS podczas bootowania." +noboot="Nieznany system. Skrypt init nie został dodany." + +# Część 1 +installscript="Skrypt instalacyjny" +system="System" +user="Użytkownik" +host="Host" +hitanyorabort="Wciśnij ENTER aby kontynuować lub Ctrl-C aby przerwać." +whattoinstall="Wybierz rodzaj instalacji (serwer, agent, lokalnie or pomoc)?" +serverchose="Wybrana instalacja: serwer" +clientchose="Wybrana instalacja: agent(klient)" +localchose="Wybrana instalacja: lokalnie" + +# Część 2 +settingupenv="Ustawianie środowiska instalacyjnego" +wheretoinstall="Wybierz katalog w którym zainstalować openarmor HIDS" +installat="openarmor HIDS zostanie zainstalowane w :" +deletedir="Wybrany katalog istnieje, skasować go?" + +# Część 3 +configuring="Konfiguracja " +mailnotify="Czy chcesz powiadomienie na e-mail?" +nomail="Powiadomienie e-mail wyłączone" +whatsemail="Podaj e-mail adres?" +yoursmtp="Znaleziony SMTP serwer: " +usesmtp="Czy chcesz go użyć?" +usingsmtp="Używam SMTP serwer: " +whatsmtp="Podaj SMTP serwer (ip/host)?" + +# Część 3.1/agent +serverip="Podaj adres IP serwera openarmor HIDS." +serveraddr="Podaj adres IP (hostname) serwera openarmor HIDS." +addingip="Dodaje IP serwera" +addingname="Dodaje hostname serwera" + + +# Część 3.2 +runsyscheck="Czy chcesz aby demon sprawdzania integralności systemu (syscheck) był uruchomiony?" +nosyscheck="Nie uruchomiony syscheck (demon sprawdzania integralności systemu)" +yessyscheck="Uruchomiony syscheck (demon sprawdzania integralności systemu)" + +# Część 3.3 +runrootcheck="Czy chcesz aby system detekcji rootkit'ów (rootcheck) był uruchomiony?" +norootcheck="Nie uruchomiony rootcheck (system detekcji rootkit'ów)" +yesrootcheck="Uruchomiony rootcheck (system detekcji rootkit'ów)" + +# Część 3.4/server/local +enable_ar="Czy chcesz uaktywnić aktywną ochrone?" +noactive="Aktywna ochrona wyłączona" +nohosts="host-deny wyłączone" +yeshosts="host-deny włączone (local) dla poziomów >= 6" +firewallar="Czy chcesz uaktywnić ochrone firewall-drop?" +nofirewall="firewall-drop wyłączone." +yesfirewall="firewall-drop włączone (local) dla poziomów >= 6" +defaultwhitelist="Domyślna biała lista dla aktywnej ochrony:" +addwhite="Czy chcesz dodać więcej adresów IP do białej listy?" +ipswhite="Adresy IP (część oddzielona): " + +# Część 3.5/server/local +syslog="Czy chcesz uaktywnić zdalnego syslog'a (port 514 udp)?" +nosyslog="Zdalny syslog wyłączony" +yessyslog="Zdalny syslog włączony" + +# Część 3.4/3.5 +readlogs="Ustawianie konfiguracji do analizy następujących logów:" + +# Część 5 +installing="Instaluje system" +runningmake="Uruchomiono Makefile" + +# Finał +configurationdone="Konfiguracja zakończona pomyślnie" +tostart="Aby wystartować openarmor HIDS" +tostop="Aby zatrzymać openarmor HIDS" +configat="Konfiguracja może być wyświetlona lub zmodyfikowana w" +addserveragent="Powinieneś dodać agent(a/ów) przed ich autoryzacją dostępu." +runma="Uruchom 'manage_agents' aby je dodać lub usunąć" +presskey="Wciśnij ENTER aby kontynuować" + +# Update +wanttoupdate="Masz już zainstalowany openarmor. Czy chcesz dokonać aktualizacji?" +unabletoupdate="Nie można dokonać aktualizacji. Pełna nowa instalacja jest konieczna." +updatecompleted="Aktualizacja ukończona." +updatefailed="Aktualizacja ukończona niepowodzeniem." +updaterules="Czy chcesz zaktualizować reguły?" +updatingrules="Aktualizacja reguł." +notupdatingrules="Bez aktualizacji reguł." + +# Wsparcie dla Pf +pfenable="Chcesz uywa firewall'a PF jako aktywnej ochrony?" +nopf="ochrona PF wyczona." +pftablename="Podaj nazwe tabeli PF?" +pfmessage="Dodaj nastpujce linie na pocztku Twoich regu" + diff --git a/etc/templates/pl/messages/0x101-initial.txt b/etc/templates/pl/messages/0x101-initial.txt new file mode 100644 index 000000000..223e2dc0c --- /dev/null +++ b/etc/templates/pl/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Rozpoczynasz proces instalacji programu openarmor HIDS. + Aby kontynuować musisz mieć zainstalowany kompilator C. + diff --git a/etc/templates/pl/messages/0x102-installhelp.txt b/etc/templates/pl/messages/0x102-installhelp.txt new file mode 100644 index 000000000..4098932a6 --- /dev/null +++ b/etc/templates/pl/messages/0x102-installhelp.txt @@ -0,0 +1,30 @@ + + - Masz do wyboru trzy metody instalacji: serwer, agent oraz lokalna. + + - Jeśli wybierzesz 'serwer', bęziesz miał możliwość analizy + wszystkich logów, tworzenia powiadomienia e-mail, aktywnej + ochrony oraz także otrzymywania logów ze zdalnych maszyn z + syslog-iem i systemów działajcych jako 'agent' (skąd ruch + jest szyfrowany do serwera) + + - Jeśli wybierzesz 'agent'(klient), będziesz miał możliwość + czytania lokalnych plików (z syslog, apache, snort itp) + oraz przekazywania ich (zaszyfrowanych) do serwera w celu + analizy. + + - Jeśli wybierzesz 'lokalna', będziesz wstanie wykonywać + wszystkie operacje serwera za wyjątkiem odbierania zdalnych + wiadomości od klientów oraz zewnętrzych syslog-ów. + + - Wybierz 'serwer' jeśli chcesz ustawić serwer analizy logów. + + - Wybierz 'agent' jeśli masz inną maszynę działającą jako serwer i + chcesz przekazywać do niego logi w celu analizy. + (idealny dla serwerów http, bazodanowych, itp) + + - Wybierz 'lokalna' jeśli masz tylko jeden system do monitorowania. + + - Więcej informacji na: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/pl/messages/0x103-thanksforusing.txt b/etc/templates/pl/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..b61273ec8 --- /dev/null +++ b/etc/templates/pl/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + + Dziękujemy za użycie openarmor HIDS. + Jeśli masz jakieś pytania, propozycje lub znalazłeś jakiś błąd, + skontaktuj się z nami poprzez contact@theopenarmor.org lub publiczną + listę mailingową openarmor-list@theopenarmor.org + ( http://www.theopenarmor.org/main/support/ ). + + Więcej informacji można znaleźć na http://www.theopenarmor.org + + --- Wciśnij ENTER aby zakończyć (więcej informacji poniżej?). --- + diff --git a/etc/templates/pl/messages/0x104-client.txt b/etc/templates/pl/messages/0x104-client.txt new file mode 100644 index 000000000..d0f6808d4 --- /dev/null +++ b/etc/templates/pl/messages/0x104-client.txt @@ -0,0 +1,6 @@ + + - Najpierw musisz dodać tego agenta do serwera aby + umożliwić komunikację między nimi. Jeśli zakończyłeś + możesz uruchomić narzędzie 'manage_agents' aby + zaimportować klucz autoryzacyjny z serwera. + diff --git a/etc/templates/pl/messages/0x105-noboot.txt b/etc/templates/pl/messages/0x105-noboot.txt new file mode 100644 index 000000000..48bb636c9 --- /dev/null +++ b/etc/templates/pl/messages/0x105-noboot.txt @@ -0,0 +1,5 @@ + + - Nie została podjęta żadna akcja aby skonfigurować openarmor HIDS + do startowania podczas bootowania. + Dodaj następującą linię do skryptu init: + diff --git a/etc/templates/pl/messages/0x106-logs.txt b/etc/templates/pl/messages/0x106-logs.txt new file mode 100644 index 000000000..2d5b88842 --- /dev/null +++ b/etc/templates/pl/messages/0x106-logs.txt @@ -0,0 +1,8 @@ + - Jeśli chcesz monitorować inne pliki, poprostu + zmień openarmor.conf oraz dodaj nowy wpis localfile. + Wszystkie wyjaśnienia odnośnie konfiguracji + znajdziesz na http://www.theopenarmor.org . + + + --- Wciśnij ENTER aby kontynuować --- + diff --git a/etc/templates/pl/messages/0x107-ar.txt b/etc/templates/pl/messages/0x107-ar.txt new file mode 100644 index 000000000..7d804bb83 --- /dev/null +++ b/etc/templates/pl/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- Aktywna ochrona pozwala na wykonywanie określonych + komend w zależności od otrzymanego sygnału. Np. + możesz zablokować adres IP lub dostęp dla wybranego + użytkownika. + Więcej informacji na: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/pl/messages/0x108-ar-enabled.txt b/etc/templates/pl/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..2af7b60a7 --- /dev/null +++ b/etc/templates/pl/messages/0x108-ar-enabled.txt @@ -0,0 +1,11 @@ + - Aktywna ochrona włączona. + + - Domyślnie, możemy włączyć ochronę host-deny oraz + firewall-drop. Pierwsze doda hosta do listy + /etc/hosts.deny, a drugie zablokuje hosta na + poziomie iptables (dla linuxa) lub ipfilter + (dla Solaris, FreeBSD oraz NetBSD). + - Przedstawione metody mogą zatrzymać ataki brute + force na ssh, skanowanie portów oraz pare innych. + Możesz również na przykład dodać blokowanie + korzystając ze zdarzeń snort'a. diff --git a/etc/templates/ru/errors/0x1-location.txt b/etc/templates/ru/errors/0x1-location.txt new file mode 100644 index 000000000..ff335b721 --- /dev/null +++ b/etc/templates/ru/errors/0x1-location.txt @@ -0,0 +1,4 @@ + Ошибка 0x1. Этот скрипт может быть запущен только из того же каталога + Сделайте каталог где находится скрипт текущей перед его зпуском + Вы должны запустить скрипт командой ./install.sh + diff --git a/etc/templates/ru/errors/0x2-beroot.txt b/etc/templates/ru/errors/0x2-beroot.txt new file mode 100644 index 000000000..95ba923bc --- /dev/null +++ b/etc/templates/ru/errors/0x2-beroot.txt @@ -0,0 +1 @@ + Ошибка 0x2 .Вы должны иметь права root чтобы воспользоваться этим скриптом diff --git a/etc/templates/ru/errors/0x3-dependencies.txt b/etc/templates/ru/errors/0x3-dependencies.txt new file mode 100644 index 000000000..861e52e51 --- /dev/null +++ b/etc/templates/ru/errors/0x3-dependencies.txt @@ -0,0 +1,2 @@ + Ошибка 0x3. Вам нужен компиллятор (например gcc или cc) чтобы продолжить + далее. diff --git a/etc/templates/ru/errors/0x4-installtype.txt b/etc/templates/ru/errors/0x4-installtype.txt new file mode 100644 index 000000000..b9ca9812c --- /dev/null +++ b/etc/templates/ru/errors/0x4-installtype.txt @@ -0,0 +1,2 @@ +Ошибка 0x4. Неправильный тип установки . Он должен быть :агент,сервер или локальный. + diff --git a/etc/templates/ru/errors/0x5-build.txt b/etc/templates/ru/errors/0x5-build.txt new file mode 100644 index 000000000..1638762da --- /dev/null +++ b/etc/templates/ru/errors/0x5-build.txt @@ -0,0 +1,2 @@ + Ошибка 0x5 .Ошибка компиляции. Невозможно завершить установку. + diff --git a/etc/templates/ru/language.txt b/etc/templates/ru/language.txt new file mode 100644 index 000000000..da6541462 --- /dev/null +++ b/etc/templates/ru/language.txt @@ -0,0 +1 @@ + ** Для инструкций по установке на русском ,введите [ru]. diff --git a/etc/templates/ru/messages.txt b/etc/templates/ru/messages.txt new file mode 100644 index 000000000..8e0f65b35 --- /dev/null +++ b/etc/templates/ru/messages.txt @@ -0,0 +1,109 @@ +# Configuration +yes="д" +no="н" +yesmatch="д" +nomatch="н" +agent="агент" +local="локальный" +server="сервер" +help="помощь" + +# Global +moreinfo="Дополнительная информация: " +starting="Запуск openarmor HIDS" +systemis="Система" +modifiedinit="Init скрипт модифицирован чтобы програма openarmor HIDS запускалась при перезагрузке компьютера." +noboot="Система неизвестна. Никаких скриптов начала запуска не добавлено." + +# Part 1 +installscript="Скрипт установки программы" +system="Система" +user="Пользователь" +host="Хост" +hitanyorabort="Нажмите Ввод (ENTER) для продолжения или Ctrl-C для выхода." +whattoinstall="Какой тип установки Вы выбираете (сервер,агент,локальный или помощь)?" +serverchose="Выбран тип установки сервер" +clientchose="Выбран тип установки агент (клиент)" +localchose="Выбран локальный тип утановки" + +# Part 2 +settingupenv="Производится конфигурация параметров установки" +wheretoinstall="Укажите куда установить openarmor HIDS" +installat="Программа будет установлена в " +deletedir="Указанный каталог уже существует. Удалить его?" + +# Part 3 +configuring="Конфигурация" +mailnotify="Активировать систему уведомления по электронной почте?" +nomail="Оповещение по электронной почте отменено" +whatsemail="Укажите адрес электронной почты:" +yoursmtp="Ваш сервер SMTP (для отправки электронной почты) определён как" +usesmtp="Хотите использовать его?" +usingsmtp="Испльзуется SMTP сервер: " +whatsmtp="Каков Ваш SMTP сервер ip/host?" + +# Part 3.1/agent +serverip="Какой IP адрес у Вашего openarmor HIDS сервера?" +serveraddr="Какой IP адрес (Hostname) у Вашего openarmor HIDS сервера?" +addingip="Добавляется IP адрес сервера" +addingname="Добавляется IP (host) адрес сервера" + + +# Part 3.2 +runsyscheck="Запустить сервис проверки целостности системы?" +nosyscheck="syscheck (сервис проверки целостности системы) не запущен" +yessyscheck="Запускается syscheck (сервис проверки целостности системы)" + +# Part 3.3 +runrootcheck="Активировать сервис обнаружения руткитов?" +norootcheck="Сервис обнаружения руткитов (rootcheck) не запущен " +yesrootcheck="Запускается rootcheck (обнаружение руткитов)" + +# Part 3.4/server/local +enable_ar="Включить систему активного реагирования?" +noactive="Система активного реагирования отключена" +nohosts="Блокирование хостов отключено " +yeshosts="Блокирование хостов включено (локально) для уровня >= 6" +firewallar="Включить блокирование файерволом?" +nofirewall="Блокирование файерволом отключено." +yesfirewall="Блокирование файерволом включено (локально) для уровня >= 6" +defaultwhitelist="Список разрешённых адресов по умолчанию для активного реагирования:" +addwhite="Вы хотите добавить ещё адресов IP в список разрешённых?" +ipswhite="Адреса IP (разделяйте пробелом): " + +# Part 3.5/server/local +syslog="Активировать сохранение логов на удаленном сервере syslog (порт 514 udp)?" +nosyslog="Удалённое сохранение логов отменено" +yessyslog="Удалённое сохранение логов включено" + +# Part 3.4/3.5 +readlogs="Устанавливается конфигурация для анализа следующих логов" + +# Part 5 +installing="Производится установка" +runningmake="Исполняется Makefile" + +# Final +configurationdone="Конфигурация произведена успешно" +tostart="Запустить openarmor HIDS" +tostop="Завершить работу openarmor HIDS" +configat="Вы можете прочитать и отредактировать конфигурацию здесь" +addserveragent="Вы должны добавить агентов прежде чем они получат права доступа" +runma="Запустите 'manage_agents' чтобы добавить или удалить их" +presskey="Нажмите Ввод (ENTER) чтобы продолжить" + +# Update +wanttoupdate="openarmor уже установлен на этой машине. Хотите ли Вы обновить его?" +unabletoupdate="Невозможно произвести обновление. Потребуется полная установка заново" +updatecompleted="Обновление завершено успешно." +updatefailed="Произошел сбой и обновление не произведено ." +updaterules="Вы хотите обновить правила?" +updatingrules="Идет обновление правил ." +notupdatingrules="Обновление правил не производится ." + + +# Pf support +pfenable="Хотите ли Вы использовать PF файервол в активном реагировании?" +nopf="PF активное реагирование отключено" +pftablename="Имя таблицы PF ?" +pfmessage="Добавьте следующие строки в начало ваших правил" diff --git a/etc/templates/ru/messages/0x101-initial.txt b/etc/templates/ru/messages/0x101-initial.txt new file mode 100644 index 000000000..b9d2af722 --- /dev/null +++ b/etc/templates/ru/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + +Вы готовы начать процесс установки openarmor HIDS. Для следующего шага на Вашей +системе должен уже быть установлен компиллятор языка С. + diff --git a/etc/templates/ru/messages/0x102-installhelp.txt b/etc/templates/ru/messages/0x102-installhelp.txt new file mode 100644 index 000000000..698924165 --- /dev/null +++ b/etc/templates/ru/messages/0x102-installhelp.txt @@ -0,0 +1,17 @@ + - Есть 3 варианта установки: сервер,агент или локальный. + + - Если выбрать "сервер", Вы сможете анализировать логи, создавать уведомления + по e-mail и ответные действия, а также получать логи от удаленных syslog + серверов и машин с установленными агентами (откуда все данные посылаются +зашифрованными) .Если выбрать "агент" (клиент) Вы сможете читать локальные + файлы (от syslog, snort, apache, и так далее) и пересылать их (зашифрованным +и) на сервер для анализа. Если выбрать локальный то Вы сможете делать всё что + вариант "сервер" позволяет делать кроме принимать сообщения от агентлв на +удалённых машинах или внешних устройств syslog . + - Выберите "сервер" если хотите установить сервер обработки логов/анализа. + - Выберите "агент" если другая машина будет сервером обрабатывающим логи и туда + устанавливаемый агент будет посылать свои логи (идеально для веб серверов, + серверов баз данных ). + - Выберите "локальный" если у Вас всего лишь одна система . Более подробно +можно прочитать здесь: http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + diff --git a/etc/templates/ru/messages/0x103-thanksforusing.txt b/etc/templates/ru/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..197e48445 --- /dev/null +++ b/etc/templates/ru/messages/0x103-thanksforusing.txt @@ -0,0 +1,8 @@ + Спасибо что воспользовались openarmor HIDS . + Со всеми вопросами замечаниями или багами пожалуйста обращайтесь на + contact@theopenarmor.org или в свободно доступную почтовую рассылку openarmor-list@theopenarmor.org + ( http://www.theopenarmor.org/main/support/ ). + + Дополнительная информация доступна тут: http://www.theopenarmor.org + + --- Нажмите Ввод для завершения (возможна дополнительная информация далее). diff --git a/etc/templates/ru/messages/0x104-client.txt b/etc/templates/ru/messages/0x104-client.txt new file mode 100644 index 000000000..53632ac83 --- /dev/null +++ b/etc/templates/ru/messages/0x104-client.txt @@ -0,0 +1,4 @@ + Сначала Вы должны добавить этого агента на +сервере, чтобы они смогли обмениваться информацией друг с +другом. После этого Вы можете ,командой 'manage_agents', +импортировать ключ идентификации с сервера. diff --git a/etc/templates/ru/messages/0x105-noboot.txt b/etc/templates/ru/messages/0x105-noboot.txt new file mode 100644 index 000000000..502c73d7a --- /dev/null +++ b/etc/templates/ru/messages/0x105-noboot.txt @@ -0,0 +1,4 @@ + - Никаких изменений с целью запускать openarmor HIDS при перезагрузке системы +в конфигурации произведено не было. + Добавьте следующую строку в скрипт init: + diff --git a/etc/templates/ru/messages/0x106-logs.txt b/etc/templates/ru/messages/0x106-logs.txt new file mode 100644 index 000000000..fd0071727 --- /dev/null +++ b/etc/templates/ru/messages/0x106-logs.txt @@ -0,0 +1,4 @@ +- Если Вы хотите отслеживать любой другой файл, просто + измените openarmor.conf и добавьте новое значение в localfile. + Любые ответы по конфигурации могут быть найдены на сайте + http://www.theopenarmor.org diff --git a/etc/templates/ru/messages/0x107-ar.txt b/etc/templates/ru/messages/0x107-ar.txt new file mode 100644 index 000000000..2e03e69eb --- /dev/null +++ b/etc/templates/ru/messages/0x107-ar.txt @@ -0,0 +1,4 @@ + 3.4- Активное реагирование позволяет Вам выполнить выбранную команду в +зависимости от полученного события. Например, Вы можете блокировать адрес IP +или отказать в доступе определённому пользователю. Дополнительная информация + на сайте: http://www.theopenarmor.org/docs/docs/manual/ar/index.html diff --git a/etc/templates/ru/messages/0x108-ar-enabled.txt b/etc/templates/ru/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..c0af4d550 --- /dev/null +++ b/etc/templates/ru/messages/0x108-ar-enabled.txt @@ -0,0 +1,8 @@ +- Активное реагирование включено. + - По умолчанию, мы можем задействовать host-deny и firewall-drop ответные + реакции. Первая добавит хост в файл /etc/hosts.deny , а вторая заблокирует + хост через iptables (если Линукс) или через ipfilter (если Solaris, + FreeBSD или NetBSD). + - Они могут быть полезны для остановки сканирования методом перебора, + а также сканирования портов и некоторые другие формы атак. Также можно + добавить их для блокирования в связке с событиями snort. diff --git a/etc/templates/sr/errors/0x1-location.txt b/etc/templates/sr/errors/0x1-location.txt new file mode 100644 index 000000000..f60899d26 --- /dev/null +++ b/etc/templates/sr/errors/0x1-location.txt @@ -0,0 +1,5 @@ +Greška 0x1. +Ovaj skript može biti izveden jedino iz istog direktorijuma. +Prebaci direktorij tamo gde je ovaj skript pre nego što ga pustiš. +Moraš ga pustiti kao ./install.sh ." + diff --git a/etc/templates/sr/errors/0x2-beroot.txt b/etc/templates/sr/errors/0x2-beroot.txt new file mode 100644 index 000000000..06ed26529 --- /dev/null +++ b/etc/templates/sr/errors/0x2-beroot.txt @@ -0,0 +1,3 @@ +Greška 0x2. +Moraš biti root da bi koristio ovaj skript. + diff --git a/etc/templates/sr/errors/0x3-dependencies.txt b/etc/templates/sr/errors/0x3-dependencies.txt new file mode 100644 index 000000000..3949c0ef5 --- /dev/null +++ b/etc/templates/sr/errors/0x3-dependencies.txt @@ -0,0 +1,2 @@ +Greška 0x3. +Treba ti kompajler (kao gcc ili cc) da nastaviš sa instalacijom. diff --git a/etc/templates/sr/errors/0x4-installtype.txt b/etc/templates/sr/errors/0x4-installtype.txt new file mode 100644 index 000000000..d44df78d7 --- /dev/null +++ b/etc/templates/sr/errors/0x4-installtype.txt @@ -0,0 +1,3 @@ +Greška 0x4. +Pogrešan tip instalacije. Može biti jedino agent, server ili lokalna. + diff --git a/etc/templates/sr/errors/0x5-build.txt b/etc/templates/sr/errors/0x5-build.txt new file mode 100644 index 000000000..40ac745a3 --- /dev/null +++ b/etc/templates/sr/errors/0x5-build.txt @@ -0,0 +1,4 @@ + Greška 0x5. + Greška u gradnji. U nemogućnosti da završi instalaciju. + + diff --git a/etc/templates/sr/language.txt b/etc/templates/sr/language.txt new file mode 100644 index 000000000..f9a0e95a0 --- /dev/null +++ b/etc/templates/sr/language.txt @@ -0,0 +1 @@ + ** Za instalaciju na srpskom, izaberi [sr]. diff --git a/etc/templates/sr/messages.txt b/etc/templates/sr/messages.txt new file mode 100644 index 000000000..44c2f15aa --- /dev/null +++ b/etc/templates/sr/messages.txt @@ -0,0 +1,109 @@ +# Configuration +yes="d" +no="n" +yesmatch="d" +nomatch="n" +agent="agent" +local="lokalna" +server="server" +help="pomoć" + +# Global +moreinfo="Vise informacija na: " +starting="Zapocinje openarmor HIDS" +systemis="Sistem je" +modifiedinit="Init skript je modifikovan da započne openarmor HIDS za vreme startovanja ." +noboot="Nepoznat sistem. Init skript nije dodat." + +# Part 1 +installscript="Instalacioni Skript" +system="Sistem" +user="Korisnik" +host="Host" +hitanyorabort="Pritisni ENTER da nastavis ili Ctrl-C da poništiš." +whattoinstall="Koju vrstu instalacije želiš (server, agent, lokalnu ili pomoć)?" +serverchose="Izabrana instalacija server" +clientchose="Izabrana instalacija agent (klijent)" +localchose="Izabrana lokalna instalacija" + +# Part 2 +settingupenv="Postavljanje instalacionog okruženja" +wheretoinstall="Izaberi gde želiš da instaliraš openarmor HIDS" +installat="Instalacija će biti izvršena na " +deletedir="Instalacioni direktorij već postoji. Da li da ga obrišem?" + +# Part 3 +configuring="Trenutno vrši konfiguraciju" +mailnotify="Da li želiš email notifikaciju?" +nomail="Email notifikacija onesposobljena" +whatsemail="Koja je tvoja email adresa?" +yoursmtp="Našli smo da je tvoj SMTP server" +usesmtp="Da li želiš da ga koristiš?" +usingsmtp="Koristi SMTP server: " +whatsmtp="Koji je tvoj SMTP server IP/host?" + +# Part 3.1/agent +serverip="Koja je IP adresa openarmor HIDS servera?" +serveraddr="Koja je IP adresa/host openarmor HIDS servera?" +addingip="Dodaje serverov IP" +addingname="Dodaje serverov hostname" + + +# Part 3.2 +runsyscheck="Da li želiš da pustiš daemon provere integriteta?" +nosyscheck="Ne obavlja syscheck (daemon provere integriteta)" +yessyscheck="Obavlja syscheck (daemon provere integriteta)" + +# Part 3.3 +runrootcheck="Da li želiš da pustiš engine za otkrivanje rootkit-a?" +norootcheck="Ne obavlja rootcheck (otkrivanje rootkit-a )" +yesrootcheck="Obavlja rootcheck (otkrivanje rootkit-a)" + +# Part 3.4/server/local +enable_ar="Da li želiš da osposobiš aktivnu reakciju?" +noactive="Aktivna reakcija onesposobljena" +nohosts="host-deny onesposobljen" +yeshosts="host-deny osposobljen (lokalni) za nivoe >= 6" +firewallar="Da li želiš da osposobiš firewall-drop reakciju?" +nofirewall="firewall-drop onesposobljen." +yesfirewall="firewall-drop osposobljen (lokalni) za nivoe >= 6" +defaultwhitelist="Default bele liste za aktivnu reakciju:" +addwhite="Da li želiš da dodaš još IP-jeva beloj listi?" +ipswhite="IP-jevi (odvojen prostor): " + +# Part 3.5/server/local +syslog="Da li želiš da osposobiš udaljeni syslog (port 514 udp)?" +nosyslog="Udaljeni syslog onesposobljen" +yessyslog="Udaljeni syslog osposobljen" + +# Part 3.4/3.5 +readlogs="Postavlja konfiguraciju da analizira sledeće logove:" + +# Part 5 +installing="Instalira sistem" +runningmake="Vrši Makefile" + +# Final +configurationdone="Konfiguracija je dobro završena" +tostart="Da se započne openarmor HIDS" +tostop="Da se zaustavi openarmor HIDS" +configat="Konfiguracija se može videti ili modifikovati na" +addserveragent="Da bi se agent povezao sa serverom, treba da dodaš svakog od tvojih agenata +serveru." +runma="Pusti 'manage_agents' da ih dodaje ili otklanja" +presskey="Pritisni ENTER da nastaviš" + +# Update +wanttoupdate="Već imaš instaliran openarmor. Da li želiš da ga ažuriraš?" +unabletoupdate="U nemogućnosti da izvrši ažuriranje. Potrebna je potpuna nova instalacija." +updatecompleted="Ažuriranje završeno." +updatefailed="Ažuriranje nije uspelo." +updaterules="Da li želiš da ažuriraš pravila?" +updatingrules="Pravila ažuriranja." +notupdatingrules="Ne ažurira pravila." + +# Pf support +pfenable="Da li želiš da koristiš PF firewall u aktivnoj reakciji?" +nopf="PF reakcija onesposobljena." +pftablename="Ime PF table za korišćenje?" +pfmessage="Dodaj sledeće redove početku tvojih PF pravila" diff --git a/etc/templates/sr/messages/0x101-initial.txt b/etc/templates/sr/messages/0x101-initial.txt new file mode 100644 index 000000000..83b53ac9e --- /dev/null +++ b/etc/templates/sr/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + Nalaziš se pred početkom instalacionog proces openarmor HIDS. + Moraš imati c kompajler već instaliran u svoj sistem. + diff --git a/etc/templates/sr/messages/0x102-installhelp.txt b/etc/templates/sr/messages/0x102-installhelp.txt new file mode 100644 index 000000000..d0a2365f0 --- /dev/null +++ b/etc/templates/sr/messages/0x102-installhelp.txt @@ -0,0 +1,28 @@ + - Imaš tri instalacione opcije: server, agent ili lokalnu. + + - Ako izabereš 'server', moćićeš da analiziraš sve + logove, napraviš e-mail notifikacije i reakcije, + kao i da primiš logove sa udaljenih syslog mašina i + sistema kojima su pušteni 'agenti' (iz kojih se saobraćaj + šalje kriptovan u server). + + - Ako izabereš 'agent' (klijent), moćićeš da čitaš + lokalne fajlove (iz syslog, snort. apache itd) i da ih proslediš + (kriptovane) serveru na analizu. + + - Ako izabereš 'lokalnu', moćićeš da radiš sve što radi server, + osim da primaš udaljene poruke od agenata ili spoljašnjih + syslog mašina. + + - Izaberi 'server' ako postavljaš log/analysis server. + + - Izaberi 'agent' ako imaš drugu mašinu koju možeš da koristiš kao + log server i hoćeš da prosleđuješ logove serveru na analizu. + (idealno za webservere, servere baze podataka, itd) + + - Izaberi 'lokalnu' ako pratiš samo jedan sistem. + + - Više obaveštenja na: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/sr/messages/0x103-thanksforusing.txt b/etc/templates/sr/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..f1ec7fe90 --- /dev/null +++ b/etc/templates/sr/messages/0x103-thanksforusing.txt @@ -0,0 +1,11 @@ + Hvala što koristiš openarmor HIDS. + Ako imaš bilo kakvo pitanje, predlog ili ako nađeš neki bag, + kontaktiraj nas na contact@theopenarmor.org ili koristeći našu javnu maillistu na + openarmor-list@theopenarmor.org + ( http://www.theopenarmor.org/main/support/ ). + + Više informacija možeš naći na http://www.theopenarmor.org + + --- Pritisni ENTER da završiš (možda ima još informacije niže). --- + + diff --git a/etc/templates/sr/messages/0x104-client.txt b/etc/templates/sr/messages/0x104-client.txt new file mode 100644 index 000000000..3ed5a5ee1 --- /dev/null +++ b/etc/templates/sr/messages/0x104-client.txt @@ -0,0 +1,5 @@ + - Moraš prvo dodati ovog agenta serveru tako da + mogu da komuniciraju jedan sa drugim. Kada to uradiš + možeš da pustiš 'manage_agents' pomagalo da preuzmeš + ključ autentičnosti od servera. + diff --git a/etc/templates/sr/messages/0x105-noboot.txt b/etc/templates/sr/messages/0x105-noboot.txt new file mode 100644 index 000000000..15c2259f6 --- /dev/null +++ b/etc/templates/sr/messages/0x105-noboot.txt @@ -0,0 +1,2 @@ + Ništa nije preduzeto da konfiguriše openarmor HIDS da startuje + u toku buta. Dodaj sledeći red svom init skriptu: diff --git a/etc/templates/sr/messages/0x106-logs.txt b/etc/templates/sr/messages/0x106-logs.txt new file mode 100644 index 000000000..8e2bda283 --- /dev/null +++ b/etc/templates/sr/messages/0x106-logs.txt @@ -0,0 +1,9 @@ + - Ako želiš da nadgledaš neki drugi fajl, samo promeni + openarmor.conf i dodaj novi localfile ulaz. + Sva pitanja vezana za konfiguraciju mogu biti odgovorena + ako nas posetiš online na http://www.theopenarmor.org . + + + --- Pritisni ENTER da nastaviš --- + + diff --git a/etc/templates/sr/messages/0x107-ar.txt b/etc/templates/sr/messages/0x107-ar.txt new file mode 100644 index 000000000..c16ebf403 --- /dev/null +++ b/etc/templates/sr/messages/0x107-ar.txt @@ -0,0 +1,7 @@ + 3.4- Aktivna reakcija ti omogućava da izvedeš specifičnu + komandu na bazi primljenih događaja. Na primer, + možeš da blokiraš IP adresu ili onemogućiš pristup + određenom korisniku. + Više obaveštenja na: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/sr/messages/0x108-ar-enabled.txt b/etc/templates/sr/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..a8ead14f8 --- /dev/null +++ b/etc/templates/sr/messages/0x108-ar-enabled.txt @@ -0,0 +1,13 @@ + - Aktivirana aktivna reakcija. + + - Po default-u možemo osposobiti host-deny i + firewall-drop reakcije. Prvi će dodati host-a + na /etc/hosts.deny a drugi će blokirati host-a + na iptabeli (ako je u pitanju Linux) ili na + ipfilteru (Solaris, FreeBSD ili NetBSD). + - Oni se mogu koristiti da zaustave SSHD brute force skenove, + portskenove i neke druge vrste napada. Takođe ih možeš + dodati za blokiranje u slučaju snort dojava, na primer. + + + diff --git a/etc/templates/tr/errors/0x1-location.txt b/etc/templates/tr/errors/0x1-location.txt new file mode 100644 index 000000000..4b6a52d2f --- /dev/null +++ b/etc/templates/tr/errors/0x1-location.txt @@ -0,0 +1,6 @@ + + Error 0x1. + Bu betik sadece aynı dizin içinden çalıştırılabilir. + Bu betiğin daha önce çalıştığı dizine geçin. + Betiği ./install.sh şeklinde çalıştırmalısınız. + diff --git a/etc/templates/tr/errors/0x2-beroot.txt b/etc/templates/tr/errors/0x2-beroot.txt new file mode 100644 index 000000000..0c438457b --- /dev/null +++ b/etc/templates/tr/errors/0x2-beroot.txt @@ -0,0 +1,4 @@ + + Error 0x2. + Bu betiği çalıştırabilmeniz için root olmalısınız. + diff --git a/etc/templates/tr/errors/0x3-dependencies.txt b/etc/templates/tr/errors/0x3-dependencies.txt new file mode 100644 index 000000000..a887507fe --- /dev/null +++ b/etc/templates/tr/errors/0x3-dependencies.txt @@ -0,0 +1,5 @@ + + Error 0x3. + Kuruluma devam edebilmek için bir derleyiciye (gcc veya cc gibi) + ihtiyacınız var. + diff --git a/etc/templates/tr/errors/0x4-installtype.txt b/etc/templates/tr/errors/0x4-installtype.txt new file mode 100644 index 000000000..8e4c99c06 --- /dev/null +++ b/etc/templates/tr/errors/0x4-installtype.txt @@ -0,0 +1,4 @@ + + Error 0x4. + Yanlış kurulum türü. Sadece aracı, sunucu veya yerel olabilir. + diff --git a/etc/templates/tr/errors/0x5-build.txt b/etc/templates/tr/errors/0x5-build.txt new file mode 100644 index 000000000..7ad99ed8a --- /dev/null +++ b/etc/templates/tr/errors/0x5-build.txt @@ -0,0 +1,4 @@ + + Error 0x5. + Oluşturma hatası. Kurulum tamamlanamadı. + diff --git a/etc/templates/tr/language.txt b/etc/templates/tr/language.txt new file mode 100644 index 000000000..c3e1f3f86 --- /dev/null +++ b/etc/templates/tr/language.txt @@ -0,0 +1 @@ + ** Türkçe kurulum için seçin [tr]. diff --git a/etc/templates/tr/messages.txt b/etc/templates/tr/messages.txt new file mode 100644 index 000000000..4aedb53d7 --- /dev/null +++ b/etc/templates/tr/messages.txt @@ -0,0 +1,109 @@ +# Configuration +yes="e" +no="h" +yesmatch="e" +nomatch="h" +agent="aracı" +local="yerel" +server="sunucu" +help="yardım" + +# Global +moreinfo="Daha fazla bilgi: " +starting="openarmor HIDS başlatılıyor" +systemis="Sistem" +modifiedinit="openarmor HIDS'i önyüklemede başlatmak için başlangıç betiği değiştirildi." +noboot="Bilinmeyen sistem. Başlangıç betiği eklenmedi." + +# Part 1 +installscript="Kurulum Betiği" +system="Sistem" +user="Kullanıcı" +host="Bilgisayar" +hitanyorabort="Devam etmek için ENTER veya çıkmak için Ctrl-C ye basın" +whattoinstall="Ne tür kurulum yapmak istiyorsunuz (sunucu,aracı,yerel veya yardım)?" +serverchose="Sunucu kurulumu seçildi" +clientchose="Aracı(istemci) kurulumu seçildi" +localchose="Yerel kurulum seçildi" + +# Part 2 +settingupenv="Kurulum ortamı hazırlanıyor" +wheretoinstall="openarmor HIDS kurulacak yeri seçin" +installat="Kurulum buraya yapılacak: " +deletedir="Kurulum dizini zaten var. Silinsin mi?" + +# Part 3 +configuring="yapılandırılıyor:" +mailnotify="E-posta ile bilgilendirilmek ister misiniz?" +nomail="E-posta ile bilgilendirme etkisiz kılındı" +whatsemail="E-posta adresiniz nedir?" +yoursmtp="SMTP sunucunuz olarak bunu bulduk" +usesmtp="Kullanmak ister misiniz?" +usingsmtp="SMTP sunucu kullanılıyor: " +whatsmtp="SMTP sunucunuzun IP adresi veya ismi nedir?" + +# Part 3.1/agent +serverip="openarmor HIDS sunucusunun IP adresi nedir?" +serveraddr="openarmor HIDS sunucusunun IP adresi veya ismi nedir?" +addingip="Sunucu IP adresi ekleniyor" +addingname="Sunucu ismi ekleniyor" + + +# Part 3.2 +runsyscheck="Güvenilirlik/bütünlük kontrol programının çalıştırılmasını ister misiniz?" +nosyscheck="syscheck çalıştırılmıyor (güvenilirlik/bütünlük kontrol programı)" +yessyscheck="syscheck çalıştırılıyor (güvenilirlik/bütünlük kontrol programı)" + +# Part 3.3 +runrootcheck="rootkit tespit etme motorunun çalışmasını ister misiniz?" +norootcheck="rootcheck çalıştırılmıyor (rootkit tespit etme)" +yesrootcheck="rootcheck çalıştırılıyor (rootkit tespit etme)" + +# Part 3.4/server/local +enable_ar="Etkin yanıt üretmenin (Active response) etkin kılınmasını ister misiniz?" +noactive="Etkin yanıt üretme(Active response) etkisiz kılındı" +nohosts="host-deny etkin kılınmadı" +yeshosts="Uyarı seviyesi >= 6 için host-deny etkin kılındı (yerel)" +firewallar="firewall-drop yanıtının etkin kılınmasını ister misiniz?" +nofirewall="firewall-drop etkisiz kılındı." +yesfirewall="Uyarı seviyesi >= 6 için firewall-drop etkin kılındı (yerel)" +defaultwhitelist="Etkin yanıt üretme için öntanımlı beyaz liste:" +addwhite="Beyaz listeye başka IP adreslerini de eklemek ister misiniz?" +ipswhite="IPler (boşlukla ayrılmış): " + +# Part 3.5/server/local +syslog="Uzak syslog'un (514 udp) etkin kılınmasını ister misiniz?" +nosyslog="Uzak syslog etkisiz kılındı" +yessyslog="Uzak syslog etkin kılındı" + +# Part 3.4/3.5 +readlogs="Bu dosyaları incelemek için yapılandırma oluşturuluyor:" + +# Part 5 +installing="Sistem kuruluyor" +runningmake="Makefile çalıştırılıyor" + +# Final +configurationdone="Yapılandırma doğru olarak tamamlandı" +tostart="openarmor HIDS'i başlatmak için" +tostop="openarmor HIDS'i durdurmak için" +configat="Yapılandırma buradan görülebilir veya değiştirilebilir:" +addserveragent="Her bir aracıyı/istemciyi erişim için yetkilendirmeden önce eklemeniz gerekmektedir." +runma="Eklemek ve çıkarmak için 'manage_agents' komutunu kullanın." +presskey="Devam etmek için ENTER tuşuna basınız" + +# Update +wanttoupdate="Bir openarmor kurulumu mevcut. Güncellemek ister misiniz?" +unabletoupdate="Güncelleme gerçekleştirilemedi. Yeni kurulum yapılması gerekiyor." +updatecompleted="Güncelleme tamamlandı." +updatefailed="Güncelleme başarısız oldu." +updaterules="Kuralları güncellemek ister misiniz?" +updatingrules="Kurallar güncelleniyor." +notupdatingrules="Kurallar güncellenmiyor." + +# Pf support +pfenable="Etkin yanıtlarda PF güvenlik duvarını kullanmak istiyor musunuz?" +nopf="PF yanıtları etkisiz kılındı." +pftablename="Kullanılacak PF tablosunun adı?" +pfmessage="Aşağıdaki satırları kurallarınızın başına ekleyin" + diff --git a/etc/templates/tr/messages/0x101-initial.txt b/etc/templates/tr/messages/0x101-initial.txt new file mode 100644 index 000000000..a7653ce23 --- /dev/null +++ b/etc/templates/tr/messages/0x101-initial.txt @@ -0,0 +1,4 @@ + + openarmor HIDS kurulum sürecini başlatmak üzeresiniz. + Sisteminizde önceden kurulmuş bir C derleyicisi bulunmalıdır. + diff --git a/etc/templates/tr/messages/0x102-installhelp.txt b/etc/templates/tr/messages/0x102-installhelp.txt new file mode 100644 index 000000000..42af80c22 --- /dev/null +++ b/etc/templates/tr/messages/0x102-installhelp.txt @@ -0,0 +1,30 @@ + + - Üç adet kurulum seçeneği bulunmaktadır: sunucu, aracı veya yerel. + + - Eğer sunucu seçerseniz, bütün günlük kayıtlarını inceleyebilir + e-posta ile bilgilendirilebilir, yanıt üretebilirsiniz. + Ayrıca uzak syslog bilgisayarlarından ve 'aracı' olarak + çalışan sistemlerden günlük kayıtlarını alabilirsiniz + (aradaki trafik şifrelenecektir). + + - Eğer 'aracı' (istemci) seçerseniz, syslog, snort, apache vb. + tarafından üretilen yerel dosyaları okuyabilir ve incelenmek üzere + şifreli bir şekilde sunucuya gönderebilirsiniz. + + - Eğer 'yerel' seçerseniz, aracılardan veya harici syslog + aygıtlarından gelen mesajları almak dışında sunucunun + yapabildiği herşeyi yapabilirsiniz. + + - Eğer günlük kaydı inceleme sunucusu oluşturuyorsanız 'sunucu' kullanın. + + - Eğer başka bir günlük kaydı sunucunuz varsa ve incelenmesi için + günlük kayıtlarınızı bu sunucuya yönlendirmek istiyorsanız + 'aracı' kullanın. (web sunucular, veritabanı sunucular vb. için + idealdir) + + - Eğer inceleme yapacağınız tek sisteminiz varsa 'yerel' kullanın. + + - Daha fazla bilgi: + http://www.theopenarmor.org/docs/docs/manual/non-technical-overview.html + + diff --git a/etc/templates/tr/messages/0x103-thanksforusing.txt b/etc/templates/tr/messages/0x103-thanksforusing.txt new file mode 100644 index 000000000..797e44b50 --- /dev/null +++ b/etc/templates/tr/messages/0x103-thanksforusing.txt @@ -0,0 +1,12 @@ + + openarmor HIDS kullandığınız için teşekkürler. + Sorularınız, önerileriniz olursa veya her hangi bir yanlış + bulursanız contact@theopenarmor.org adresi ile veya kamuya açık + e-posta listemiz ile openarmor-list@theopenarmor.org adresinden iletişime + geçiniz. + ( http://www.theopenarmor.org/main/support/ ). + + http://www.theopenarmor.org adresinde daha fazla bilgi bulunabilir. + + --- Bitirmek için ENTER tuşuna basın (aşağıda daha fazla bilgi olabilir). --- + diff --git a/etc/templates/tr/messages/0x104-client.txt b/etc/templates/tr/messages/0x104-client.txt new file mode 100644 index 000000000..92811dab0 --- /dev/null +++ b/etc/templates/tr/messages/0x104-client.txt @@ -0,0 +1,6 @@ + + - Sunucu ile iletişimi sağlayabilmek için önce bu aracıyı + sunucuya eklemeniz gerekmektedir. Bunu yaptıktan sonra + sunucudan yetkilendirme anahtarını aktarmak için 'manage_agents' + komutunu çalıştırabilirsiniz. + diff --git a/etc/templates/tr/messages/0x105-noboot.txt b/etc/templates/tr/messages/0x105-noboot.txt new file mode 100644 index 000000000..d8667d2c0 --- /dev/null +++ b/etc/templates/tr/messages/0x105-noboot.txt @@ -0,0 +1,4 @@ + + - Önyükleme sırasında openarmor HIDS'i başlatmak için hiç birşey yapılmadı. + Bu satırı başlangıç betiğine ekleyin: + diff --git a/etc/templates/tr/messages/0x106-logs.txt b/etc/templates/tr/messages/0x106-logs.txt new file mode 100644 index 000000000..ee1ddc6a7 --- /dev/null +++ b/etc/templates/tr/messages/0x106-logs.txt @@ -0,0 +1,8 @@ + - Eğer başka bir dosyayı daha gözlemek isterseniz + openarmor.conf dosyasına yeni bir localfile girdisi ekleyin. + Yapılandırma hakkındaki herhangi bir sorunuzu cevaplamak için + http://www.theopenarmor.org adresini ziyaret edebilirsiniz. + + + --- Devam etmek için ENTER tuşuna basın --- + diff --git a/etc/templates/tr/messages/0x107-ar.txt b/etc/templates/tr/messages/0x107-ar.txt new file mode 100644 index 000000000..9e63e2856 --- /dev/null +++ b/etc/templates/tr/messages/0x107-ar.txt @@ -0,0 +1,8 @@ + + 3.4- Etkin yanıt üretme (Active response), edinilen olay + bilgilerine göre belirli bir komut çalıştırmanıza olanak + tanır. Örneğin bir IP adresinin engelleyebilir veya bir + kullanıcının erişimini kısıtlayabilirsiniz. + Daha fazla bilgi: + http://www.theopenarmor.org/docs/docs/manual/ar/index.html + diff --git a/etc/templates/tr/messages/0x108-ar-enabled.txt b/etc/templates/tr/messages/0x108-ar-enabled.txt new file mode 100644 index 000000000..dab0f59a5 --- /dev/null +++ b/etc/templates/tr/messages/0x108-ar-enabled.txt @@ -0,0 +1,11 @@ + - Etkin yanıt üretme (Active response) etkin kılındı. + + - Öntanımlı olarak host-deny ve firewall-drop etkin yanıt + mekanizmalarını etkin hale getirebiliriz. Bunlardan ilki + bir bilgisayarı /etc/hosts.deny dosyasına ekler, ikincisi + bilgisayarı iptables (linux) veya ipfilter (Solaris, + FreeBSD vb.) ile engeller. + - Bunlar, SSHD kaba güç saldırılarını, port taramalarını + ve diğer saldırı şekillerini durdurmak için kullanılabilir. + Ayrıca snort olaylarını değerlendirerek engelleme yapmak + için de ekleyebilirsiniz. diff --git a/install.sh b/install.sh new file mode 100644 index 000000000..5944dac59 --- /dev/null +++ b/install.sh @@ -0,0 +1,1269 @@ +#!/bin/sh +# Installation script for the openarmor +# Author: Daniel B. Cid +# Last modification: Aug 30, 2012 + +# Changelog 19/03/2006 - Rafael M. Capovilla +# New function AddWhite to allow users to add more Ips in the allow_list +# Minor *echos* modifications to better look +# Bug fix - When email address is blank +# Bug fix - delete INSTALLDIR - Default is yes but if the user just press enter the script wasn't deleting it as it should +# Changelog 15/07/2006 - Rafael M. Capovilla +# New function AddTable to add support for OpenBSD pf rules in firewall-drop active response + +# Changelog 29 March 2012 - Adding hybrid mode (standalone + agent) +# added fix for use of USER_AGENT_CONFIG_PROFILE in preloaded-vars + + + +### Looking up for the execution directory +cd `dirname $0` + + +### Looking for echo -n +ECHO="echo -n" +hs=`echo -n "a"` +if [ ! "X$hs" = "Xa" ]; then + if [ -x /usr/ucb/echo ]; then + ECHO="/usr/ucb/echo -n" + else + ECHO=echo + fi +fi + +# For solaris +echo "xxxx" | grep -E "xxx" > /dev/null 2>&1 +if [ ! $? = 0 ]; then + if [ -x /usr/xpg4/bin/grep ]; then + PATH=/usr/xpg4/bin:$PATH + fi +fi + +# Initializing vars +SET_DEBUG="" + +# Checking for command line arguments +for i in $*; do + if [ "X$i" = "Xdebug" ]; then + SET_DEBUG="debug" + elif [ "X$i" = "Xbinary-install" ]; then + USER_BINARYINSTALL="yes" + elif [ "X$i" = "Xhelp" ]; then + echo "$0 debug" + echo "$0 binary-install" + exit 1; + fi +done + + + +########## +# install() +########## +Install() +{ + echo "" + echo "5- ${installing}" + + echo "DIR=\"${INSTALLDIR}\"" > ${LOCATION} + + # Changing Config.OS with the new C flags + # Checking if debug is enabled + if [ "X${SET_DEBUG}" = "Xdebug" ]; then + CEXTRA="${CEXTRA} -DDEBUGAD" + fi + + echo "CEXTRA=${CEXTRA}" >> ./src/Config.OS + + MAKEBIN=make + ## Find make/gmake + if [ "X$NUNAME" = "XOpenBSD" ]; then + MAKEBIN=gmake + fi + if [ "X$NUNAME" = "XFreeBSD" ]; then + MAKEBIN=gmake + fi + if [ "X$NUNAME" = "XNetBSD" ]; then + MAKEBIN=gmake + fi + if [ "X$NUNAME" = "XDragonflyBSD" ]; then + MAKEBIN=gmake + fi + if [ "X%NUNAME" = "XBitrig" ]; then + MAKEBIN=gmake + fi + + + # Makefile + echo " - ${runningmake}" + cd ./src + + # Binary install will use the previous generated code. + if [ "X${USER_BINARYINSTALL}" = "X" ]; then + # Add DATABASE=pgsql or DATABASE=mysql to add support for database + # alert entry + ${MAKEBIN} PREFIX=${INSTALLDIR} TARGET=${INSTYPE} build + if [ $? != 0 ]; then + cd ../ + catError "0x5-build" + fi + fi + + # If update, stop openarmor + if [ "X${update_only}" = "Xyes" ]; then + UpdateStopopenarmor + fi + + ${MAKEBIN} PREFIX=${INSTALLDIR} TARGET=${INSTYPE} install + if [ $? != 0 ]; then + cd ../ + catError "0x5-build" + fi + + cd ../ + + + # Generate the /etc/openarmor-init.conf + VERSION_FILE="./src/VERSION" + VERSION=`cat ${VERSION_FILE}` + chmod 700 ${openarmor_INIT} > /dev/null 2>&1 + echo "DIRECTORY=\"${INSTALLDIR}\"" > ${openarmor_INIT} + echo "VERSION=\"${VERSION}\"" >> ${openarmor_INIT} + echo "DATE=\"`date`\"" >> ${openarmor_INIT} + echo "TYPE=\"${INSTYPE}\"" >> ${openarmor_INIT} + chmod 600 ${openarmor_INIT} + cp -pr ${openarmor_INIT} ${INSTALLDIR}${openarmor_INIT} + chmod 640 ${INSTALLDIR}${openarmor_INIT} + + + # If update_rules is set, we need to tweak + # openarmor.conf to read the new signatures. + if [ "X${update_rules}" = "Xyes" ]; then + UpdateopenarmorRules + fi + + # If update, start openarmor + if [ "X${update_only}" = "Xyes" ]; then + UpdateStartopenarmor + fi + + # Calling the init script to start openarmor hids during boot + if [ "X${update_only}" = "X" ]; then + runInit + if [ $? = 1 ]; then + notmodified="yes" + fi + fi + +} + + + + +########## +# UseSyscheck() +########## +UseSyscheck() +{ + + # Integrity check config + echo "" + $ECHO " 3.2- ${runsyscheck} ($yes/$no) [$yes]: " + if [ "X${USER_ENABLE_SYSCHECK}" = "X" ]; then + read AS + else + AS=${USER_ENABLE_SYSCHECK} + fi + echo "" + case $AS in + $nomatch) + echo " - ${nosyscheck}." + ;; + *) + SYSCHECK="yes" + echo " - ${yessyscheck}." + ;; + esac + + # Adding to the config file + if [ "X$SYSCHECK" = "Xyes" ]; then + cat ${SYSCHECK_TEMPLATE} >> $NEWCONFIG + fi +} + + + + +########## +# UseRootcheck() +########## +UseRootcheck() +{ + + # Rootkit detection configuration + echo "" + $ECHO " 3.3- ${runrootcheck} ($yes/$no) [$yes]: " + + if [ "X${USER_ENABLE_ROOTCHECK}" = "X" ]; then + read ES + else + ES=${USER_ENABLE_ROOTCHECK} + fi + + echo "" + case $ES in + $nomatch) + echo " - ${norootcheck}." + ;; + *) + ROOTCHECK="yes" + echo " - ${yesrootcheck}." + ;; + esac + + + # Adding to the config file + if [ "X$ROOTCHECK" = "Xyes" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " $INSTALLDIR/etc/shared/rootkit_files.txt" >> $NEWCONFIG + echo " $INSTALLDIR/etc/shared/rootkit_trojans.txt" >> $NEWCONFIG + echo " $INSTALLDIR/etc/shared/system_audit_rcl.txt" >> $NEWCONFIG + echo " $INSTALLDIR/etc/shared/cis_debian_linux_rcl.txt" >> $NEWCONFIG + echo " $INSTALLDIR/etc/shared/cis_rhel_linux_rcl.txt" >> $NEWCONFIG + echo " $INSTALLDIR/etc/shared/cis_rhel5_linux_rcl.txt" >> $NEWCONFIG + echo " " >> $NEWCONFIG + # Patch for systems that use s-nail instead of GNU Mailutils (such as Arch Linux). + if [ -r /usr/bin/mail ] && strings /usr/bin/mail | grep "x-shsh bash" 1> /dev/null; then + sed -i 's/mail !bash|/mail !/' ./src/rootcheck/db/rootkit_trojans.txt + fi + else + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " yes" >> $NEWCONFIG + echo " " >> $NEWCONFIG + fi +} + + + + +########## +# SetupLogs() +########## +SetupLogs() +{ + if [ "x${USER_CLEANINSTALL}" = "xy" ]; then + OPENDIR=`dirname $INSTALLDIR` + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " openarmoralert" >> $NEWCONFIG + echo " $OPENDIR/logs/alerts/alerts.log" >>$NEWCONFIG + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + return; + fi + + NB=$1 + echo "" + echo " $NB- ${readlogs}" + + echo " " >> $NEWCONFIG + LOG_FILES=`cat ${SYSLOG_TEMPLATE}` + for i in ${LOG_FILES}; do + # If log file present, add it + if [ -f "$i" ]; then + echo " -- $i" + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " syslog" >> $NEWCONFIG + echo " $i" >>$NEWCONFIG + echo " " >> $NEWCONFIG + fi + done + + + # Getting snort files + SNORT_FILES=`cat ${SNORT_TEMPLATE}` + for i in ${SNORT_FILES}; do + if [ -f "$i" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + + head -n 1 $i|grep "\[**\] "|grep -v "Classification:" > /dev/null + if [ $? = 0 ]; then + echo " snort-full" >> $NEWCONFIG + echo " -- $i (snort-full file)" + else + echo " snort-fast" >> $NEWCONFIG + echo " -- $i (snort-fast file)" + fi + echo " $i" >>$NEWCONFIG + echo " " >> $NEWCONFIG + fi + done + + # Getting apache logs + APACHE_FILES=`cat ${APACHE_TEMPLATE}` + for i in ${APACHE_FILES}; do + if [ -f "$i" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " apache" >> $NEWCONFIG + echo " $i" >>$NEWCONFIG + echo " " >> $NEWCONFIG + + echo " -- $i (apache log)" + fi + done + + # Getting postgresql logs + PGSQL_FILES=`cat ${PGSQL_TEMPLATE}` + for i in ${PGSQL_FILES}; do + if [ -f "$i" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " postgresql_log" >> $NEWCONFIG + echo " $i" >>$NEWCONFIG + echo " " >> $NEWCONFIG + + echo " -- $i (postgresql log)" + fi + done + + if [ "X$NUNAME" = "XLinux" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " command" >> $NEWCONFIG + echo " df -P" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " full_command" >> $NEWCONFIG + echo " netstat -tan |grep LISTEN |egrep -v '(127.0.0.1| ::1)' | sort" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " full_command" >> $NEWCONFIG + echo " last -n 5" >> $NEWCONFIG + echo " " >> $NEWCONFIG + fi + + + + + echo "" + catMsg "0x106-logs" + + + if [ "X$USER_NO_STOP" = "X" ]; then + read ANY + fi +} + + + +# install.sh + +########## +# ConfigureClient() +########## +ConfigureClient() +{ + echo "" + echo "3- ${configuring} $NAME." + echo "" + + if [ "X${USER_AGENT_SERVER_IP}" = "X" -a "X${USER_AGENT_SERVER_NAME}" = "X" ]; then + # Looping and asking for server ip or hostname + while [ 1 ]; do + $ECHO " 3.1- ${serveraddr}: " + read ADDRANSWER + # Is it an IP? + echo $ADDRANSWER | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "" + IP=$ADDRANSWER + echo " - ${addingip} $IP" + break; + # Must be a name + elif [ $? != 0 ]; then + echo "" + HNAME=$ADDRANSWER + echo " - ${addingname} $HNAME" + break; + fi + done + else + IP=${USER_AGENT_SERVER_IP} + HNAME=${USER_AGENT_SERVER_NAME} + fi + + echo "" > $NEWCONFIG + echo " " >> $NEWCONFIG + if [ "X${IP}" != "X" ]; then + echo " $IP" >> $NEWCONFIG + elif [ "X${HNAME}" != "X" ]; then + echo " $HNAME" >> $NEWCONFIG + fi + if [ "$X{USER_AGENT_CONFIG_PROFILE}" != "X" ]; then + PROFILE=${USER_AGENT_CONFIG_PROFILE} + echo " $PROFILE" >> $NEWCONFIG + fi + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + + # Syscheck? + UseSyscheck + + # Rootcheck? + UseRootcheck + + echo "" + $ECHO " 3.4 - ${enable_ar} ($yes/$no) [$yes]: " + + if [ "X${USER_ENABLE_ACTIVE_RESPONSE}" = "X" ]; then + read ANY + else + ANY=${USER_ENABLE_ACTIVE_RESPONSE} + fi + + case $ANY in + $nomatch) + echo "" + echo " - ${noactive}." + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " yes" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + ;; + *) + ACTIVERESPONSE="yes" + echo "" + ;; + esac + + # Set up the log files + SetupLogs "3.5" + + echo "" >> $NEWCONFIG +} + + + + +########## +# ConfigureServer() +########## +ConfigureServer() +{ + echo "" + echo "3- ${configuring} $NAME." + + + # Configuring e-mail notification + echo "" + $ECHO " 3.1- ${mailnotify} ($yes/$no) [$yes]: " + + if [ "X${USER_ENABLE_EMAIL}" = "X" ]; then + read ANSWER + else + ANSWER=${USER_ENABLE_EMAIL} + fi + + case $ANSWER in + $nomatch) + echo "" + echo " --- ${nomail}." + EMAILNOTIFY="no" + ;; + *) + EMAILNOTIFY="yes" + $ECHO " - ${whatsemail} " + if [ "X${USER_EMAIL_ADDRESS}" = "X" ]; then + + read EMAIL + echo "${EMAIL}" | grep -E "^[a-zA-Z0-9_.+-]{1,36}@[a-zA-Z0-9_.-]{1,54}$" > /dev/null 2>&1 ;RVAL=$?; + # Ugly e-mail validation + while [ "$EMAIL" = "" -o ! ${RVAL} = 0 ] ; do + $ECHO " - ${whatsemail} " + read EMAIL + echo "${EMAIL}" | grep -E "^[a-zA-Z0-9_.+-]{1,36}@[a-zA-Z0-9_.-]{1,54}$" > /dev/null 2>&1 ;RVAL=$?; + done + else + EMAIL=${USER_EMAIL_ADDRESS} + fi + + if [ -x "$HOST_CMD" ]; then + HOSTTMP=`${HOST_CMD} -W 5 -t mx theopenarmor.org 2>/dev/null` + if [ $? = 1 ]; then + # Trying without the -W + HOSTTMP=`${HOST_CMD} -t mx theopenarmor.org 2>/dev/null` + fi + echo "x$HOSTTMP" | grep "theopenarmor.org mail is handled" > /dev/null 2>&1 + if [ $? = 0 ]; then + # Breaking down the user e-mail + EMAILHOST=`echo ${EMAIL} | cut -d "@" -f 2` + if [ "X${EMAILHOST}" = "Xlocalhost" ]; then + SMTPHOST="127.0.0.1" + else + HOSTTMP=`${HOST_CMD} -W 5 -t mx ${EMAILHOST}` + SMTPHOST=`echo ${HOSTTMP} | cut -d " " -f 7` + fi + fi + fi + + if [ "X${USER_EMAIL_SMTP}" = "X" ]; then + if [ "X${SMTPHOST}" != "X" ]; then + echo "" + echo " - ${yoursmtp}: ${SMTPHOST}" + $ECHO " - ${usesmtp} ($yes/$no) [$yes]: " + read EMAIL2 + case ${EMAIL2} in + $nomatch) + echo "" + SMTP="" + ;; + *) + SMTP=${SMTPHOST} + echo "" + echo " --- ${usingsmtp} ${SMTP}" + ;; + esac + fi + + if [ "X${SMTP}" = "X" ]; then + $ECHO " - ${whatsmtp} " + read SMTP + fi + else + SMTP=${USER_EMAIL_SMTP} + fi + ;; + esac + + + # Writting global parameters + echo "" > $NEWCONFIG + echo " " >> $NEWCONFIG + if [ "$EMAILNOTIFY" = "yes" ]; then + echo " yes" >> $NEWCONFIG + echo " $EMAIL" >> $NEWCONFIG + echo " $SMTP" >> $NEWCONFIG + echo " openarmorm@${HOST}" >> $NEWCONFIG + else + echo " no" >> $NEWCONFIG + fi + + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + + # Writting rules configuration + cat ${RULES_TEMPLATE} >> $NEWCONFIG + echo "" >> $NEWCONFIG + + + # Checking if syscheck should run + UseSyscheck + + # Checking if rootcheck should run + UseRootcheck + + + # Active response + catMsg "0x107-ar" + $ECHO " - ${enable_ar} ($yes/$no) [$yes]: " + + if [ "X${USER_ENABLE_ACTIVE_RESPONSE}" = "X" ]; then + read AR + else + AR=${USER_ENABLE_ACTIVE_RESPONSE} + fi + + case $AR in + $nomatch) + echo "" + echo " - ${noactive}." + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " yes" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo "" >> $NEWCONFIG + ;; + *) + ACTIVERESPONSE="yes" + echo "" + catMsg "0x108-ar-enabled" + + echo "" + $ECHO " - ${firewallar} ($yes/$no) [$yes]: " + + if [ "X${USER_ENABLE_FIREWALL_RESPONSE}" = "X" ]; then + read HD2 + else + HD2=${USER_ENABLE_FIREWALL_RESPONSE} + fi + + echo "" + case $HD2 in + $nomatch) + echo " - ${nofirewall}" + ;; + *) + echo " - ${yesfirewall}" + FIREWALLDROP="yes" + ;; + esac + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " 127.0.0.1" >> $NEWCONFIG + echo " ::1" >> $NEWCONFIG + echo " localhost.localdomain">>$NEWCONFIG + echo "" + echo " - ${defaultallowlist}" + for ip in ${NAMESERVERS} ${NAMESERVERS2}; + do + if [ ! "X${ip}" = "X" ]; then + echo " - ${ip}" + echo " ${ip}" >>$NEWCONFIG + fi + done + AddWhite + + # If Openbsd or Freebsd with pf enable, ask about + # automatically setting it up. + # Commenting it out in case I change my mind about it + # later. + #if [ "X`sh ./src/init/fw-check.sh`" = "XPF" ]; then + # echo "" + # $ECHO " - ${pfenable} ($yes/$no) [$yes]: " + # if [ "X${USER_ENABLE_PF}" = "X" ]; then + # read PFENABLE + # else + # PFENABLE=${USER_ENABLE_PF} + # fi + # + # echo "" + # case $PFENABLE in + # $nomatch) + # echo " - ${nopf}" + # ;; + # *) + # AddPFTable + # ;; + # esac + #fi + + echo " " >> $NEWCONFIG + ;; + esac + + + if [ "X$INSTYPE" = "Xserver" ]; then + # Configuring remote syslog + echo "" + $ECHO " 3.5- ${syslog} ($yes/$no) [$yes]: " + + if [ "X${USER_ENABLE_SYSLOG}" = "X" ]; then + read ANSWER + else + ANSWER=${USER_ENABLE_SYSLOG} + fi + + echo "" + case $ANSWER in + $nomatch) + echo " --- ${nosyslog}." + ;; + *) + echo " - ${yessyslog}." + RLOG="yes" + ;; + esac + + # Configuring remote connections + SLOG="yes" + fi + + + + if [ "X$RLOG" = "Xyes" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " syslog" >> $NEWCONFIG + echo " " >> $NEWCONFIG + fi + + if [ "X$SLOG" = "Xyes" ]; then + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " secure" >> $NEWCONFIG + echo " " >> $NEWCONFIG + fi + + + # Email/log alerts + echo "" >> $NEWCONFIG + echo " " >> $NEWCONFIG + echo " 1" >> $NEWCONFIG + if [ "$EMAILNOTIFY" = "yes" ]; then + echo " 7">> $NEWCONFIG + fi + echo " " >> $NEWCONFIG + + + if [ "X$ACTIVERESPONSE" = "Xyes" ]; then + # Add commands in here + echo "" >> $NEWCONFIG + cat ${HOST_DENY_TEMPLATE} >> $NEWCONFIG + echo "" >> $NEWCONFIG + cat ${FIREWALL_DROP_TEMPLATE} >> $NEWCONFIG + echo "" >> $NEWCONFIG + cat ${DISABLE_ACCOUNT_TEMPLATE} >> $NEWCONFIG + echo "" >> $NEWCONFIG + cat ${ROUTENULL_TEMPLATE} >> $NEWCONFIG + echo "" >> $NEWCONFIG + + if [ "X$FIREWALLDROP" = "Xyes" ]; then + echo "" >> $NEWCONFIG + cat ${ACTIVE_RESPONSE_TEMPLATE} >> $NEWCONFIG + echo "" >> $NEWCONFIG + fi + fi + + # Setting up the logs + SetupLogs "3.6" + echo "" >> $NEWCONFIG +} + + + + +########## +# setEnv() +########## +setEnv() +{ + echo "" + echo "2- ${settingupenv}." + + echo "" + if [ "X${USER_DIR}" = "X" ]; then + while [ 1 ]; do + $ECHO " - ${wheretoinstall} [$INSTALLDIR]: " + read ANSWER + if [ ! "X$ANSWER" = "X" ]; then + echo $ANSWER |grep -E "^/[a-zA-Z0-9./_-]{3,128}$">/dev/null 2>&1 + if [ $? = 0 ]; then + INSTALLDIR=$ANSWER; + break; + fi + else + break; + fi + done + else + INSTALLDIR=${USER_DIR} + fi + + + CEXTRA="$CEXTRA -DDEFAULTDIR=\\\"${INSTALLDIR}\\\"" + + echo "" + echo " - ${installat} ${INSTALLDIR} ." + + + if [ "X$INSTYPE" = "Xagent" ]; then + CEXTRA="$CEXTRA -DCLIENT" + elif [ "X$INSTYPE" = "Xlocal" ]; then + CEXTRA="$CEXTRA -DLOCAL" + fi + + if [ -d "$INSTALLDIR" ]; then + if [ "X${USER_DELETE_DIR}" = "X" ]; then + echo "" + $ECHO " - ${deletedir} ($yes/$no) [$yes]: " + read ANSWER + else + ANSWER=${USER_DELETE_DIR} + fi + + case $ANSWER in + $yesmatch) + rm -rf $INSTALLDIR + if [ ! $? = 0 ]; then + exit 2; + fi + ;; + esac + fi +} + + + + +########## +# checkDependencies() +# Thanks to gabriel@macacos.org +########## +checkDependencies() +{ + echo "" + OLDOPATH=$PATH + if [ "X$NUNAME" = "XSunOS" ]; then + PATH=$PATH:/usr/ccs/bin:/usr/xpg4/bin:/opt/csw/gcc3/bin:/opt/csw/bin:/usr/sfw/bin + export PATH + elif [ "X$NUNAME" = "XAIX" ]; then + PATH=$PATH:/usr/vac/bin + export PATH + fi + + PATH=$OLDOPATH + export PATH +} + +########## +# AddWhite() +########## +AddWhite() +{ + while [ 1 ] + do + echo "" + $ECHO " - ${addwhite} ($yes/$no)? [$no]: " + + # If allow list is set, we don't need to ask it here. + if [ "X${USER_WHITE_LIST}" = "X" ]; then + read ANSWER + else + ANSWER=$yes + fi + + if [ "X${ANSWER}" = "X" ] ; then + ANSWER=$no + fi + + case $ANSWER in + $no) + break; + ;; + *) + $ECHO " - ${ipswhite}" + if [ "X${USER_WHITE_LIST}" = "X" ]; then + read IPS + else + IPS=${USER_WHITE_LIST} + fi + + for ip in ${IPS}; + do + if [ ! "X${ip}" = "X" ]; then + echo $ip | grep -Ei "^[0-9a-f.:/]{5,20}$" > /dev/null 2>&1 + if [ $? = 0 ]; then + echo " ${ip}" >>$NEWCONFIG + fi + fi + done + + break; + ;; + esac + done +} + + +########## +# AddPFTable() +########## +AddPFTable() +{ + #default pf rules + TABLE="openarmor_fwtable" + + # Add table to the first line + echo "" + echo " - ${pfmessage}:" + echo " ${moreinfo}" + echo " http://www.theopenarmor.org/docs/docs/manual/ar/index.html-tools" + + echo "" + echo "" + echo " table <${TABLE}> persist #$TABLE " + echo " block in quick from <${TABLE}> to any" + echo " block out quick from any to <${TABLE}>" + echo "" + echo "" + +} + +########## +# main() +########## +main() +{ + LG="en" + LANGUAGE="en" + . ./src/init/shared.sh + . ./src/init/functions.sh + + # Reading pre-defined file + if [ ! `isFile ${PREDEF_FILE}` = "${FALSE}" ]; then + . ${PREDEF_FILE} + fi + + # If user language is not set + + if [ "X${USER_LANGUAGE}" = "X" ]; then + + # Choosing the language. + while [ 1 ]; do + echo "" + for i in `ls ${TEMPLATE}`; do + # ignore CVS (should not be there anyways and config) + if [ "$i" = "CVS" -o "$i" = "config" ]; then continue; fi + cat "${TEMPLATE}/$i/language.txt" + if [ ! "$i" = "en" ]; then + LG="${LG}/$i" + fi + done + $ECHO " (${LG}) [en]: " + read USER_LG; + + if [ "X${USER_LG}" = "X" ]; then + USER_LG="en" + fi + + if [ -d "${TEMPLATE}/${USER_LG}" ]; then + break; + fi + done; + + LANGUAGE=${USER_LG} + + else + + # If provided language is not valid, default to english + if [ -d "${TEMPLATE}/${USER_LANGUAGE}" ]; then + LANGUAGE=${USER_LANGUAGE} + else + LANGUAGE="en" + fi + + fi # for USER_LANGUAGE + + + . ./src/init/shared.sh + . ./src/init/language.sh + . ./src/init/functions.sh + . ./src/init/init.sh + . ${TEMPLATE}/${LANGUAGE}/messages.txt + + + # Must be executed as ./install.sh + if [ `isFile ${VERSION_FILE}` = "${FALSE}" ]; then + catError "0x1-location"; + fi + + # Must be root + if [ ! "X$ME" = "Xroot" ]; then + catError "0x2-beroot"; + fi + + # Checking dependencies + checkDependencies + + clear + + + # Initial message + echo " $NAME $VERSION ${installscript} - http://www.theopenarmor.org" + + catMsg "0x101-initial" + + echo " - $system: $UNAME" + echo " - $user: $ME" + echo " - $host: $HOST" + echo "" + echo "" + echo " -- $hitanyorabort --" + + if [ "X$USER_NO_STOP" = "X" ]; then + read ANY + fi + + . ./src/init/update.sh + # Is this an update? + if [ "`isUpdate`" = "${TRUE}" -a "x${USER_CLEANINSTALL}" = "x" ]; then + echo "" + ct="1" + while [ $ct = "1" ]; do + ct="0" + $ECHO " - ${wanttoupdate} ($yes/$no): " + if [ "X${USER_UPDATE}" = "X" ]; then + read ANY + else + ANY=$yes + fi + + case $ANY in + $yes) + update_only="yes" + break; + ;; + $no) + break; + ;; + *) + ct="1" + ;; + esac + done + + + # Do some of the update steps. + if [ "X${update_only}" = "Xyes" ]; then + . ./src/init/update.sh + + if [ "`doUpdatecleanup`" = "${FALSE}" ]; then + # Disabling update + echo "" + echo "${unabletoupdate}" + sleep 5; + update_only="" + else + # Get update + USER_INSTALL_TYPE=`getPreinstalled` + USER_DIR=`getPreinstalledDir` + USER_DELETE_DIR="$nomatch" + fi + + ct="1" + + # We dont need to update the rules on agent installs + if [ "X${USER_INSTALL_TYPE}" = "Xagent" ]; then + ct="0" + fi + + while [ $ct = "1" ]; do + ct="0" + $ECHO " - ${updaterules} ($yes/$no): " + if [ "X${USER_UPDATE_RULES}" = "X" ]; then + read ANY + else + ANY=$yes + fi + + case $ANY in + $yes) + update_rules="yes" + break; + ;; + $no) + break; + ;; + *) + ct="1" + ;; + esac + done + fi + echo "" + fi + + hybrid="hybrid" + HYBID="" + hybridm=`echo ${hybrid} | cut -b 1` + serverm=`echo ${server} | cut -b 1` + localm=`echo ${local} | cut -b 1` + agentm=`echo ${agent} | cut -b 1` + helpm=`echo ${help} | cut -b 1` + + # If user install type is not set, ask for it. + if [ "X${USER_INSTALL_TYPE}" = "X" ]; then + + # Loop for the installation options + while [ 1 ] + do + echo "" + $ECHO "1- ${whattoinstall} " + + read ANSWER + case $ANSWER in + + ${helpm}|${help}) + catMsg "0x102-installhelp" + ;; + + ${server}|${serverm}) + echo "" + echo " - ${serverchose}." + INSTYPE="server" + break; + ;; + + ${agent}|${agentm}) + echo "" + echo " - ${clientchose}." + INSTYPE="agent" + break; + ;; + + ${hybrid}|${hybridm}) + echo "" + echo " - ${serverchose} (hybrid)." + INSTYPE="server" + HYBID="go" + break; + ;; + ${local}|${localm}) + echo "" + echo " - ${localchose}." + INSTYPE="local" + break; + ;; + esac + done + + else + INSTYPE=${USER_INSTALL_TYPE} + fi + + + # Setting up the environment + setEnv + + + # Configuring the system (based on the installation type) + if [ "X${update_only}" = "X" ]; then + if [ "X$INSTYPE" = "Xserver" ]; then + ConfigureServer + elif [ "X$INSTYPE" = "Xagent" ]; then + ConfigureClient + elif [ "X$INSTYPE" = "Xlocal" ]; then + ConfigureServer + else + catError "0x4-installtype" + fi + fi + + # Installing (calls the respective script + # -- InstallAgent.sh or InstallServer.sh + Install + + # User messages + echo "" + echo " - ${configurationdone}." + echo "" + echo " - ${tostart}:" + echo " $INSTALLDIR/bin/openarmor-control start" + echo "" + echo " - ${tostop}:" + echo " $INSTALLDIR/bin/openarmor-control stop" + echo "" + echo " - ${configat} $INSTALLDIR/etc/openarmor.conf" + echo "" + + + catMsg "0x103-thanksforusing" + + + if [ "X${update_only}" = "Xyes" ]; then + # Message for the update + if [ "X`sh ./src/init/fw-check.sh`" = "XPF" -a "X${ACTIVERESPONSE}" = "Xyes" ]; then + if [ "X$USER_NO_STOP" = "X" ]; then + read ANY + fi + AddPFTable + fi + echo "" + echo " - ${updatecompleted}" + echo "" + exit 0; + fi + + + if [ "X$USER_NO_STOP" = "X" ]; then + read ANY + fi + + + # PF firewall message + if [ "X`sh ./src/init/fw-check.sh`" = "XPF" -a "X${ACTIVERESPONSE}" = "Xyes" ]; then + AddPFTable + fi + + + if [ "X$INSTYPE" = "Xserver" ]; then + echo "" + echo " - ${addserveragent}" + echo " ${runma}:" + echo "" + echo " $INSTALLDIR/bin/manage_agents" + echo "" + echo " ${moreinfo}" + echo " http://www.theopenarmor.org/docs/docs/programs/manage_agents.html" + echo "" + + elif [ "X$INSTYPE" = "Xagent" ]; then + catMsg "0x104-client" + echo " $INSTALLDIR/bin/manage_agents" + echo "" + echo " ${moreinfo}" + echo " http://www.theopenarmor.org/docs/docs/programs/manage_agents.html" + echo "" + fi + + if [ "X$notmodified" = "Xyes" ]; then + catMsg "0x105-noboot" + echo " $INSTALLDIR/bin/openarmor-control start" + echo "" + fi +} + +_f_cfg="./install.cfg.sh" + +if [ -f $_f_cfg ]; then + . $_f_cfg +fi + +### Calling main function where everything happens +main + + +if [ "x$HYBID" = "xgo" ]; then + echo " --------------------------------------------" + echo " Finishing Hybrid setup (agent configuration)" + echo " --------------------------------------------" + echo 'USER_LANGUAGE="en"' > ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_NO_STOP="y"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_INSTALL_TYPE="agent"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo "USER_DIR=\"$INSTALLDIR/openarmor-agent\"" >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_ENABLE_ROOTCHECK="n"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_ENABLE_SYSCHECK="n"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_ENABLE_ACTIVE_RESPONSE="n"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_UPDATE="n"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_UPDATE_RULES="n"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + echo 'USER_CLEANINSTALL="y"' >> ./etc/preloaded-vars.conf + echo "" >> ./etc/preloaded-vars.conf + + cd src && ${MAKEBIN} clean && cd .. + ./install.sh + rm etc/preloaded-vars.conf +fi + + +exit 0 + + + +#### exit ? ### diff --git a/openarmor-rules/README.md b/openarmor-rules/README.md new file mode 100644 index 000000000..d5d6faf4a --- /dev/null +++ b/openarmor-rules/README.md @@ -0,0 +1,3 @@ +This repository will contain the rules and decoders for openarmor. +Rules will be contained in `rules.d` and the decoders in `etc/decoders.d`. +A copy of the combined decoder file may be contained in `etc/` diff --git a/openarmor-rules/decoders.d/00-crs-iptables_decoder.xml b/openarmor-rules/decoders.d/00-crs-iptables_decoder.xml new file mode 100644 index 000000000..67c31ad42 --- /dev/null +++ b/openarmor-rules/decoders.d/00-crs-iptables_decoder.xml @@ -0,0 +1,81 @@ + + + ^kernel + + + + iptables + firewall + ^\[\d+\.\d+\] \S+ IN= + + ^\[\d+\.\d+\] (\S+) .+ SRC=(\S+) DST=(\S+) + .+ PROTO=(\w+) + action,srcip,dstip,protocol + + + + iptables + firewall + ^SPT=(\d+) DPT=(\d+) + srcport,dstport + + + + iptables + firewall + ^\S+ IN= + + ^(\S+) .+ SRC=(\S+) DST=(\S+) .+ + PROTO=(\w+) + action,srcip,dstip,protocol + + + + + iptables + firewall + ^SPT=(\d+?) DPT=(\d+?) + srcport,dstport + + + + iptables + firewall + ^Shorewall:\S+: + + ^(\S+):.+ SRC=(\S+) DST=(\S+) .+ + PROTO=(\w+) + action,srcip,dstip,protocol + + + + iptables + firewall + ^SPT=(\d+) DPT=(\d+) + srcport,dstport + + + + iptables + firewall + ^[()*+,.:;\<=>?\[\]!"'#%&$|{}-]\S+[()*+,.:;\<=>?\[\]!"'#%&$|{}-] Shorewall:\S+: + ^(\S+):.+ SRC=(\S+) DST=(\S+) .+ + PROTO=(\w+) + action,srcip,dstip,protocol + + + diff --git a/openarmor-rules/decoders.d/00-crs-pam_decoder.xml b/openarmor-rules/decoders.d/00-crs-pam_decoder.xml new file mode 100644 index 000000000..73686becf --- /dev/null +++ b/openarmor-rules/decoders.d/00-crs-pam_decoder.xml @@ -0,0 +1,75 @@ + + + \(pam_unix\)$ + + + + + .* + ^pam_unix|^\(pam_unix\)|^pam_succeed_if + + + + pam + ^session \w+ + ^for user (\S+) + user + + + + + + pam + rhost=\S+[ ]+user=\S+ + rhost=(\S+)[ ]+?user=(\S+) + srcip, user + + + + pam + ruser + ^=(\S+) + user + + + + pam + rhost=(\S+) + srcip + + + + pam + rhost + ^=(\S+) + srcip + + diff --git a/openarmor-rules/decoders.d/00-crs-windows-date-format_decoder.xml b/openarmor-rules/decoders.d/00-crs-windows-date-format_decoder.xml new file mode 100644 index 000000000..a4106865b --- /dev/null +++ b/openarmor-rules/decoders.d/00-crs-windows-date-format_decoder.xml @@ -0,0 +1,13 @@ + + + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} + + + + + diff --git a/openarmor-rules/decoders.d/50-crs-aix-ipsec_decoder.xml b/openarmor-rules/decoders.d/50-crs-aix-ipsec_decoder.xml new file mode 100644 index 000000000..f5d0fb325 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-aix-ipsec_decoder.xml @@ -0,0 +1,15 @@ + + + firewall + ^ipsec_logd + R:(\w) \w:\S+ S:(\S+) + D:(\S+) P:(\S+) SP:(\d+) DP:(\d+) + action,srcip,dstip,protocol,srcport,dstport + + + diff --git a/openarmor-rules/decoders.d/50-crs-apache_decoder.xml b/openarmor-rules/decoders.d/50-crs-apache_decoder.xml new file mode 100644 index 000000000..cc1ccefa3 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-apache_decoder.xml @@ -0,0 +1,62 @@ + + + + + ^httpd + + + + ^\[warn\] |^\[notice\] |^\[error\] + + + + ^\[\w+ \w+ \d+ \d+:\d+:\d+\.\d+ \d+\] (?:\[\S+:warn\]|\[\S+:notice\]|\[\S*:error\]|\[\S+:info\]) + + + + apache-errorlog + \[client \S+:\d+?\] \S+: + \[client (\S+):(\d+?)\] (\S+): + srcip,srcport,id + + + + apache-errorlog + \[client \S+\] \S+: + \[client (\S+)\] (\S+): + srcip,id + + + + + apache-errorlog + \[client + ^ (\S+):(\d+?)\] |^ (\S+)\] + srcip,srcport + + + + diff --git a/openarmor-rules/decoders.d/50-crs-apparmor_decoder.xml b/openarmor-rules/decoders.d/50-crs-apparmor_decoder.xml new file mode 100644 index 000000000..cc1ac8a2f --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-apparmor_decoder.xml @@ -0,0 +1,20 @@ + + + + iptables + apparmor= + apparmor="(\S+)" operation="(\S+)" + status, extra_data + + + diff --git a/openarmor-rules/decoders.d/50-crs-arpwatch_decoder.xml b/openarmor-rules/decoders.d/50-crs-arpwatch_decoder.xml new file mode 100644 index 000000000..8be67865e --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-arpwatch_decoder.xml @@ -0,0 +1,23 @@ + + + ^arpwatch + + + + arpwatch + ^new station |^bogon + ^(\S+) (\S+) + srcip, extra_data + name, srcip, extra_data + + + + diff --git a/openarmor-rules/decoders.d/50-crs-asterisk_decoder.xml b/openarmor-rules/decoders.d/50-crs-asterisk_decoder.xml new file mode 100644 index 000000000..2b5521a49 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-asterisk_decoder.xml @@ -0,0 +1,47 @@ + + + ^asterisk + + + + asterisk + ^WARNING\[\d+?\]: \S+ in \S+: Don't know + ^\S+ how to respond via '([A-Za-z0-9@_-]+/\d\.\d/[A-Za-z0-9@_-]+)' + user + + + + asterisk + ^NOTICE\[\d+?\]: \S+ in \S+: Registration from + ^'.+' failed for '(\S+):(\d+?)'|^'.+' failed for '(\S+)' + srcip,srcport + + + + asterisk + Registration from + failed for '(\S+):(\d+?)'|failed for '(\S+)' + srcip,srcport + + + + asterisk + ^NOTICE\[\d+?\]\[[A-Za-z0-9@_-]+?\]: \S+ in \S+: Call from + ^'\S*' \((\S+):(\d+?)\) to extension '(\S+)' rejected because extension not found in context '(\S+)'\.$ + srcip, srcport, extra_data, extra_data + + + + asterisk + ^NOTICE\[\d+\]: \S+ in \S+: Host + ^(\S+) failed MD5 authentication for (\S+) + srcip, user + + + diff --git a/openarmor-rules/decoders.d/50-crs-auditd_decoder.xml b/openarmor-rules/decoders.d/50-crs-auditd_decoder.xml new file mode 100644 index 000000000..6f0c60f7b --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-auditd_decoder.xml @@ -0,0 +1,101 @@ + +type=USER_ACCT msg=audit(1310592861.936:1222): user pid=24675 uid=0 auid=501 ses=188 subj=system_u:system_r:unconfined_t:s0 msg='op=PAM:accounting acct="username" exe="/usr/bin/sudo" (hostname=?, addr=?, terminal=pts/5 res=success)' +type=CRED_ACQ msg=audit(1305666154.831:51859): user pid=21250 uid=0 auid=4294967295 subj=system_u:system_r:unconfined_t:s0-s0:c0.c1023 msg='PAM: setcred acct="username" : exe="/usr/sbin/sshd" (hostname=lala.example.com, addr=172.16.0.1, terminal=ssh res=success)' +type=CRED_ACQ msg=audit(1273182001.226:148635): user pid=29770 uid=0 auid=4294967295 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: setcred acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron +type=USER_AUTH msg=audit(1305666163.690:51871): user pid=21269 uid=0 auid=500 subj=user_u:system_r:unconfined_t:s0 msg='PAM: authentication acct="root" : exe="/bin/su" (hostname=?, addr=?, terminal=pts/0 res=success)' +type=USER_ACCT msg=audit(1306939201.750:67934): user pid=4401 uid=0 auid=4294967295 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: accounting acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron res=success)' +type=CRED_ACQ msg=audit(1306939201.751:67935): user pid=4401 uid=0 auid=4294967295 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: setcred acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron res=success)' +type=USER_START msg=audit(1306939201.756:67937): user pid=4401 uid=0 auid=0 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='PAM: session open acct="root" : exe="/usr/sbin/crond" (hostname=?, addr=?, terminal=cron res=success)' +type=USER_CHAUTHTOK msg=audit(1304523288.952:37394): user pid=7258 uid=0 auid=500 subj=user_u:system_r:unconfined_t:s0 msg='op=change password id=505 exe="/usr/bin/passwd" (hostname=?, addr=?, terminal=pts/1 res=success)' + + +type=USER_ACCT msg=audit(1310592861.936:1222): user pid=24675 uid=0 auid=501 ses=188 subj=system_u:system_r:unconfined_t:s0 msg='op=PAM:accounting acct="username" exe="/usr/bin/sudo" (hostname=?, addr=?, terminal=pts/5 res=success)' + + +type=SYSCALL msg=audit(1307045440.943:148): arch=c000003e syscall=59 success=yes exit=0 a0=de1fa8 a1=de23a8 a2=dc3008 a3=7fff1db3cc60 items=2 ppid=11719 pid=12140 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="wget" exe="/tmp/wget" key="webserver-watch-tmp" +type=SYSCALL msg=audit(1307045820.403:151): arch=c000003e syscall=59 success=no exit=-13 a0=de24c8 a1=de2408 a2=dc3008 a3=7fff1db3cc60 items=1 ppid=11719 pid=12347 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=4294967295 comm="bash" exe="/bin/bash" key=(null) +type=SYSCALL msg=audit(1306939143.715:67933): arch=40000003 syscall=94 success=yes exit=0 a0=5 a1=180 a2=8ebd360 a3=8ec4978 items=1 ppid=4383 pid=4388 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=8038 comm="less" exe="/usr/bin/less" subj=user_u:system_r:unconfined_t:s0 key="perm_mod" +type=USER_ROLE_CHANGE msg=audit(1280266360.845:51): user pid=1978 uid=0 auid=500 subj=system_u:system_r:local_login_t:s0-s0:c0.c1023 msg='pam: default-context=user_u:system_r:unconfined_t:s0 selected-context=user_u:system_r:unconfined_t:s0: exe="/bin/login" (hostname=?, addr=?, terminal=tty1 res=success)' +type=PATH msg=audit(1306967989.163:119): item=0 name="./ls" inode=261813 dev=fb:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 + + +type=PATH msg=audit(1273924468.947:179534): item=0 name=(null) inode=424783 dev=fd:07 mode=0100640 ouid=0 ogid=502 rdev=00:00 obj=user_u:object_r:file_t:s0 + +--> + + + ^type= + + + + + auditd + ^AVC + ^(AVC) msg=audit\(\d{10}\.\d{3}:(\d+?)\): avc: (\S+) \{ .+ \} for pid=\d+? comm="(\S+)" path="\S+" dev=\S+ ino=\d+? scontext=\S+ tcontext=\S+ tclass=\S+$ + action,id,status,extra_data + + + + + auditd + ^SYSCALL + ^(SYSCALL) msg=audit\(\d{10}\.\d{3}:(\d+?)\): arch=\w+ syscall=\d+ success=(\S+) exit=\S+ a0=\w+ a1=\w+ a2=\w+ a3=\w+ items=\d+ ppid=\d+ pid=\d+ auid=\d+ uid=\d+ gid=\d+ euid=\d+ suid=\d+ fsuid=\d+ egid=\d+ sgid=\d+ fsgid=\d+ tty=\S+ ses=\d+ comm="\S+" exe="(.+?)" + action,id,status,extra_data + + + + + auditd + ^CONFIG_CHANGE + ^(CONFIG_CHANGE) msg=audit\(\d{10}\.\d{3}:(\d+?)\): auid=\d+? ses=\d+? op=".+" path="(.+)" key="\S+" list=\d+? res=\d+?$ + action,id,extra_data + + + + + auditd + ^PATH + ^(PATH) msg=audit\(\d{10}\.\d{2}:(\d+?)\): item=\d+? name="(.+)" inode=\d+? dev=\S+ mode=\d+? ouid=\d+? ogid=\d+? rdev=\S+ + action,id,extra_data + + + + + auditd + ^(USER_\S+) msg=audit\(\d{10}\.\d{3}:(\d+?)\): user pid=\d+? uid=\d+? auid=\d+| + ^(CRED_\S+) msg=audit\(\d{10}\.\d{3}:(\d+?)\): user pid=\d+? uid=\d+? auid=\d+ + action,id + + + + auditd + acct="(.+)" : exe="(.+)" \(hostname=\S+, addr=(\S+), terminal=\S+$ + user,extra_data,srcip + + + + auditd + ses=\d+? subj=\S+ msg='.+ acct="(.+)" exe="(.+)" hostname=\S+ addr=(\S+) terminal=\S+ res=(\S+)$ + user,extra_data,srcip,status + + + + auditd + subj=\S+ msg='.+ acct="(.+)" :*[ ]*?exe="(.+)" \(hostname=\S+, addr=(\S+), terminal=\S+ res=(\S+)\)'$ + user,extra_data,srcip,status + + + + auditd + subj=\S+ msg='.+ exe="(.+)" \(hostname=\S+, addr=(\S+), terminal=\S+ res=(\S+)\)'$ + extra_data,srcip,status + + + diff --git a/openarmor-rules/decoders.d/50-crs-barracuda_decoder.xml b/openarmor-rules/decoders.d/50-crs-barracuda_decoder.xml new file mode 100644 index 000000000..95ec41cf6 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-barracuda_decoder.xml @@ -0,0 +1,71 @@ + + + + ^inbound/pass|^scan|^outbound/smtp + + + + barracuda-svf-email + ^\S+\[\S+\]| + ^\S+ + ^\S+\[(\S+)\] (\d+-[A-Za-z0-9@_-]+?-[A-Za-z0-9@_-]+) \d+ \d+ | + ^(\S+) (\d+-[A-Za-z0-9@_-]+?-[A-Za-z0-9@_-]+) \d+ \d+ + srcip, id + + + + + barracuda-svf-email + (SCAN) (\S+ \S+ \S+ \S+ \d+ \d+ .+ SUBJ:.+)$ + action, extra_data + + + + + barracuda-svf-email + (RECV) (\S+ \S+ \d+ \d+ .+)$ + action, extra_data + + + + + barracuda-svf-email + (SEND) (\S+ \d+ \S+ .+)$ + action, extra_data + + + + + + ^web + + + + barracuda-svf-admin + ^\[\S+\] global\[\] CHANGE + ^\[(\S+)\] global\[\] (CHANGE) (\S+ \(\S*)\)$ + srcip,action,extra_data + + + + barracuda-svf-admin + ^\[\S+\] LOGIN| + ^\[\S+\] FAILED_LOGIN| + ^\[\S+\] LOGOUT + ^\[(\S+)\] (\S+) \((\S+)\)[()*+,.:;\<=>?\[\]!"'#%&$|{}-]*$ + srcip,action,user + + + + diff --git a/openarmor-rules/decoders.d/50-crs-checkpoint_decoder.xml b/openarmor-rules/decoders.d/50-crs-checkpoint_decoder.xml new file mode 100644 index 000000000..1b0d251e7 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-checkpoint_decoder.xml @@ -0,0 +1,78 @@ + + + + + ^Checkpoint + ^[ ]+?\S+ \d{2}:\d{2}:\d{2} + + + + checkpoint-syslog + firewall + ^drop|^accept|^reject + ^([A-Za-z0-9@_-]+)[ ]+\S+ >\S+ rule:.+ + src: (\S+); dst: (\S+); proto: (\S+); + action,srcip,dstip,protocol + + + + checkpoint-syslog + firewall + service: (\d+); s_port: (\d+); + dstport,srcport + + + + checkpoint-syslog + ids + ^monitor|^drop + attack: (.+); + src: (\S+); dst: (\S+); + proto: (\S+); + extra_data, srcip, dstip, protocol + name, extra_data, srcip, dstip + First time Checkpoint rule fired. + + + diff --git a/openarmor-rules/decoders.d/50-crs-chkpwd_decoder.xml b/openarmor-rules/decoders.d/50-crs-chkpwd_decoder.xml new file mode 100644 index 000000000..2c3bce75c --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-chkpwd_decoder.xml @@ -0,0 +1,15 @@ + + + ^unix_chkpwd + + + + + unix_chkpwd + user \(([A-Za-z0-9@_-]+)\)$ + srcuser + + + diff --git a/openarmor-rules/decoders.d/50-crs-cimserver_decoder.xml b/openarmor-rules/decoders.d/50-crs-cimserver_decoder.xml new file mode 100644 index 000000000..06eac16a7 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-cimserver_decoder.xml @@ -0,0 +1,18 @@ + + + ^cimserver$ + + + + cimserver + ^[A-Za-z0-9@_-]+: Authentication failed for user + ^(\S+)\.$ + user + + + diff --git a/openarmor-rules/decoders.d/50-crs-cisco-ios_decoder.xml b/openarmor-rules/decoders.d/50-crs-cisco-ios_decoder.xml new file mode 100644 index 000000000..f4a3f5699 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-cisco-ios_decoder.xml @@ -0,0 +1,75 @@ + + + ^%\w+-\d-\w+: + + + + + ^%\w+-\d-\w+: + + + + + + + + cisco-ios + firewall + ^%SEC-6-IPACCESSLOGP: + ^list \S+ (\w+) (\w+) + (\S+)\((\d+)\) -> (\S+)\((\d+)\), + action, protocol, srcip, srcport, dstip, dstport + + + + + + + + + cisco-ios + ids + ^%IPS-4-SIGNATURE: + ^Sig:(\d+) .+\[(\S+):(\d+) -> + (\S+):(\d+)\] + id, srcip, srcport, dstip, dstport + name, id, srcip, dstip + First time Cisco IOS IDS/IPS module rule fired. + + + + + + cisco-ios + ^(%\w+-\d-\w+): + id + + + diff --git a/openarmor-rules/decoders.d/50-crs-cisco-vpnconcentrator_decoder.xml b/openarmor-rules/decoders.d/50-crs-cisco-vpnconcentrator_decoder.xml new file mode 100644 index 000000000..c51e3841f --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-cisco-vpnconcentrator_decoder.xml @@ -0,0 +1,14 @@ + + + ^\d+? \d{2}/\d{2}/\d{4} \S+ SEV=\d + ^(\S+) RPT=\d+? (\S+) + id, srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-clamd_decoder.xml b/openarmor-rules/decoders.d/50-crs-clamd_decoder.xml new file mode 100644 index 000000000..6abff8059 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-clamd_decoder.xml @@ -0,0 +1,12 @@ + + + ^clamd + + + + ^freshclam + + + diff --git a/openarmor-rules/decoders.d/50-crs-courier_decoder.xml b/openarmor-rules/decoders.d/50-crs-courier_decoder.xml new file mode 100644 index 000000000..e0b0b58e1 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-courier_decoder.xml @@ -0,0 +1,26 @@ + + + ^pop3d|^courierpop3login|^imaplogin|^courier-pop3|^courier-imap + + + + courier + ^LOGIN, + ^user=(\S+), ip=\[(\S+)\]$ + user, srcip + + + + courier + , ip=\[(\S+)\]$ + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-dhcp_decoder.xml b/openarmor-rules/decoders.d/50-crs-dhcp_decoder.xml new file mode 100644 index 000000000..062b5356e --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-dhcp_decoder.xml @@ -0,0 +1,24 @@ + + ^dhcpd$ + + + + dhcpd + ^(\S+) \S+ (\S+) \S+ (\S+) via (\S+)$ + action, srcip, extra_data, extra_data + + + + dhcpd + acking + already acking lease (\S+) + srcip + + + + dhcpd + ^IP address + ^IP address (\S+) + srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-dnsmasq_decoder.xml b/openarmor-rules/decoders.d/50-crs-dnsmasq_decoder.xml new file mode 100644 index 000000000..455743870 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-dnsmasq_decoder.xml @@ -0,0 +1,16 @@ + + + + + ^dnsmasq + + + + dnsmasq + ^\[\d+\]: \d+ (\S+)/\d+ (\S+) (\S+) to (\S+)| + ^\[\d+\]: \d+ (\S+)/\d+ (\S+) (\S+) from (\S+)| + ^\[\d+\]: \d+ (\S+)/\d+ (\S+) (\S+) is (\S+) + srcip, action, url, extra_data + + + diff --git a/openarmor-rules/decoders.d/50-crs-doas_decoder.xml b/openarmor-rules/decoders.d/50-crs-doas_decoder.xml new file mode 100644 index 000000000..a4b69be06 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-doas_decoder.xml @@ -0,0 +1,18 @@ + + + ^doas + + + + doas + ^(\S+) ran| for (\S+): + srcuser + + + + doas + as (\S+): + dstuser + + + diff --git a/openarmor-rules/decoders.d/50-crs-dovecot_decoder.xml b/openarmor-rules/decoders.d/50-crs-dovecot_decoder.xml new file mode 100644 index 000000000..49c02c7ce --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-dovecot_decoder.xml @@ -0,0 +1,79 @@ + + + + ^dovecot + + + + dovecot + ^\w{4}-login: Login: + ^user=\<(\S+)\>, method=\S+, rip=(\S+), lip=(\S+), mpid=\S+, (\S*?)$ + user, srcip, dstip, protocol + + + + dovecot + ^\w{4}-login: Aborted login + : user=\<(\S+)\>, method=\S+, rip=(\S+), lip=(\S+), (\S*)$ + user, srcip, dstip, protocol + + + + dovecot + ^auth\(default\)|auth-worker\(default\) + ^: \S+\((\S+),(\S+)\) + user, srcip + + + + dovecot + ^\w{4}-login: + \(auth failed, \d+? attempts in \d+? secs\): user=\<(\S+)\>, method=\S+, rip=(\S+), lip=(\S+) + user,srcip,dstip + + + + dovecot + ^\w{4}-login: Disconnected: + ^rip=(\S+), lip=(\S+) + srcip, dstip + + + + ^Info$|^Warn$ + + + + dovecot-info + imap-login + Login: user=(\S+), method=.+, rip=(\S+), lip=(\S+) + user, srcip, dstip + + + + dovecot-info + auth\(.+\): \S+\((\S+),(\S+)\): + user, srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-dragon_decoder.xml b/openarmor-rules/decoders.d/50-crs-dragon_decoder.xml new file mode 100644 index 000000000..2bbd4b8bf --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-dragon_decoder.xml @@ -0,0 +1,16 @@ + + + ids + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\| + ^\S+\|(\S+)\| + (\S+)\|(\S+)\| + id, srcip, dstip + name, id, srcip, dstip + + + diff --git a/openarmor-rules/decoders.d/50-crs-dropbear_decoder.xml b/openarmor-rules/decoders.d/50-crs-dropbear_decoder.xml new file mode 100644 index 000000000..6a479f054 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-dropbear_decoder.xml @@ -0,0 +1,37 @@ + + + ^dropbear + + + + + + dropbear + password + for '(\S+)' from (\S+):\d+$ + dstuser, srcip + + + + + + dropbear + nonexistent + from (\S+):\d+$ + srcip + + + + + + dropbear + (\S+) for '(\S+)' with key \S+ (\S+) from (\S+):\d+$ + status,dstuser,extra_data,srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-exim_decoder.xml b/openarmor-rules/decoders.d/50-crs-exim_decoder.xml new file mode 100644 index 000000000..7522234ad --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-exim_decoder.xml @@ -0,0 +1,38 @@ + + + + windows-date-format + authenticator failed + \[(\S+)\]:\d+: \d+ Incorrect authentication data \(set_id=([A-Za-z0-9@_-]+?)\) + srcip,user + + + + windows-date-format + ^SMTP connection from + \[(\S+)\]:\d+ \(TCP/IP connection count + srcip + + + + windows-date-format + ^SMTP connection from + \[(\S+)\]:\d+ lost + srcip + + + + windows-date-format + ^SMTP call from + \[(\S+)\]:\d+ dropped: too many syntax or protocol errors + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-ftpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-ftpd_decoder.xml new file mode 100644 index 000000000..f5d26e64a --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-ftpd_decoder.xml @@ -0,0 +1,42 @@ + + + ^ftpd|^in\.ftpd + + + + ftpd + ^Failed authentication from: \S+ | + ^repeated login failures from + + ^\S+ \[(\S+)\]$|^(\S+) + srcip + + + + ftpd + ^FTP LOGIN REFUSED + \[(\S+)\]$ + srcip + + + + ftpd + from (\S+)$ + srcip + + + + ftpd + ^login \S+ from \S+ failed\. + ^login (\S+) from (\S+) failed\.$ + user, srcip + + + + diff --git a/openarmor-rules/decoders.d/50-crs-grandstream_decoder.xml b/openarmor-rules/decoders.d/50-crs-grandstream_decoder.xml new file mode 100644 index 000000000..0afe3861a --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-grandstream_decoder.xml @@ -0,0 +1,40 @@ + + + + + + ^HT286: \[\w\w:\w\w:\w\w:\w\w:\w\w:\w\w\][()*+,.:;\<=>?\[\]!"'#%&$|{}-]*?.+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]* | + ^HT502: \[\w\w:\w\w:\w\w:\w\w:\w\w:\w\w\][()*+,.:;\<=>?\[\]!"'#%&$|{}-]*?.+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]* | + ^HT503: \[\w\w:\w\w:\w\w:\w\w:\w\w:\w\w\][()*+,.:;\<=>?\[\]!"'#%&$|{}-]*?.+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]* + + + + grandstream-ata + Received + ^(\d+) response for transaction (\d+?)\(([A-Za-z0-9@_-]+)\)$ + status, id, action + + + + grandstream-ata + Account + ^(\d+) (registered), tried \d+; Next registration in \d+ seconds \(\d+/\d+\) on (.+)$ + id, status, extra_data + name, location, extra_data + + + + grandstream-ata + Vinetic:: + ^(startRing) with CID, Attempting to deliver CID (\d+) on port \d+$ + action, id + + + + grandstream-ata + ^(Dialing) (\d+)$ + action, id + + + diff --git a/openarmor-rules/decoders.d/50-crs-horde_decoder.xml b/openarmor-rules/decoders.d/50-crs-horde_decoder.xml new file mode 100644 index 000000000..e2c3316c7 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-horde_decoder.xml @@ -0,0 +1,27 @@ + + + ^\[[A-Za-z0-9@_-]+\] \[imp\] |^\[[A-Za-z0-9@_-]+\] \[horde\] + + + + horde_imp + ^Login success + ^for (\S+) \[(\S+)\] + user, srcip + + + + horde_imp + ^FAILED LOGIN + ^ (\S+) to \S+ as (\S+) + srcip, user + + + + + diff --git a/openarmor-rules/decoders.d/50-crs-imapd_decoder.xml b/openarmor-rules/decoders.d/50-crs-imapd_decoder.xml new file mode 100644 index 000000000..dc574e118 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-imapd_decoder.xml @@ -0,0 +1,15 @@ + + + ^imapd + user=(\S+) .+ \[(\S+)\]$ + user,srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-ipfilter_decoder.xml b/openarmor-rules/decoders.d/50-crs-ipfilter_decoder.xml new file mode 100644 index 000000000..7e4e219c3 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-ipfilter_decoder.xml @@ -0,0 +1,14 @@ + + + firewall + ^ipmon + (\w) (\S+),(\d+?) -> (\S+),(\d+?) PR (\w+) + action,srcip,srcport,dstip,dstport,protocol + + diff --git a/openarmor-rules/decoders.d/50-crs-isakmpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-isakmpd_decoder.xml new file mode 100644 index 000000000..4eaa6ab49 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-isakmpd_decoder.xml @@ -0,0 +1,22 @@ + + + + ^isakmpd + + + + isakmpd + message from + from (\S+) port (\d+) + srcip,srcport + + + + isakmpd + from peer + from peer (\S+):(\d+?)$ + srcip,srcport + + + + diff --git a/openarmor-rules/decoders.d/50-crs-lighttpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-lighttpd_decoder.xml new file mode 100644 index 000000000..37637b065 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-lighttpd_decoder.xml @@ -0,0 +1,10 @@ + + + + ^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d: \( + diff --git a/openarmor-rules/decoders.d/50-crs-mailscanner_decoder.xml b/openarmor-rules/decoders.d/50-crs-mailscanner_decoder.xml new file mode 100644 index 000000000..1148aaacc --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-mailscanner_decoder.xml @@ -0,0 +1,25 @@ + + + ^MailScanner + + + + mailscanner + ^Message \S+ from + ^(\S+) \S+ to \S+ is (\w+) + srcip, action + + + diff --git a/openarmor-rules/decoders.d/50-crs-mptscsi_decoder.xml b/openarmor-rules/decoders.d/50-crs-mptscsi_decoder.xml new file mode 100644 index 000000000..1fbefc5d1 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-mptscsi_decoder.xml @@ -0,0 +1,28 @@ + + + iptables + ^\[ \d+\.\d+\] mptscsih: + ^\[ \d+\.\d+\] (\w+): (\w+): task abort: (\w+) + id,data,status + + + + iptables + ^\[ \d+\.\d+\] mptbase: + ^\[ \d+\.\d+\] (\w+): (\w+):[ ]+[A-Za-z0-9@_-]+ is now (\w+), (\D+)$ + id,data,action,status + + diff --git a/openarmor-rules/decoders.d/50-crs-ms-dhcp_decoder.xml b/openarmor-rules/decoders.d/50-crs-ms-dhcp_decoder.xml new file mode 100644 index 000000000..662bb4e93 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-ms-dhcp_decoder.xml @@ -0,0 +1,29 @@ + + + + + + ^\d{2},\d+?/\d+?/\d{4},\d+?:\d+?:\d+?,| + ^\d{2},\d+?/\d+?/\d{2},\d+?:\d+?:\d+?, + ^(\d{2}),\d+?/\d+?/\d{2,},\d+?:\d+?:\d+?,([A-Za-z0-9@_-]+?),(\S+) + id,extra_data,srcip + + + + + ^\d{5},\d{2}/\d{2}/\d{2},\d{2}:\d{2}:\d{2}, + ^(\d{5}), + id + + + diff --git a/openarmor-rules/decoders.d/50-crs-mysql_decoder.xml b/openarmor-rules/decoders.d/50-crs-mysql_decoder.xml new file mode 100644 index 000000000..9f432af4c --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-mysql_decoder.xml @@ -0,0 +1,12 @@ + + + ^MySQL log: + + + diff --git a/openarmor-rules/decoders.d/50-crs-named_decoder.xml b/openarmor-rules/decoders.d/50-crs-named_decoder.xml new file mode 100644 index 000000000..75de640be --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-named_decoder.xml @@ -0,0 +1,46 @@ + + + ^named + + + + named + : query + client (\S+)#\d+[ ]*?\S*: + srcip,url + + + + named + query: (\S+) IN|query \S+ '(\S+)/ + url + + + + named + ^client + ^(\S+)# + srcip + + + + named + from \[(\S+)\] + srcip + + + + named + for master + for master (\S+):(\d+) \S+ \(source (\S+)#d\+\)$ + dstip,dstport,srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-netscreen_decoder.xml b/openarmor-rules/decoders.d/50-crs-netscreen_decoder.xml new file mode 100644 index 000000000..c4d7fb0a8 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-netscreen_decoder.xml @@ -0,0 +1,46 @@ + + + + ^NetScreen device_id + + + + netscreenfw + firewall + + system-notification-00257 + \(traffic\): + + proto=(\w+) .+action=(\w+) + .+src=(\S+) dst=(\S+) src_port=(\d+) dst_port=(\d+) + protocol, action, srcip, dstip, srcport, dstport + + + + netscreenfw + system-critical-.+ from | + system-alert-.+ from | + system-emergency-.+ From + + system-(\w+?)-(\d+): .+ + from.+(\S+) + action, id, srcip + + + + + netscreenfw + system-(\w+?)-(\d+): + action, id + + + diff --git a/openarmor-rules/decoders.d/50-crs-nginx_decoder.xml b/openarmor-rules/decoders.d/50-crs-nginx_decoder.xml new file mode 100644 index 000000000..d8d88b4df --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-nginx_decoder.xml @@ -0,0 +1,18 @@ + + + ^20\d{2}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[ + + + + nginx-errorlog + , client: \S+, server: \S+, request: "\S+ + , client: (\S+), + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-nsd_decoder.xml b/openarmor-rules/decoders.d/50-crs-nsd_decoder.xml new file mode 100644 index 000000000..8e4b4c756 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-nsd_decoder.xml @@ -0,0 +1,20 @@ + + + + ^nsd + + + + nsd + from (\S+)@| from (\S+) + srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-ntpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-ntpd_decoder.xml new file mode 100644 index 000000000..7453b85ba --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-ntpd_decoder.xml @@ -0,0 +1,30 @@ + + + ^ntpd + + + + ntpd + ^bad peer + ^bad peer \S+ \((\S+)\)$|^bad peer from pool \S+ \((\S+)\)$ + srcip + + + + ntpd + ^recvmsg (\S+): + dstip + + diff --git a/openarmor-rules/decoders.d/50-crs-openarmor_decoder.xml b/openarmor-rules/decoders.d/50-crs-openarmor_decoder.xml new file mode 100644 index 000000000..28affcd3a --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-openarmor_decoder.xml @@ -0,0 +1,52 @@ + + + ^openarmor: + openarmor + + + + openarmor + ^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} openarmor-logcollector + ^\(\d+?\): (.) + extra_data + + + + openarmor + openarmor + ^Agent started: + ^ '(\S+\S)' + extra_data + name, location, extra_data + + + + openarmor + ^openarmor: Alert Level: + openarmorAlert_Decoder + + + + ^openarmor$ + openarmorAlert_Decoder + + + + + + + ^[A-Za-z0-9@_-]{3} [A-Za-z0-9@_-]+?[ ]+?\d+? \d{2}:\d{2}:\d{2} [A-Za-z0-9@_-]+? \d+? /\S+/active-response + /bin/(\S+) (\S+) - (\S+) (\d+?\.\d+?) (\d+) + action, status, srcip, id, extra_data + + + diff --git a/openarmor-rules/decoders.d/50-crs-openbsd-pf_decoder.xml b/openarmor-rules/decoders.d/50-crs-openbsd-pf_decoder.xml new file mode 100644 index 000000000..2b732d6ad --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-openbsd-pf_decoder.xml @@ -0,0 +1,15 @@ + + + firewall + ^pf$ + PF_Decoder + + diff --git a/openarmor-rules/decoders.d/50-crs-openbsd_decoder.xml b/openarmor-rules/decoders.d/50-crs-openbsd_decoder.xml new file mode 100644 index 000000000..479647eb6 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-openbsd_decoder.xml @@ -0,0 +1,77 @@ + + + ^/bsd + + + + bsd_kernel + ^arp + for (\S+) by (\S+) on \S+ + dstip, extra_data + + + + + + userdel + user removed: name=(\S+)$ + srcuser + + + + + + + + ^mountd + + + + mountd + from host + (\S+) port \d+?$ + srcip + + + + + + + + + groupdel + ^group deleted: name=(\S+)$ + extra_data + + + + + + \[\d+/[A-Za-z0-9@_-]+/\d+:\d+:\d+:\d+ -\d+\] " + ^(\S+) (\S+) \S+ \S+ \[\d+/[A-Za-z0-9@_-]+/\d+:\d+:\d+:\d+ -\d+\] "(\S+) (\S+) HTTP/\d\.\d" (\d+?) \d$ + url, srcip, protocol, url, status + web-log + + + diff --git a/openarmor-rules/decoders.d/50-crs-openldap_decoder.xml b/openarmor-rules/decoders.d/50-crs-openldap_decoder.xml new file mode 100644 index 000000000..7666a03df --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-openldap_decoder.xml @@ -0,0 +1,44 @@ + + + ^slapd + + + + + openldap + ACCEPT + ^conn=(\d+) fd=\d+ ACCEPT from IP=(\S+): + id, srcip + + + + + openldap + BIND + ^conn=(\d+) op=\d+ BIND dn="[A-Za-z0-9@_-]+=([A-Za-z0-9@_-]+), + id, dstuser + + + + + + openldap + RESULT + ^conn=(\d+) op=\d+ RESULT + id + + + diff --git a/openarmor-rules/decoders.d/50-crs-opensmtpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-opensmtpd_decoder.xml new file mode 100644 index 000000000..7ce13fed4 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-opensmtpd_decoder.xml @@ -0,0 +1,33 @@ + + + + ^smtpd + + + + smtpd + ^client + ^client (\S+) + srcip + + + + smtpd + relay= + relay=\S+ \[(\S+)\], + srcip + + + + smtpd + ^smtp-in: + ^(\S+) + status + + + + smtpd + => (\d+) + action + + diff --git a/openarmor-rules/decoders.d/50-crs-owncloud_decoder.xml b/openarmor-rules/decoders.d/50-crs-owncloud_decoder.xml new file mode 100644 index 000000000..8f7a2a053 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-owncloud_decoder.xml @@ -0,0 +1,65 @@ + + + + ^\{"reqId":"\S+","message":".+","level":\d,"time":".+"\}$|^\{"app":"\S+","message":".+","level":\d,"time":".+"\}$|^\{"reqId":"\S+","level":\d,"time":"\S+","message":".+"\}$ + + + + + ^ownCloud + + + + owncloud + Login failed: user + ^'([A-Za-z0-9@_-]+)' , wrong password, IP:(\S+) + + user, srcip + + + + owncloud + + Login failed: + ^'([A-Za-z0-9@_-]+)' \(Remote IP: '(\S+)'|^'([A-Za-z0-9@_-]+)' \(Remote IP: '(\S+)\) + user, srcip + + + + owncloud + + Passed filename is not valid, might be malicious + ;ip:"(\S+)"|;ip:\\"(\S+)\\" + + srcip + + + + owncloud + ","level": + ^(\d)," + status + + + diff --git a/openarmor-rules/decoders.d/50-crs-pix_decoder.xml b/openarmor-rules/decoders.d/50-crs-pix_decoder.xml new file mode 100644 index 000000000..f7c36c3f6 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-pix_decoder.xml @@ -0,0 +1,156 @@ + + + ^%PIX-|^[A-Za-z0-9@_-]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}: %PIX-| + ^%ASA-|^[A-Za-z0-9@_-]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}: %ASA-| + ^%FWSM-|^[A-Za-z0-9@_-]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}: %FWSM- + + + + pix + firewall + ^2-106001 + ^(\S+): [A-Za-z0-9@_-]+ ([A-Za-z0-9@_-]+) \S+ (\S+) from + (\S+)/(\S+) to (\S+)/(\S+) + id, protocol, action, srcip, srcport, dstip, dstport + + + + pix + firewall + ^3-710003|^7-710002|^7-710005 + ^(\S+): (\S+) [A-Za-z0-9@_-]+ ([A-Za-z0-9@_-]+) .+from + (\S+)/(\S+) to [A-Za-z0-9@_-]+:(\S+)/(\S+) + id, protocol, action, srcip, srcport, dstip, dstport + + + + pix + firewall + ^4-106023 + ^(\S+): ([A-Za-z0-9@_-]+) ([A-Za-z0-9@_-]+) src [A-Za-z0-9@_-]+: + (\S+)/(\S+) dst [A-Za-z0-9@_-]+?:(\S+)/(\S+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^4-106019 + ^(\S+): IP packet from (\S+) to + (\S+), protocol ([A-Za-z0-9@_-]+) ([A-Za-z0-9@_-]+) + id, srcip, dstip, protocol, action + + + + + pix + firewall + ^2-106006|^2-106007 + ^(\S+): ([A-Za-z0-9@_-]+) \S+ ([A-Za-z0-9@_-]+) from + (\S+)/(\d+?) to (\S+)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^6-106015 + ^(\S+): ([A-Za-z0-9@_-]+) ([A-Za-z0-9@_-]+) \(no connection\) from (\S+)/ + (\d+) to (\S+)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^6-305012 + ^(\S+): ([A-Za-z0-9@_-]+) [A-Za-z0-9@_-]+ ([A-Za-z0-9@_-]+) translation + from [A-Za-z0-9@_-]+:(\S+)/(\d+) to [A-Za-z0-9@_-]+:(\S)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + firewall + ^3-106011|^3-106010 + ^(\S+): ([A-Za-z0-9@_-]+) .+ ([A-Za-z0-9@_-]+) src + [A-Za-z0-9@_-]+?:(\S+)/(\d+?) dst [A-Za-z0-9@_-]+?:(\S+)/(\d+) + id, action, protocol, srcip, srcport, dstip, dstport + + + + pix + ^5-304001: + ^(\S+): (\S+) Accessed URL + (\S+):(http[A-Za-z0-9@_-]*://.+)| + ^(\S+): (\S+) Accessed URL (\S+): + id, srcip, dstip, url + + + + pix + ^5-304002: + ^(\S+): Access (denied) URL (http[A-Za-z0-9@_-]*://.+) + SRC (\S+) DEST (\S+) on interface + id, action, url, srcip, dstip + + + + pix + ^2-106012: |^2-106017: | + ^2-106020|^1-106021|^1-106022| + ^4-4000 + ^(\S+): .+ from (\S+) + id, srcip + + + + pix + ^6-308001 + ^(\S+): .+ (\S+) + id, srcip + + + + pix + ^6-605004|^6-605005 + ^(\S+): Login (\S+) from (\S+)/(\d+?) .+user "([A-Za-z0-9@_-]+?)" + id, action, srcip, srcport, user + + + + pix + ^(\S+): + id + + + diff --git a/openarmor-rules/decoders.d/50-crs-portsentry_decoder.xml b/openarmor-rules/decoders.d/50-crs-portsentry_decoder.xml new file mode 100644 index 000000000..c6066e939 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-portsentry_decoder.xml @@ -0,0 +1,20 @@ + + + ^portsentry + + + + portsentry + attackalert: Connect from host: + (\S+)/\S+ to (\S+) port: (\d+?)$ + srcip,protocol,dstport + + + + portsentry + is already blocked\. Ignoring$ + Host: (\S+) is + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-postfix_decoder.xml b/openarmor-rules/decoders.d/50-crs-postfix_decoder.xml new file mode 100644 index 000000000..3edf282ac --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-postfix_decoder.xml @@ -0,0 +1,29 @@ + + + + ^postfix + + + + true + postfix + ^NOQUEUE: reject: \w{4} from + \[(\S+)\]:\d+?: (\d+?) |\[(\S+)\]:(\d+?): |\[(\S+)\]: (\d+?) |\[(\S+)\]:(\d+?): + srcip,id + + + + postfix + ^warning: \S+: SASL + ^warning: \S+\[(\S+)\]: + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-postgresql_decoder.xml b/openarmor-rules/decoders.d/50-crs-postgresql_decoder.xml new file mode 100644 index 000000000..f08e0fc5f --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-postgresql_decoder.xml @@ -0,0 +1,11 @@ + + + ^\[\d{4}-\d{2}-\d{2} \S+ [A-Za-z0-9@_-]+?\] + ^\S+ ([A-Za-z0-9@_-]+?): + status + + diff --git a/openarmor-rules/decoders.d/50-crs-proftpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-proftpd_decoder.xml new file mode 100644 index 000000000..58a36ab67 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-proftpd_decoder.xml @@ -0,0 +1,30 @@ + + + ^proftpd + + + + proftpd + : Login successful + ^\S+ \(\S+\[(\S+)\]\)[ ]*?\S [A-Za-z0-9@_-]+? (\S+): + Login successful + srcip, user + name, user, srcip, location + + + + proftpd + ^\S+ \(\S+\[(\S+)\]\) + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-proxmox_decoder.xml b/openarmor-rules/decoders.d/50-crs-proxmox_decoder.xml new file mode 100644 index 000000000..494b69165 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-proxmox_decoder.xml @@ -0,0 +1,61 @@ + + + + + ^pvedaemon + + + + ^pvestatd + + + + ^pveproxy + + + + ^pvepw-logger + + + + pvedaemon + authentication failure; + ^rhost=(\S+) user=(\S+)@pam msg=|^rhost=(\S+) user=(\S+)@pve msg= + srcip, user + + + + pvedaemon + successful auth for user ' + ^(\S+)@pam'$|^(\S+)@pve'$ + user + + + diff --git a/openarmor-rules/decoders.d/50-crs-psad_decoder.xml b/openarmor-rules/decoders.d/50-crs-psad_decoder.xml new file mode 100644 index 000000000..52cbc25d4 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-psad_decoder.xml @@ -0,0 +1,39 @@ + + + + psad + + + + psad + ^scan detected + (\S+) -> (\S+) .+ DL: (\d) + srcip,dstip,status + + + + psad + ^message repeated + (\S+) -> (\S+) .+ DL: (\d) + srcip,dstip,status + + + + psad + signature match: + src: (\S+) signature match: .+ port: (\d+) + srcip,dstport + + + diff --git a/openarmor-rules/decoders.d/50-crs-pure-ftpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-pure-ftpd_decoder.xml new file mode 100644 index 000000000..affc4acf0 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-pure-ftpd_decoder.xml @@ -0,0 +1,42 @@ + + + ^pure-ftpd + + + + pure-ftpd + ^\S+ \[INFO\] \S+ is now logged in + ^\(\?@(\S+)\) \[INFO\] (\S+) is now logged in + srcip, user + name, user, srcip, location + + + + pure-ftpd + ^\((\S+)@(\S+)\) \[ + user,srcip + + + + + + ^\S+ - \S+ \[\d{2}/\S{3}/\d{4}:\d{2}:\d{2}:\d{2} \S\d{4}\] "[A-Za-z0-9@_-]+? \S+" + ^(\S+) - (\S+) \[\d{2}/\S{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4}\] "(\S+) (.+) (\d+) \d+$ + extra_data,dstuser,action,url,status + + + + diff --git a/openarmor-rules/decoders.d/50-crs-raccoon_decoder.xml b/openarmor-rules/decoders.d/50-crs-raccoon_decoder.xml new file mode 100644 index 000000000..b499fb78f --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-raccoon_decoder.xml @@ -0,0 +1,25 @@ + + + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}: + + + + racoon + true + ^ERROR: couldn't find the pskey + ^for (\S+) + srcip + + + + racoon + ^([A-Za-z0-9@_-]+?): + action + + + + diff --git a/openarmor-rules/decoders.d/50-crs-roundcube_decoder.xml b/openarmor-rules/decoders.d/50-crs-roundcube_decoder.xml new file mode 100644 index 000000000..cb71b59ab --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-roundcube_decoder.xml @@ -0,0 +1,46 @@ + + + + + ^roundcube + + + + ^\[\d{2}-[\w]{3}-\d{4} \d{2}:\d{2}:\d{2} \S+\] + + + + roundcube + Successful login for + ^(\S+) \(id \d+\) from (\S+)$|^(\S+) \(ID: \d+\) from (\S+) + user, srcip + + + + roundcube + \] \w+ Error: Authentication + ^for (\S+) failed + user + + + + roundcube + > \w+ Error: Login failed |> Failed login + ^for (\S+) from (\S+). |^for (\S+) from (\S+) in session + user, srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-rshd_decoder.xml b/openarmor-rules/decoders.d/50-crs-rshd_decoder.xml new file mode 100644 index 000000000..f25679def --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-rshd_decoder.xml @@ -0,0 +1,17 @@ + + + ^rshd$ + + + + rshd + ^Connection from (\S+) on illegal port$ + srcip + + + + diff --git a/openarmor-rules/decoders.d/50-crs-sendmail_decoder.xml b/openarmor-rules/decoders.d/50-crs-sendmail_decoder.xml new file mode 100644 index 000000000..9bca80d0e --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-sendmail_decoder.xml @@ -0,0 +1,56 @@ + + + ^sendmail|^sm-mta|^sm-msp-queue + + + + sendmail-reject + ^\S+: rejecting commands from + ^ \S+ \[(\S+)\] + srcip + + + + sendmail-reject + relay=\[ + ^(\S+)\] + srcip + + + + sendmail-reject + relay=\S+ \[ + ^(\S+)\] + srcip + + + + + ^smf-sav + ^sender check failed| + ^sender check tempfailed + ^ \(cached\): \S+, (\S+),| + ^: \S+, (\S+), + srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-smbd_decoder.xml b/openarmor-rules/decoders.d/50-crs-smbd_decoder.xml new file mode 100644 index 000000000..92b2a7b8e --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-smbd_decoder.xml @@ -0,0 +1,45 @@ + + + + ^smbd + + + + smbd + User name: + ^ (\S+)\. + user + + + + smbd + from \((\S+)\) + srcip + + + + smbd + from (\S+)$ + from (\S+)$ + srcip + + + + smbd + to client \S+\. + to client (\S+)\. + srcip + + + + ^nmbd + + diff --git a/openarmor-rules/decoders.d/50-crs-snort_decoder.xml b/openarmor-rules/decoders.d/50-crs-snort_decoder.xml new file mode 100644 index 000000000..f4a104b12 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-snort_decoder.xml @@ -0,0 +1,38 @@ + + + + ^snort + + + + ids + ^\[\*\*\] \[\d+:\d+:\d+\] + + + + snort + ids + ^\[\*\*\] \[|^\[Drop\] \[\*\*\] \[|^\[ + (\d+:\d+:\d+)\] .+ (\S+?):?\d* -> ([^:]+) + id,srcip,dstip + name,id,srcip,dstip + + + + diff --git a/openarmor-rules/decoders.d/50-crs-solaris-bsm_decoder.xml b/openarmor-rules/decoders.d/50-crs-solaris-bsm_decoder.xml new file mode 100644 index 000000000..b589316da --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-solaris-bsm_decoder.xml @@ -0,0 +1,28 @@ + + + ^audit$ + + + + solaris_bsm + [A-Za-z0-9@_-]+? session \d+? by + ([A-Za-z0-9@_-]+) session \d+ by + status + + + + solaris_bsm + ^ \S+ as \S+:\S+ from (\S+) + srcip + + + + diff --git a/openarmor-rules/decoders.d/50-crs-sonicwall_decoder.xml b/openarmor-rules/decoders.d/50-crs-sonicwall_decoder.xml new file mode 100644 index 000000000..c1e1e5dc3 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-sonicwall_decoder.xml @@ -0,0 +1,15 @@ + + + firewall + ^id=[A-Za-z0-9@_-]+? sn=[A-Za-z0-9@_-]+? time=\S+ \S+ fw=\S+ pri=\d + SonicWall_Decoder + + + diff --git a/openarmor-rules/decoders.d/50-crs-squid_decoder.xml b/openarmor-rules/decoders.d/50-crs-squid_decoder.xml new file mode 100644 index 000000000..1a40e137d --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-squid_decoder.xml @@ -0,0 +1,17 @@ + + + squid + ^\d+? \S+ + ^\d+? (\S+) ([A-Za-z0-9@_-]+?)/(\d+?) \d+? [A-Za-z0-9@_-]+? (\S+) + srcip,action,id,url + + + diff --git a/openarmor-rules/decoders.d/50-crs-sshd_decoder.xml b/openarmor-rules/decoders.d/50-crs-sshd_decoder.xml new file mode 100644 index 000000000..ac29bc40c --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-sshd_decoder.xml @@ -0,0 +1,259 @@ + + + ^sshd + + + + sshd + ^Accepted + ^ \S+ for (\S+) from (\S+) port + user, srcip + name, user, location + + + + sshd + ^User \S+ from + ^User (\S+) from (\S+) + user, srcip + + + + sshd + ^User + ^(\S+), coming from (\S+), + user, srcip + name, user, location + + + + sshd + ^Postponed keyboard-interactive|^Failed keyboard-interactive + user (\S+) from (\S+) port (\d+) + user, srcip, srcport + + + + sshd + ^Failed \S+ for invalid user|^Failed \S+ for illegal user + from (\S+) port \d+ \w+$ + srcip + + + + sshd + ^Failed \S+ + ^for (\S+) from (\S+) port \d+ + user, srcip + + + + sshd + ^error: PAM: Authentication \w+ + ^for (\S+) from (\S+)$ + user, srcip + + + + sshd + ^error: PAM: + user (\S+) from (\S+) + user, srcip + + + + sshd + ^reverse mapping checking + ^\w+ for \S+ \[(\S+)\] |^\w+ for (\S+) + srcip + + + + sshd + ^Invalid user|^Illegal user + from (\S+) + srcip + + + + sshd + ^scanned from + (\S+) + srcip + + + + sshd + ^Received disconnect + ^from (\S+): |^from (\S+) + srcip + + + + sshd + ^Disconnected from invalid user + \S+ (\S+) + srcip + + + + sshd + ^Connection closed by + user (\S+) (\S+) + user, srcip + + + + sshd + ^Unable to negotiate with + ^(\S+) port (\d+) + srcip, srcport + + + + sshd + ^Protocol major versions differ for + ^(\S+) + srcip + + + + + + sshd + ^Did not receive identification |^Bad protocol version + from (\S+)$| from (\S+) port (\d+?)$ + srcip,srcport + + + + sshd + ^refused connect + ^from (\S+)$|^from \S+ \((\S+[A-Za-z0-9@_-]+?)\)$|^from \S+ \((\S+::)\)$ + srcip + + + + sshd + ^Connection closed + ^by (\S+)$ + srcip + + + + sshd + ^Received disconnect + ^from (\S+): + srcip + + + + + + sshd + ^pam_ldap: + user "uid=(\S+),ou=[A-Za-z0-9@_-]+?,dc=[A-Za-z0-9@_-]+?,dc=[A-Za-z0-9@_-]+" + user + + + + sshd + fatal: Unable to negotiate with + ^(\S+) port (\d+?): |^(\S+): + srcip, srcport + + + + sshd + rhost=\S+[ ]+?user=\S+ + rhost=(\S+)[ ]+?user=(\S+) + srcip, user + + + + + + + sshd + exceeded for + (\S+) from (\S+) port (\d+) + user, srcip, srcport + + + diff --git a/openarmor-rules/decoders.d/50-crs-su_decoder.xml b/openarmor-rules/decoders.d/50-crs-su_decoder.xml new file mode 100644 index 000000000..a60b15f78 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-su_decoder.xml @@ -0,0 +1,60 @@ + + + ^su$ + + + + su + ^'su + ^'su (\S+)' \S+ for (\S+) on \S+$ + dstuser, srcuser + name, srcuser, location + + + + su + pam_ldap + user "uid=(\S+), + user + + + + ^SU \S+ \S+ + ^\S \S+ (\S+)-(\S+)$ + srcuser, dstuser + name, srcuser, location + + + + su + ^FAILED SU + ^\(to (\S+) (\S+) on + dstuser, srcuser + + + + + su + + ^BAD SU (\S+) to (\S+) on| + ^failed: \S+ changing from (\S+) to (\S+)| + ^\S \S+ (\S+)[()*+,.:;\<=>?\[\]!"'#%&$|{}-](\S+)$|^(\S+) to (\S+) on + srcuser, dstuser + name, srcuser, location + + + + diff --git a/openarmor-rules/decoders.d/50-crs-sudo_decoder.xml b/openarmor-rules/decoders.d/50-crs-sudo_decoder.xml new file mode 100644 index 000000000..e6beaeb54 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-sudo_decoder.xml @@ -0,0 +1,18 @@ + + + ^sudo + ^[ ]*?(\S+)[ ]:[ ]TTY=\S+[ ];[ ]PWD=(\S+)[ ];[ ]USER=(\S+)[ ];[ ]COMMAND=(.+)$| + ^[ ]*?(\S+)[ ]:[ ]TTY=\S+[ ];[ ]PWD=(\S+)[ ];[ ]USER=(\S+)[ ];[ ]TSID=\S+[ ];[ ]COMMAND=(.+)$ + dstuser,url,srcuser,status + name,dstuser,location + First time user executed the sudo command + + diff --git a/openarmor-rules/decoders.d/50-crs-suhosin_decoder.xml b/openarmor-rules/decoders.d/50-crs-suhosin_decoder.xml new file mode 100644 index 000000000..2f111f51e --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-suhosin_decoder.xml @@ -0,0 +1,15 @@ + + + ^suhosin + ids + ^ALERT - (.+) \(attacker '(\S+)', + id, srcip + name, location, id + + diff --git a/openarmor-rules/decoders.d/50-crs-symantec-av_decoder.xml b/openarmor-rules/decoders.d/50-crs-symantec-av_decoder.xml new file mode 100644 index 000000000..36071dea8 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-symantec-av_decoder.xml @@ -0,0 +1,15 @@ + + + ^[A-Za-z0-9@_-]{12}, + ^(\d+?),\d+?,\d+?,(\S+),(.+), + id, system_name, extra_data + name, location, id, system_name, extra_data + + + diff --git a/openarmor-rules/decoders.d/50-crs-symantec-websecurity_decoder.xml b/openarmor-rules/decoders.d/50-crs-symantec-websecurity_decoder.xml new file mode 100644 index 000000000..f30a8b2c7 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-symantec-websecurity_decoder.xml @@ -0,0 +1,13 @@ + + + ^\d{8},\d{3,}, + SymantecWS_Decoder + + + diff --git a/openarmor-rules/decoders.d/50-crs-sysmon_decoder.xml b/openarmor-rules/decoders.d/50-crs-sysmon_decoder.xml new file mode 100644 index 000000000..84ee32d42 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-sysmon_decoder.xml @@ -0,0 +1,22 @@ + + + +windows +INFORMATION\(1\) +Image: (.*?) [ ]*?CommandLine: .*? [ ]*?User: (.*?) [ ]*?LogonGuid: \S*? [ ]*?LogonId: \S*? [ ]*?TerminalSessionId: \S*? [ ]*?IntegrityLevel: .*?HashType: \S*? [ ]*?Hash: (\S*?) [ ]*?ParentProcessGuid: \S*? [ ]*?ParentProcessID: \S*? [ ]*?ParentImage: (.*?) [ ]*?ParentCommandLine: +status,user,url,data + + + diff --git a/openarmor-rules/decoders.d/50-crs-telnetd_decoder.xml b/openarmor-rules/decoders.d/50-crs-telnetd_decoder.xml new file mode 100644 index 000000000..be198893d --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-telnetd_decoder.xml @@ -0,0 +1,23 @@ + + + ^telnetd|^in\.telnetd + + + + telnetd + from (\S+)$ + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-trend-osce_decoder.xml b/openarmor-rules/decoders.d/50-crs-trend-osce_decoder.xml new file mode 100644 index 000000000..e46366d33 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-trend-osce_decoder.xml @@ -0,0 +1,17 @@ + + + + ^20\d{6}\<;> + ^\d+?\<;>\S+\<;>(\d+?)\<; + id + + + + + diff --git a/openarmor-rules/decoders.d/50-crs-unbound_decoder.xml b/openarmor-rules/decoders.d/50-crs-unbound_decoder.xml new file mode 100644 index 000000000..5bd334036 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-unbound_decoder.xml @@ -0,0 +1,25 @@ + + + + + ^unbound + + + + unbound + info: (\S+) (\S+)\. A IN$| info: (\S+) (\S+) AAAA IN$ + srcip,url + + + diff --git a/openarmor-rules/decoders.d/50-crs-vm-pop3d_decoder.xml b/openarmor-rules/decoders.d/50-crs-vm-pop3d_decoder.xml new file mode 100644 index 000000000..941e6cb7b --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-vm-pop3d_decoder.xml @@ -0,0 +1,16 @@ + + + ^vm-pop3d + + + + vm-pop3d + ^User ' + ^(\S+)' - [A-Za-z0-9@_-]+? auth, + from=(\S+)$ + user, srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-vmware-esx_decoder.xml b/openarmor-rules/decoders.d/50-crs-vmware-esx_decoder.xml new file mode 100644 index 000000000..1d01bfe52 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-vmware-esx_decoder.xml @@ -0,0 +1,46 @@ + + + ^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} '\S+' \d+? + + + + vmware + ^([A-Za-z0-9@_-]+?)\] \S+ \S+ + status + + + + vmware + ^: User ([A-Za-z0-9@_-]+?)@(\S+) + logged |^: Failed login \w+ for ([A-Za-z0-9_-]+)@(\S+) + user, srcip + + + + vmware + + + + vmware-syslog + ^Accepted|^Rejected + ^ \S+ for user (\S+) from (\S+)$ + user, srcip + + + + vmware-syslog + ^login from + ^(\S+) as + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-vpopmail_decoder.xml b/openarmor-rules/decoders.d/50-crs-vpopmail_decoder.xml new file mode 100644 index 000000000..55ea9c66a --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-vpopmail_decoder.xml @@ -0,0 +1,40 @@ + + + ^vpopmail + + + + vpopmail + ^vchkpw-\S+: password fail + (\S+)@\S+:(\S+)$ + user, srcip + + + + vpopmail + ^vchkpw-\S+: vpopmail user not + ^found (\S+):(\S+)$ + user, srcip + + + + vpopmail + ^vchkpw-\S+: null password + ^given (\S+):(\S+)$ + user, srcip + + + + vpopmail + ^vchkpw-\S+: \(\S+\) login + ^success (\S+):(\S+)$ + user, srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-vsftpd_decoder.xml b/openarmor-rules/decoders.d/50-crs-vsftpd_decoder.xml new file mode 100644 index 000000000..b8a4c1e41 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-vsftpd_decoder.xml @@ -0,0 +1,68 @@ + + + + + + ^[A-Za-z0-9@_-]{3} [A-Za-z0-9@_-]{3}[ ]+?\d+? \S+ \d+? \[pid \d+?\] + + + + ^vsftpd + ^[A-Za-z0-9@_-]{3} [A-Za-z0-9@_-]{3}[ ]+?\d+? \S+ \d+? \[pid \d+?\] + + + + vsftpd + LOGIN: + \[(\S+)\] (\S+ LOGIN): Client "(\S+[A-Za-z0-9@_-])"$ + user,status,srcip + + + + vsftpd + ^CONNECT: + (CONNECT): Client "(\S+[A-Za-z0-9@_-]+?)"$ + action,srcip + + + + vsftpd + \[(\S+)\] (OK \S+): Client "(\S+)", "(.+)".* + user,status,srcip,url + + + + vsftpd + Client "(\S+[A-Za-z0-9@_-])"$ + srcip + + + diff --git a/openarmor-rules/decoders.d/50-crs-web-accesslog_decoder.xml b/openarmor-rules/decoders.d/50-crs-web-accesslog_decoder.xml new file mode 100644 index 000000000..5711f8614 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-web-accesslog_decoder.xml @@ -0,0 +1,23 @@ + + + web-log + ^\S+ \S+ \S+ \[\S+ \S\d+\] "\w+ \S+ HTTP\S+" + ^(\S+) \S+ (\S+) \[\S+ \S\d+\] + "(\w+) (\S+) HTTP\S+" (\d+) + srcip, srcuser, action, url, id + + + diff --git a/openarmor-rules/decoders.d/50-crs-windows-ntsyslog_decoder.xml b/openarmor-rules/decoders.d/50-crs-windows-ntsyslog_decoder.xml new file mode 100644 index 000000000..e1866073b --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-windows-ntsyslog_decoder.xml @@ -0,0 +1,16 @@ + + + windows + ^security\[[A-Za-z0-9@_-]+?\] \d+? + ^([A-Za-z0-9@_-]+?)\[([A-Za-z0-9@_-]+?)\] (\d+?) + extra_data, status, id + + + + diff --git a/openarmor-rules/decoders.d/50-crs-windows-snare_decoder.xml b/openarmor-rules/decoders.d/50-crs-windows-snare_decoder.xml new file mode 100644 index 000000000..0ddaea213 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-windows-snare_decoder.xml @@ -0,0 +1,35 @@ + + + windows + ^MSWinEventLog\t\d\t.+\t\d+?\t[A-Za-z0-9@_-]{3}\S+ [A-Za-z0-9@_-]{3} \d{2} \d{2} + ^:\d{2}:\d{2} \d{4}\t(\d+?)\t(.+) + \t(.+)\t.+\t(.+)\t(.+)\t + id, extra_data, user, status, system_name + name, id, location, user, system_name + + + diff --git a/openarmor-rules/decoders.d/50-crs-windows_decoder.xml b/openarmor-rules/decoders.d/50-crs-windows_decoder.xml new file mode 100644 index 000000000..e55a7fda4 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-windows_decoder.xml @@ -0,0 +1,54 @@ + + + windows + ^WinEvtLog + + + + windows + windows + ^.+: ([A-Za-z0-9@_-]+?)\((\d+?)\): (.+): + (.+): .+: (\S+): + status, id, extra_data, user, system_name + name, location, system_name + + + + windows + windows + Source Network Address: (\S+) + srcip + + + + + windows + windows + Account Name:[ ]+?([A-Za-z0-9@_-]+?)[ ]+?Account + user + + + + windows + windows + Account Domain:[ ]+?([A-Za-z0-9@_-]+?)[ ]+?Logon ID: + extra_data + + diff --git a/openarmor-rules/decoders.d/50-crs-wordpress_decoder.xml b/openarmor-rules/decoders.d/50-crs-wordpress_decoder.xml new file mode 100644 index 000000000..8f1d7f7cb --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-wordpress_decoder.xml @@ -0,0 +1,14 @@ + + + ^WPsyslog|^wpcore + ^\[ + ^(\S+) + srcip + + diff --git a/openarmor-rules/decoders.d/50-crs-zeus_decoder.xml b/openarmor-rules/decoders.d/50-crs-zeus_decoder.xml new file mode 100644 index 000000000..a347f3a61 --- /dev/null +++ b/openarmor-rules/decoders.d/50-crs-zeus_decoder.xml @@ -0,0 +1,12 @@ + + + ^\[\d{2}/[A-Za-z0-9@_-][A-Za-z0-9@_-][A-Za-z0-9@_-]/\d{4}:\d{2}:\d{2}:\d{2} \S+\] + host=(\S+), + srcip + + diff --git a/openarmor-rules/decoders.d/60-crs-cowrie_decoder.xml b/openarmor-rules/decoders.d/60-crs-cowrie_decoder.xml new file mode 100644 index 000000000..ed35f99aa --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-cowrie_decoder.xml @@ -0,0 +1,33 @@ + + + + + + + + cowrie\.sessions + + + + cowrie + "SSH login attempted + ^\{"direction": "\S+", "protocol": "(\S+)", "ids_type": "(\S+)", "ssh_username": "(\S+)", "app": "cowrie", "transport": "\S+", "dest_port": (\d+), "src_port": (\d+), "severity": "\S+", "timestamp": "\d{4}-\d{2}-\d{2}", "vendor_product": "Cowrie", "sensor": \S+, "src_ip": "(\S+)", "ssh_password": "\S+", "signature": "(.+)", "ssh_version": .+, "type": "cowrie\.sessions", "dest_ip": "(\S+)"\} + protocol, extra_data, user, dstport, srcport, srcip, action, dstip + + + + cowrie + "SSH session on cowrie honeypot + ^\{"direction": "\S+", "protocol": "(\S+)", "ids_type": "(\S+)", "timestamp": "\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}.\d+", "vendor_product": "Cowrie", "type": "cowrie\.sessions", "app": "cowrie", "src_ip": "(\S+)", "dest_port": (\d+?), "signature": "(.+)", "ssh_version": .+, "src_port": (\d+?), "dest_ip": "(\S+)", "sensor": \S+, "transport": "\S+", "severity": "\S+"\} + protocol, extra_data, srcip, dstport, action, srcport, dstip + + + + + cowrie + "command attempted on cowrie honeypot + ^\{"direction": "\S+", "protocol": "(\S+)", "ids_type": "(\S+)", "timestamp": "\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}.\d+", "app": "cowrie", "transport": "\S+", "dest_port": (\d+?), "src_port": (\d+?), "severity": "\S+", "vendor_product": "Cowrie", "sensor": \S+, "src_ip": "(\S+)", "command": "\S+", "signature": "(.+)", "ssh_version": .+, "type": "cowrie\.sessions", "dest_ip": "(\S+)"\} + protocol, extra_data, dstport, srcport, srcip, action, dstip + + + diff --git a/openarmor-rules/decoders.d/60-crs-dionaea_decoder.xml b/openarmor-rules/decoders.d/60-crs-dionaea_decoder.xml new file mode 100644 index 000000000..c9c5ce1f8 --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-dionaea_decoder.xml @@ -0,0 +1,10 @@ + + + + + dionaea\.connections + ^\{"direction": "(\S+)", "protocol": "(\S+)", "ids_type": "\S+", "timestamp": "\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}.\d+", "dionaea_action": "(\S+)", "type": "dionaea\.connections", "app": "dionaea", "src_ip": "(\S+)", "vendor_product": "Dionaea", "dest_port": (\d+), "signature": ".+", "src_port": (\d+?), "dest_ip": "(\S+)", "sensor": \S+, "transport": "\S+", "severity": "\S+"\} + extra_data, protocol, action, srcip, dstport, srcport, dstip + + + diff --git a/openarmor-rules/decoders.d/60-crs-iis-ftp_decoder.xml b/openarmor-rules/decoders.d/60-crs-iis-ftp_decoder.xml new file mode 100644 index 000000000..ae8293479 --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-iis-ftp_decoder.xml @@ -0,0 +1,17 @@ + + + windows-date-format + true + ^\S+ \S+ MSFTPSVC + ^(\S+) (\S+) \S+ \S+ \S+ + \d+ \[\d+\](\S+) \S+ \S+ (\d+) + srcip,user,action,id + + + + diff --git a/openarmor-rules/decoders.d/60-crs-iis-smtp_decoder.xml b/openarmor-rules/decoders.d/60-crs-iis-smtp_decoder.xml new file mode 100644 index 000000000..8490fdc0d --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-iis-smtp_decoder.xml @@ -0,0 +1,17 @@ + + + windows-date-format + true + ^\S+ \S+ SMTPSVC + ^(\S+) \S+ \S+ \S+ \S+ + \d+ (\S+) \S+ \S+ (\d+) + srcip, action, id + + + + diff --git a/openarmor-rules/decoders.d/60-crs-iis-web_decoder.xml b/openarmor-rules/decoders.d/60-crs-iis-web_decoder.xml new file mode 100644 index 000000000..94154515b --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-iis-web_decoder.xml @@ -0,0 +1,58 @@ + + + windows-date-format + web-log + true + ^\S+ \S+ W3SVC + ^(\S+) \S+ \S+ \S+ \S+ + \d+ \S+ (\S+ \S+) (\d+) + srcip,url,id + + + + + + windows-date-format + web-log + true + ^W3SVC\d+ \S+ \S+ \S+ + ^(\S+ \S+) \d+ \S+ (\S+) + \S+ \S+ \S+ \S+ \S+ (\d+) + url, srcip, id + + + + + + + windows-date-format + web-log + true + ^\S+ GET |^\S+ POST + (\S+ \S*) .* (\S+) \S*.* (\d{3}) \S+ \S+ \S+ + url,srcip,id + + + + diff --git a/openarmor-rules/decoders.d/60-crs-kaspersky_decoder.xml b/openarmor-rules/decoders.d/60-crs-kaspersky_decoder.xml new file mode 100644 index 000000000..921476447 --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-kaspersky_decoder.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + ^kesl + + + + kesl + ^""EventType": "\S+","EventId": "\d+?","TaskName": "\S+","TaskId": "\d+?","AVBasesDate": "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"" + ^""EventType": "(\S+)","EventId": "(\d+?)","TaskName": "(\S+)","TaskId": "\d+?","AVBasesDate": "(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})"" + status, id, action, extra_data + + + + kesl + ^""EventType": "\S+","EventID": "\d+","DetectName": "\S+","DetectType": "\S+","DetectCertainty": "\S+","DetectSource": "\S+","FileName": "\S+,"ObjectName": "\S+","TaskId": "\d+?","RuntimeTaskId": "\d+","TaskName": "\S+","TaskType": "\S+","AccessUser": "\S+","AccessUserId": "\d+","FileOwner": "\S+","FileOwnerId": "\d+"" + ^""EventType": "(\S+)","EventID": "(\d+)","DetectName": "\S+","DetectType": "\S+","DetectCertainty": "(\S+)","DetectSource": "\S+","FileName": \S+,"ObjectName": "\S+","TaskId": "\d+","RuntimeTaskId": "\d+?","TaskName": "\S+","TaskType": "(\S+)","AccessUser": "\S+","AccessUserId": "\d+?","FileOwner": "\S+","FileOwnerId": "\d+"" + status, id, extra_data, action + + + + kesl + ^""EventType": "\S+","EventId": "\d+","TaskName": "\S+","TaskType": "\S+","TaskId": "\d+","TaskState": "\S+","PrevTaskState": "\S+","TaskRequestInitiator": "\S+","RuntimeTaskId": "\d+"" + ^""EventType": "(\S+)","EventId": "(\d+)","TaskName": "\S+","TaskType": "(\S+)","TaskId": "\d+","TaskState": "(\S+)","PrevTaskState": "\S+","TaskRequestInitiator": "(\S+)","RuntimeTaskId": "\d+"" + action, id, extra_data, status, srcuser + + + diff --git a/openarmor-rules/decoders.d/60-crs-windows-firewall_decoder.xml b/openarmor-rules/decoders.d/60-crs-windows-firewall_decoder.xml new file mode 100644 index 000000000..4128b71cd --- /dev/null +++ b/openarmor-rules/decoders.d/60-crs-windows-firewall_decoder.xml @@ -0,0 +1,20 @@ + + + windows-date-format + firewall + true + ^OPEN|^CLOSE|^DROP + ^(\w+) (\w+) + (\S+) (\S+) (\d+) (\d+) + action, protocol, srcip, dstip, srcport, dstport + + + + diff --git a/openarmor-rules/decoders.d/README.md b/openarmor-rules/decoders.d/README.md new file mode 100644 index 000000000..ef00002f8 --- /dev/null +++ b/openarmor-rules/decoders.d/README.md @@ -0,0 +1,17 @@ + diff --git a/openarmor-rules/openarmor-testing/runtests.py b/openarmor-rules/openarmor-testing/runtests.py new file mode 100644 index 000000000..0d46da61a --- /dev/null +++ b/openarmor-rules/openarmor-testing/runtests.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +import ConfigParser +import subprocess +import os +import sys +import os.path + + +class openarmorTester(object): + def __init__(self): + self._error = False + self._debug = False + self._quiet = False + self._openarmor_conf = "/var/openarmor/etc/openarmor.conf" + self._base_dir = "/var/openarmor/" + self._openarmor_path = "/var/openarmor/bin/" + self._test_path = "./tests" + + def buildCmd(self, rule, alert, decoder): + cmd = ['%s/openarmor-logtest' % (self._openarmor_path), ] + cmd += ['-q'] + if self._openarmor_conf: + cmd += ["-c", self._openarmor_conf] + if self._base_dir: + cmd += ["-D", self._base_dir] + cmd += ['-U', "%s:%s:%s" % (rule, alert, decoder)] + return cmd + + def runTest(self, log, rule, alert, decoder, section, name, negate=False): + #print self.buildCmd(rule, alert, decoder) + p = subprocess.Popen( + self.buildCmd(rule, alert, decoder), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + stdin=subprocess.PIPE, + shell=False) + std_out = p.communicate(log)[0] + if (p.returncode != 0 and not negate) or (p.returncode == 0 and negate): + self._error = True + print "" + print "-" * 60 + print "Failed: Exit code = %s" % (p.returncode) + print " Alert = %s" % (alert) + print " Rule = %s" % (rule) + print " Decoder = %s" % (decoder) + print " Section = %s" % (section) + print " line name = %s" % (name) + print " " + print std_out + elif self._debug: + print "Exit code= %s" % (p.returncode) + print std_out + else: + sys.stdout.write(".") + + def run(self, selective_test=False): + for aFile in os.listdir(self._test_path): + aFile = os.path.join(self._test_path, aFile) + if aFile.endswith(".ini"): + if selective_test and not aFile.endswith(selective_test): + continue + print "- [ File = %s ] ---------" % (aFile) + tGroup = ConfigParser.ConfigParser() + tGroup.read([aFile]) + tSections = tGroup.sections() + for t in tSections: + rule = tGroup.get(t, "rule") + alert = tGroup.get(t, "alert") + decoder = tGroup.get(t, "decoder") + for (name, value) in tGroup.items(t): + if name.startswith("log "): + if self._debug: + print "-" * 60 + if name.endswith("pass"): + neg = False + elif name.endswith("fail"): + neg = True + else: + neg = False + self.runTest(value, rule, alert, decoder, + t, name, negate=neg) + print "" + if self._error: + sys.exit(1) + +if __name__ == "__main__": + if len(sys.argv) == 2: + selective_test = sys.argv[1] + if not selective_test.endswith('.ini'): + selective_test += '.ini' + else: + selective_test = False + OT = openarmorTester() + OT.run(selective_test) diff --git a/openarmor-rules/openarmor-testing/tests/apache.ini b/openarmor-rules/openarmor-testing/tests/apache.ini new file mode 100644 index 000000000..1fd79a6cd --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/apache.ini @@ -0,0 +1,81 @@ +[Attempt to access forbidden directory index.] +log 1 pass = [error] [client 80.230.208.105] Directory index forbidden by rule: /home/ +rule = 30106 +alert = 5 +decoder = apache-errorlog + +[Code Red attack] +log 1 pass = [error] [client 64.94.163.159] Client sent malformed Host header +rule = 30107 +alert = 6 +decoder = apache-errorlog + +[Attempt to access an non-existent file] +log 1 pass = [error] [client 66.31.142.16] File does not exist: /var/www/html/default.ida +rule = 30112 +alert = 0 +decoder = apache-errorlog + +[Apache notice messages grouped] +log 1 pass = [notice] Apache configured +rule = 30103 +alert = 0 +decoder = apache-errorlog + +[Apache 2.2 error messages grouped] +log 1 pass = [Fri Dec 13 06:59:54 2013] [error] [client 12.34.65.78] PHP Notice: +rule = 30101 +alert = 0 +decoder = apache-errorlog + +[Apache 2.4 error messages grouped] +log 1 pass = [Tue Sep 30 11:30:13.262255 2014] [core:error] [pid 20101] [client 99.47.227.95:34567] AH00037: Symbolic link not allowed or link target not accessible: /usr/share/awstats/icon/mime/document.png +log 2 pass = [Tue Sep 30 12:11:21.258612 2014] [ssl:error] [pid 30473] AH02032: Hostname www.example.com provided via SNI and hostname ssl://www.example.com provided via HTTP are different +rule = 30301 +alert = 0 +decoder = apache-errorlog + +[Apache 2.4 warn messages grouped] +log 1 pass = [Tue Sep 30 12:24:22.891366 2014] [proxy:warn] [pid 2331] [client 77.127.180.111:54082] AH01136: Unescaped URL path matched ProxyPass; ignoring unsafe nocanon, referer: http://www.easylinker.co.il/he/links.aspx?user=bguyb +rule = 30302 +alert = 0 +decoder = apache-errorlog + +[Attempt to access forbidden file or directory] +log 1 pass = [Tue Sep 30 14:25:44.895897 2014] [authz_core:error] [pid 31858] [client 99.47.227.95:38870] AH01630: client denied by server configuration: /var/www/example.com/docroot/ +rule = 30305 +alert = 5 +decoder = apache-errorlog + +[Apache messages grouped] +log 1 pass = [Thu Oct 23 15:17:55.926067 2014] [ssl:info] [pid 18838] [client 36.226.119.49:2359] AH02008: SSL library error 1 in handshake (server www.example.com:443) +log 2 pass = [Thu Oct 23 15:17:55.926123 2014] [ssl:info] [pid 18838] SSL Library Error: error:1407609B:SSL routines:SSL23_GET_CLIENT_HELLO:https proxy request -- speaking HTTP to HTTPS port!? +rule = 30100 +alert = 0 +decoder = apache-errorlog + +[PHP Notices in Apache 2.4 errorlog] +log 1 pass = [Sun Nov 23 18:49:01.713508 2014] [:error] [pid 15816] [client 141.8.147.9:51507] PHP Notice: A non well formed numeric value encountered in /path/to/file.php on line 123 +rule = 30318 +alert = 5 +decoder = apache-errorlog + +[auth fail] +log 1 pass = [Tue Feb 07 08:50:22.679122 2017] [auth_basic:error] [pid 14446] [client 10.101.1.50:33168] AH01617: user pupkin: authentication failure for "/secret/": Password Mismatch +rule = 30308 +alert = 5 +decoder = apache-errorlog + +[script 404] +log 1 pass = [Tue Feb 07 02:43:19.799723 2017] [cgi:error] [pid 9721] [client 10.101.1.50:44324] AH02811: script not found or unable to stat: /var/www/html/showmail.pl +rule = 30321 +alert = 2 +decoder = apache-errorlog + +[permission denied] +log 1 pass = [Thu Feb 02 01:44:27.699327 2017] [access_compat:error] [pid 7934] [client ::1:50058] AH01797: client denied by server configuration: /var/www/html/' +log 2 pass = [Thu Feb 02 00:59:02.285651 2017] [core:error] [pid 20009] (13)Permission denied: [client ::1:49934] AH00132: file permissions deny server access: /var/www/html/1 +rule = 30320 +alert = 2 +decoder = apache-errorlog + diff --git a/openarmor-rules/openarmor-testing/tests/apparmor.ini b/openarmor-rules/openarmor-testing/tests/apparmor.ini new file mode 100644 index 000000000..bcada3d86 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/apparmor.ini @@ -0,0 +1,35 @@ +[Ignore ALLOWED or STATUS] +log 1 pass = Jun 24 10:35:29 hostname kernel: [49787.970285] audit: type=1400 audit(1403598929.839:88986): apparmor="ALLOWED" operation="getattr" profile="/usr/sbin/dovecot//null-1//null-2//null-4a6" name="/home/admin/mails/new/" pid=19973 comm="imap" requested_mask="r" denied_mask="r" fsuid=1003 ouid=1003 + +rule = 52001 +alert = 0 +decoder = iptables + +[Apparmor ALLOWED or STATUS] +log 1 pass = Jun 23 20:46:15 hostname kernel: [ 11.103248] audit: type=1400 audit(1403549175.177:2): apparmor="STATUS" operation="profile_load" name="/sbin/klogd" pid=2185 comm="apparmor_parser" + +rule = 52001 +alert = 0 +decoder = iptables + +[Apparmor DENIED] +log 1 pass = Jul 14 11:03:47 hostname kernel: [ 8665.951930] type=1400 audit(1405328627.702:54): apparmor="DENIED" operation="open" profile="/usr/bin/evince" name="/etc/xfce4/defaults.list" pid=16418 comm="evince" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 + +rule = 52002 +alert = 3 +decoder = iptables + +[Apparmor DENIED mknod operation.] +log 1 pass = Jun 16 17:37:39 hostname kernel: [891880.587989] audit: type=1400 audit(1314853822.672:33649): apparmor="DENIED" operation="mknod" parent=27250 profile="/usr/lib/apache2/mpm-prefork/apache2//example.com" name="/usr/share/wordpress/1114140474e5f13bea68a4.tmp" pid=27289 comm="apache2" requested_mask="c" denied_mask="c" fsuid=33 ouid=33 + +rule = 52004 +alert = 4 +decoder = iptables + +[Apparmor DENIED exec operation.] +log 1 pass = Jun 16 17:37:39 hostname kernel: [891880.587989] audit: type =1400 audit(1315353795.331:33657): apparmor="DENIED" operation="exec" parent=14952 profile="/usr/lib/apache2/mpm-prefork/apache2//example.com" name="/usr/lib/sm.bin/sendmail" pid=14953 comm="sh" requested_mask="x" denied_mask="x" fsuid=33 ouid=0 + +rule = 52003 +alert = 5 +decoder = iptables + diff --git a/openarmor-rules/openarmor-testing/tests/asterisk.ini b/openarmor-rules/openarmor-testing/tests/asterisk.ini new file mode 100644 index 000000000..fffff0827 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/asterisk.ini @@ -0,0 +1,15 @@ +[login failed] +log 1 pass = Aug 29 07:21:05 hostname asterisk[3284]: NOTICE[3734]: chan_sip.c:28088 in handle_request_register: Registration from '"3810" ' failed for '37.8.26.31:5065' - Wrong password +log 2 pass = Dec 16 18:02:04 asterisk1 asterisk[31774]: NOTICE[31787]: chan_sip.c:11242 in handle_request_register: Registration from '"503"' failed for '192.168.1.137' - Wrong password + +rule = 6210 +alert = 5 +decoder = asterisk + +[invalid extension] +log 1 pass = Aug 30 16:02:29 hostname asterisk[3284]: NOTICE[3734][C-00001c7a]: chan_sip.c:25650 in handle_request_invite: Call from '' (89.163.146.112:5071) to extension '70046313115067' rejected because extension not found in context 'default'. + +rule = 6258 +alert = 5 +decoder = asterisk + diff --git a/openarmor-rules/openarmor-testing/tests/cimserver.ini b/openarmor-rules/openarmor-testing/tests/cimserver.ini new file mode 100644 index 000000000..80717c6ba --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/cimserver.ini @@ -0,0 +1,9 @@ +[rshd: illegal] +log 1 pass = Dec 18 18:06:28 hostname cimserver[18575]: PGS17200: Authentication failed for user jones_b. +log 2 fail = Dec 18 18:06:29 hostname vimserver[18575]: PGS17200: Authentication failed for user domain\jones_b. + + +rule = 9610 +alert = 5 +decoder = cimserver + diff --git a/openarmor-rules/openarmor-testing/tests/cisco_ios.ini b/openarmor-rules/openarmor-testing/tests/cisco_ios.ini new file mode 100644 index 000000000..e4a7a1e04 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/cisco_ios.ini @@ -0,0 +1,21 @@ +[cisco ios ids: sig] +log 1 pass = Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:51654 -> 10.10.10.10:4444] +log 2 pass = Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:3051 Subsig:1 Sev:4 TCP Connection Window Size DoS [192.168.100.11:60797 -> 10.10.10.10:80] +log 3 pass = Sep 1 10:25:29 10.10.10.1 %IPS-4-SIGNATURE: Sig:5123 Subsig:2 Sev:5 WWW IIS Internet Printing Overflow [192.168.100.11:60797 -> 10.10.10.10:80] + + +rule = 20100 +alert = 8 +decoder = cisco-ios + + +[cisco ios: acl ] +log 1 pass = Sep 1 10:25:29 10.10.10.1 %SEC-6-IPACCESSLOGP: list 102 denied tcp 10.0.6.56(3067) -> 172.36.4.7(139), 1 packet +log 2 pass = Sep 1 10:25:29 10.10.10.1 %SEC-6-IPACCESSLOGP: list 199 denied tcp 10.0.61.108(1477) -> 10.0.127.20(445), 1 packet + + +rule = 4100 +alert = 0 +decoder = cisco-ios + + diff --git a/openarmor-rules/openarmor-testing/tests/cpanel.ini b/openarmor-rules/openarmor-testing/tests/cpanel.ini new file mode 100644 index 000000000..ae036efda --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/cpanel.ini @@ -0,0 +1,38 @@ +[successful login] +log 1 fail = [2016-04-18 13:07:02 -0400] info [cpsrvd] 10.1.5.19 - root - SUCCESS LOGIN whostmgrd +log 2 fail = [2016-04-18 13:07:15 -0400] info [cpsrvd] 10.1.5.19 - reseller (possessor: root) - SUCCESS LOGIN cpaneld +log 3 fail = [2016-04-18 13:08:27 -0400] info [cpsrvd] 10.1.5.19 - emailaccount@reseller.com (possessor: reseller) - SUCCESS LOGIN webmaild + +rule = 11007 +alert = 3 +decoder = postgresql_log + + +[cpanel attacks] +log 1 fail = [2017-01-25 06:01:10 -0500] info [cpsrvd] 10.1.5.19 - test "POST /login/?login_only=1 HTTP/1.1" FAILED LOGIN cpaneld: invalid cpanel user test (loadcpdata failed) + +rule = 11001 +alert = 5 +decoder = postgresql_log + +[cpanel attacks 2] +log 1 fail = [2016-11-18 09:32:19 +0000] info [cpsrvd] 10.1.5.19 - admin "POST /login/?login_only=1 HTTP/1.1" FAILED LOGIN whostmgrd: user password hash is missing from system (user probably does not exist) + +rule = 11000 +alert = 5 +decoder = cpanel-login + +[successful login 2] +log 1 fail = [2016-04-18 13:07:02 +0400] info [cpsrvd] 10.1.5.19 - root - SUCCESS LOGIN whostmgrd + +rule = 11006 +alert = 3 +decoder = cpanel-login + +[session purge] +log 1 fail = [2017-01-25 06:15:38 -0500] info [cpsrvd] 10.1.5.19 PURGE root:Nmm4xzhSpA2Sddv3 logout + +rule = 11009 +alert = 3 +decoder = postgresql_log + diff --git a/openarmor-rules/openarmor-testing/tests/dnsmasq.ini b/openarmor-rules/openarmor-testing/tests/dnsmasq.ini new file mode 100644 index 000000000..96f2236ef --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/dnsmasq.ini @@ -0,0 +1,9 @@ +[dnsmasq group] +log 1 pass = Jul 17 14:49:57 dnsmasq[15210]: 21745 10.10.10.33/59490 query[A] server.example.com from 10.10.10.33 +log 2 pass = Jul 17 14:49:57 dnsmasq[15210]: 21745 10.10.10.33/59490 forwarded server.example.com to 10.20.20.10 +log 3 pass = Jul 17 14:49:57 dnsmasq[15210]: 21745 10.10.10.33/59490 reply server.example.com is + +rule = 53551 +alert = 0 +decoder = dnsmasq + diff --git a/openarmor-rules/openarmor-testing/tests/doas.ini b/openarmor-rules/openarmor-testing/tests/doas.ini new file mode 100644 index 000000000..127284aef --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/doas.ini @@ -0,0 +1,28 @@ +[failed command] +log 1 pass = Apr 13 08:49:20 ix doas: failed command for ddp2: ls + +rule = 51554 +alert = 5 +decoder = doas + +[command run as root] +log 1 pass = Mar 22 07:21:58 ix doas: ddp ran command /bin/ksh as root from /data/ddp/projects/git/sysconf/openarmor/rules + +rule = 51556 +alert = 2 +decoder = doas + +[failed auth] +log 1 pass = Feb 29 14:58:39 ix doas: failed auth for ddp + +rule = 51557 +alert = 5 +decoder = doas + +[doas command run] +log 1 pass = Aug 13 15:16:40 ix doas: ddp ran command as ddpnfs: ls + +rule = 51555 +alert = 1 +decoder = doas + diff --git a/openarmor-rules/openarmor-testing/tests/dovecot.ini b/openarmor-rules/openarmor-testing/tests/dovecot.ini new file mode 100644 index 000000000..691bc82b1 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/dovecot.ini @@ -0,0 +1,81 @@ +[auth failed] +log 1 pass = Dec 19 06:21:06 ny dovecot: imap-login: Disconnected (auth failed, 7 attempts in 111 secs): user=, method=PLAIN, rip=109.201.200.201, lip=67.205.141.203, session=<+hgd5vxDBMZtycjJ> +log 2 pass = Jan 11 03:45:09 hostname dovecot: auth-worker(default): sql(username,1.2.3.4): unknown user +log 3 pass = Jan 11 03:42:09 hostname dovecot: auth(default): pam(user@example.com,1.2.3.4): pam_authenticate() failed: User not known to the underlying authentication module + +rule = 9705 +alert = 5 +decoder = dovecot + +[dovecot is starting] +log 1 pass = Jun 17 10:15:24 hostname dovecot: Dovecot v1.2.rc3 starting up (core dumps disabled) + +rule = 9703 +alert = 3 +decoder = dovecot + +[fatal error] +log 1 pass = Jun 17 10:15:24 hostname dovecot: Fatal: auth(default): Support not compiled in for passdb driver 'ldap' +log 2 pass = Jun 17 10:15:24 hostname dovecot: Fatal: Auth process died too early - shutting down + +rule = 9704 +alert = 2 +decoder = dovecot + +[user authentication failure] +log 1 pass = Jun 23 15:04:05 Info: imap-login: Login: user=, method=PLAIN, rip=1.2.3.4, lip=1.2.3.5 Authentication Failure: + +rule = 9770 +alert = 0 +decoder = dovecot-info + +[dovecot auth failed] +log 1 pass = Jan 11 03:42:09 hostname dovecot: auth-worker(default): sql(user@example.com,1.2.3.4): Password mismatch + +rule = 9702 +alert = 5 +decoder = dovecot + +[XXX nothing] +log 1 fail = Jan 07 14:46:28 Warn: auth(default): userdb(username,::ffff:127.0.0.1): user not found from userdb +log 3 fail = May 31 09:43:57 Info: pop3-login: Aborted login (1 authentication attempts): user=, method=PLAIN, rip=::ffff:1.2.3.4, lip=::ffff:1.2.3.5, secured + +rule = 1002 +alert = 2 +decoder = + +[XXX unknown 1002] +log 1 pass = Mar 13 15:25:07 Info: auth(default): pam(user@example.com,::ffff:1.2.3.4): pam_authenticate() failed: User not known to the underlying authentication module + +rule = 9771 +alert = 5 +decoder = dovecot-info + +[session disconnected] +log 1 pass = Jul 4 17:30:51 hostname dovecot[2992]: pop3-login: Disconnected: rip=1.2.3.4, lip=1.2.3.5 + +rule = 9706 +alert = 3 +decoder = dovecot + +[aborted login] +log 1 pass = Jan 30 09:37:55 hostname dovecot: pop3-login: Aborted login: user=, method=PLAIN, rip=::ffff:1.2.3.4, lip=::ffff:1.2.3.5 + +rule = 9707 +alert = 5 +decoder = dovecot + +[XXX logged out] +log 1 fail = Jun 23 15:04:06 Info: IMAP(username): Disconnected: Logged out bytes=59/566 + +rule = 1002 +alert = 2 +decoder = dovecot-info + +[unknown user] +log 1 pass = Mar 13 15:25:07 Info: auth(default): passwd-file(user@example.com,::ffff:1.2.3.4): unknown user + +rule = 9771 +alert = 5 +decoder = dovecot-info + diff --git a/openarmor-rules/openarmor-testing/tests/dpkg.ini b/openarmor-rules/openarmor-testing/tests/dpkg.ini new file mode 100644 index 000000000..61890b66f --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/dpkg.ini @@ -0,0 +1,8 @@ +[dpkg log] +log 1 pass = 2018-05-31 12:09:56 upgrade vlc-plugin-visualization:amd64 3.0.2-1+b1 3.0.3-1 +log 2 pass = 2018-05-11 09:41:49 conffile /etc/redis/redis.conf keep + +rule = 2900 +alert = 0 +decoder = windows-date-format + diff --git a/openarmor-rules/openarmor-testing/tests/dropbear.ini b/openarmor-rules/openarmor-testing/tests/dropbear.ini new file mode 100644 index 000000000..244d9d1a4 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/dropbear.ini @@ -0,0 +1,31 @@ +[already listening] +log 1 pass = Jun 25 14:04:30 10.0.0.1 dropbear[30746]: Failed listening on '7001': Error listening: Address already in use + +rule = 51011 +alert = 1 +decoder = dropbear + +[User successfully logged in using a public key] +log 1 pass = Jan 8 19:32:41 tp.lan dropbear[15165]: Pubkey auth succeeded for 'root' with key md5 78:d6:41:ca:78:37:80:88:1d:15:0a:68:91:d1:4e:ad from 10.10.10.241:51737 + +rule = 51010 +alert = 0 +decoder = dropbear + +[Bad password attempt.] +log 1 pass = Jan 8 16:39:33 tp.lan dropbear[14824]: Bad password attempt for 'root' from 193.219.28.149:48629 + +rule = 51003 +alert = 5 +decoder = dropbear + +[Bad password attempt for non existent user.] +log 1 pass = Jan 8 19:54:12 tp.lan dropbear[15197]: Login attempt for nonexistent user from 182.72.89.122:4328 + +rule = 51093 +alert = 5 +decoder = dropbear + + + + diff --git a/openarmor-rules/openarmor-testing/tests/exim.ini b/openarmor-rules/openarmor-testing/tests/exim.ini new file mode 100644 index 000000000..f6853658a --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/exim.ini @@ -0,0 +1,29 @@ +[auth failure] +log 1 pass = 2017-01-23 03:44:14 dovecot_login authenticator failed for (hydra) [10.101.1.18]:35686: 535 Incorrect authentication data (set_id=user) +log 2 pass = 2017-01-24 05:22:29 dovecot_plain authenticator failed for (test) [::1]:39454: 535 Incorrect authentication data (set_id=test) + +rule = 13006 +alert = 5 +decoder = windows-date-format + +[exim connection] +log 1 pass = 2017-01-24 03:09:46 SMTP connection from [10.101.1.10]:55010 (TCP/IP connection count = 1) + +rule = 13008 +alert = 0 +decoder = windows-date-format + +[exim connection lost] +log 1 pass = 2017-01-24 02:53:13 SMTP connection from (hydra) [10.101.1.10]:53682 lost + +rule = 13009 +alert = 1 +decoder = windows-date-format + +[exim syntax/protocol error] +log 1 pass = 2017-01-24 05:36:23 SMTP call from (000000) [::1]:39480 dropped: too many syntax or protocol errors (last command was "123") + +rule = 13010 +alert = 5 +decoder = windows-date-format + diff --git a/openarmor-rules/openarmor-testing/tests/firewalld.ini b/openarmor-rules/openarmor-testing/tests/firewalld.ini new file mode 100644 index 000000000..ceb925cd2 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/firewalld.ini @@ -0,0 +1,21 @@ +[Incorrect chain/target/match.] +log 3 fail = Jul 18 10:51:43 localhost firewalld: 2014-07-18 10:51:43 ERROR: '/sbin/iptables -D INPUT_ZONES -t filter -i enp1s0 -g IN_public' failed: iptables: No chain/target/match by that name. + +rule = 40902 +alert = 3 +decoder = + +[Incorrect chain/target/match.] +log 3 fail = Jul 18 10:51:43 localhost firewalld: 2014-07-18 10:51:43 ERROR: COMMAND_FAILED: '/sbin/iptables -D INPUT_ZONES -t filter -i enp1s0 -g IN_public' failed: iptables: No chain/target/match by that name. + +rule = 40902 +alert = 3 +decoder = + +[firewalld: zone already set] +log 3 fail = Jul 18 11:04:51 localhost firewalld: 2014-07-18 11:04:51 ERROR: ZONE_ALREADY_SET + +rule = 40903 +alert = 2 +decoder = + diff --git a/openarmor-rules/openarmor-testing/tests/mailscanner.ini b/openarmor-rules/openarmor-testing/tests/mailscanner.ini new file mode 100644 index 000000000..725bbbe02 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/mailscanner.ini @@ -0,0 +1,6 @@ +[update phishing] +log 1 fail = Feb 14 06:29:39 hostname update.bad.phishing.sites: Phishing bad sites list updated +rule = 3752 +alert = 0 +decoder = + diff --git a/openarmor-rules/openarmor-testing/tests/modsecurity.ini b/openarmor-rules/openarmor-testing/tests/modsecurity.ini new file mode 100644 index 000000000..7331dd217 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/modsecurity.ini @@ -0,0 +1,20 @@ +[ModSecurity Warning messages grouped] +log 1 pass = [Mon Feb 09 16:47:55.974089 2015] [:error] [pid 17675] [client 172.16.10.87] ModSecurity: Warning. Operator GE matched 4 at TX:outbound_anomaly_score. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_60_correlation.conf"] [line "40"] [id "981205"] [msg "Outbound Anomaly Score Exceeded (score 4): The application is not available"] [hostname "172.16.10.91"] [uri "/wordpress/wp-includes/rss-functions.php"] [unique_id "VNkA238AAQEAAEULYMwAAAAA"] +log 2 pass = [Thu Jan 22 14:33:30.959520 2015] [:error] [pid 2406] [client 172.16.10.87] ModSecurity: Warning. Pattern match "^(?i)(?:ft|htt)ps?(.*?)\\\\?+$" at ARGS:path_prefix. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_40_generic_attacks.conf"] [line "160"] [id "950119"] [rev "2"] [msg "Remote File Inclusion Attack"] [data "Matched Data: http://cirt.net/rfiinc.txt? found within ARGS:path_prefix: http://cirt.net/rfiinc.txt?"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/WEB_ATTACK/RFI"] [hostname "172.16.10.91"] [uri "/wordpress/web/BetaBlockModules//Module/Module.php"] [unique_id "VMEmWn8AAQEAAAlmdHgAAAAI"] +rule = 30401 +alert = 0 +decoder = apache-errorlog + +[ModSecurity Audit log messages grouped] +log 1 pass = [Mon Feb 09 21:17:06.798110 2015] [:error] [pid 8608] [client 172.16.10.57] ModSecurity: Audit log: Failed writing (requested 83 bytes, written 24): No space left on device [hostname "172.16.10.91"] [uri "/403.php"] [unique_id "VNk-8n8AAQEAACGg7LEAAAAE"] +log 2 pass = [Wed Feb 11 19:46:12.759594 2015] [:error] [pid 1130] [client 172.16.10.91] ModSecurity: Audit log: Failed to lock global mutex: Identifier removed [hostname "172.16.10.91"] [uri "/wordpress/wp-cron.php"] [unique_id "VNvLw38AAQEAAARqTXsAAAAD"] +rule = 30403 +alert = 0 +decoder = apache-errorlog + +[ModSecurity rejected a query] +log 1 pass = [Mon Feb 09 16:47:55.908176 2015] [:error] [pid 17679] [client 172.16.10.91] ModSecurity: Access denied with code 403 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "47"] [id "960015"] [rev "1"] [msg "Request Missing an Accept Header"] [severity "NOTICE"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "172.16.10.91"] [uri "/wordpress/wp-cron.php"] [unique_id "VNkA238AAQEAAEUP9hIAAAAI"] +log 2 pass = [Mon Feb 09 16:47:55.973954 2015] [:error] [pid 17675] [client 172.16.10.87] ModSecurity: Access denied with code 403 (phase 4). Pattern match "^5\\\\d{2}$" at RESPONSE_STATUS. [file "/etc/apache2/ModSecurity/activated_rules/modsecurity_crs_50_outbound.conf"] [line "53"] [id "970901"] [rev "2"] [msg "The application is not available"] [data "Matched Data: 500 found within RESPONSE_STATUS: 500"] [severity "ERROR"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "WASCTC/WASC-13"] [tag "OWASP_TOP_10/A6"] [tag "PCI/6.5.6"] [hostname "172.16.10.91"] [uri "/wordpress/wp-includes/rss-functions.php"] [unique_id "VNkA238AAQEAAEULYMwAAAAA"] +rule = 30411 +alert = 7 +decoder = apache-errorlog diff --git a/openarmor-rules/openarmor-testing/tests/named.ini b/openarmor-rules/openarmor-testing/tests/named.ini new file mode 100644 index 000000000..98e3dd654 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/named.ini @@ -0,0 +1,11 @@ +[Query cache denied] +log 1 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.3#1036: query (cache) denied +log 2 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.4#32769: query (cache) denied +log 3 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.3#1036: query (cache) denied +log 4 fail = Aug 29 15:33:13 ns3 name[464]: client 217.148.39.4#32769: query (cache) denied +log 5 pass = Aug 29 15:33:13 ns3 named[464]: client 217.148.39.3#1036: query (cache) +log 6 pass = Mar 13 01:42:45 net19 named[6147]: client 31.150.218.239#6173 (odcdavcxkvin.games.yuanyou8.com): query (cache) 'odcdavcxkvin.games.yuanyou8.com/A/IN' denied + +rule = 12108 +alert = 5 +decoder = named diff --git a/openarmor-rules/openarmor-testing/tests/netscreen.ini b/openarmor-rules/openarmor-testing/tests/netscreen.ini new file mode 100644 index 000000000..92de03d80 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/netscreen.ini @@ -0,0 +1,28 @@ +[Firewall configuration changed.] +log 1 pass = 2014-05-23T10:25:58.681222-04:00 10.10.10.1 ssg5-serial: NetScreen device_id=0275112227993284 [Root]system-information-00767: System configuration saved by netscreen via web from host 10.10.10.101 to 10.10.10.1:443 by netscreen. (2014-05-23 10:58:17) + +rule = 4509 +alert = 8 +decoder = netscreenfw + +[Firewall policy changed.] +log 1 pass = 2014-05-23T10:29:55.704201-04:00 10.10.10.1 ssg5-serial: NetScreen device_id=0275112227993284 [Root]system-notification-00018: Policy (5, Trust->Untrust, 10.10.10.0/24->172.16.19.0/24,ANY, Permit) was modified by netscreen via web from host 10.10.10.101 to 10.10.10.1:443. (2014-05-23 11:02:13) + +rule = 4508 +alert = 8 +decoder = netscreenfw + +[Successfull admin login to the Netscreen firewall] +log 1 pass = 2014-05-23T10:39:20.681154-04:00 10.10.10.1 ssg5-serial: NetScreen device_id=0275112227993284 [Root]system-warning-00515: Management session via SSH from 10.10.10.100:0 for admin netscreen has timed out (2014-05-23 11:11:39) + +rule = 4507 +alert = 8 +decoder = netscreenfw + +[syn flood] +log 1 pass = Jul 7 05:02:34 ssg5.17.168.192.in-addr.arpa ssg5: NetScreen device_id=ssg5 [Root]system-emergency-00005: SYN flood! From 192.168.18.53:41437 to 192.168.17.251:9612, proto TCP (zone Untrust int ethernet0/0). Occurred 1 times. (2016-07-07 05:02:32) + +rule = 4560 +alert = 3 +decoder = netscreenfw + diff --git a/openarmor-rules/openarmor-testing/tests/nginx.ini b/openarmor-rules/openarmor-testing/tests/nginx.ini new file mode 100644 index 000000000..91aa78035 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/nginx.ini @@ -0,0 +1,79 @@ +; YYYY/MM/DD HH:MM:SS [LEVEL] PID:TID yadda yadda +[Nginx messages grouped.] +log 1 pass = 2014/12/30 06:07:37 [yadda] 80:2 yadda yadda + +rule = 31300 +alert = 0 +decoder = nginx-errorlog + +[Nginx error message.] +log 1 pass = 2014/12/30 06:07:37 [error] 80:2 yadda yadda + +rule = 31301 +alert = 3 +decoder = nginx-errorlog + +[Nginx warning message.] +log 1 pass = 2014/12/30 06:07:37 [warn] 80:2 yadda yadda + +rule = 31302 +alert = 3 +decoder = nginx-errorlog + +[Nginx critical message.] +log 1 pass = 2014/12/30 06:07:37 [crit] 80:2 + +rule = 31303 +alert = 5 +decoder = nginx-errorlog + +[Server returned 404 (reported in the access.log).] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 blah blah failed (2: No such file or directory) +log 2 pass = 2015/01/08 11:31:23 [error] 80:2 blah blah is not found (2: No such file or directory) + +rule = 31310 +alert = 0 +decoder = nginx-errorlog + +[Incomplete client request.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 blah blah accept() failed (53: Software caused connection abort) + +rule = 31311 +alert = 0 +decoder = nginx-errorlog + +[Initial 401 authentication request.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 no user/password was provided for basic authentication + +rule = 31312 +alert = 0 +decoder = nginx-errorlog + +[Web authentication failed.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 yadda password mismatch, client yadda +log 2 pass = 2015/01/08 11:31:23 [error] 80:2 yadda was not found in yadda + +rule = 31315 +alert = 5 +decoder = nginx-errorlog + +# Can't yet test frequency +;[Multiple web authentication failures.] +; +;rule = 31316 +;alert = 10 +;decoder = nginx-errorlog + +[Common cache error when files were removed.] +log 1 pass = 2015/01/08 11:31:23 [crit] 80:2 yadda yadda failed (2: No such file or directory + +rule = 31317 +alert = 0 +decoder = nginx-errorlog + +[Invalid URI, file name too long.] +log 1 pass = 2015/01/08 11:31:23 [error] 80:2 yadda yadda failed (36: File name too long) + +rule = 31320 +alert = 10 +decoder = nginx-errorlog diff --git a/openarmor-rules/openarmor-testing/tests/openbsd-dhcpd.ini b/openarmor-rules/openarmor-testing/tests/openbsd-dhcpd.ini new file mode 100644 index 000000000..799bab627 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/openbsd-dhcpd.ini @@ -0,0 +1,25 @@ +[lease release] +log 1 pass = Jan 26 18:12:55 junction dhcpd[4842]: IP address 192.168.1.16 answers a ping after sending a release +log 2 pass = Jan 26 18:12:40 junction dhcpd[4842]: Possible release spoof - Not releasing address 192.168.17.160 + +rule = 53003 +alert = 5 +decoder = dhcpd + +[no free leases] +log 1 pass = Jan 26 17:42:32 junction dhcpd[4842]: no free leases on subnet 192.168.17.0 + +rule = 53011 +alert = 7 +decoder = dhcpd + +[normal dhcp stuff] +log 1 pass = Jan 27 09:25:36 junction dhcpd[71391]: DHCPREQUEST for 192.168.17.164 from f4:8c:50:9d:eb:35 via em1 +log 2 pass = Jan 27 09:25:36 junction dhcpd[71391]: DHCPDISCOVER from f4:8c:50:9d:eb:35 via em1 +log 3 pass = Jan 27 09:25:31 junction dhcpd[71391]: DHCPOFFER on 192.168.17.164 to f4:8c:50:9d:eb:35 via em1 + +rule = 53001 +alert = 1 +decoder = dhcpd + + diff --git a/openarmor-rules/openarmor-testing/tests/openbsd-httpd.ini b/openarmor-rules/openarmor-testing/tests/openbsd-httpd.ini new file mode 100644 index 000000000..5bbdd19ae --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/openbsd-httpd.ini @@ -0,0 +1,14 @@ +[access] +log 1 pass = wafflelab.online 192.168.18.8 - - [08/Jul/2018:00:29:48 -0400] "GET / HTTP/1.0" 302 0 +log 2 pass = wafflelab.online 192.168.18.8 - - [08/Jul/2018:00:32:57 -0400] "GET /nmaplowercheck1531024375 HTTP/1.1" 302 0 +rule = 31100 +alert = 0 +decoder = openbsd-httpd + +[POST] +log 1 pass = www.wafflelab.online 192.168.18.8 - - [08/Jul/2018:00:33:13 -0400] "POST /sdk HTTP/1.1" 404 0 + +rule = 31530 +alert = 3 +decoder = openbsd-httpd + diff --git a/openarmor-rules/openarmor-testing/tests/openbsd.ini b/openarmor-rules/openarmor-testing/tests/openbsd.ini new file mode 100644 index 000000000..77ae6610d --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/openbsd.ini @@ -0,0 +1,7 @@ +[sendsyslog drop] +log 1 fail = Oct 16 08:15:07 ix sendsyslog: dropped 2 messages, error 55 + +rule = 51558 +alert = 4 +decoder = + diff --git a/openarmor-rules/openarmor-testing/tests/opensmtpd.ini b/openarmor-rules/openarmor-testing/tests/opensmtpd.ini new file mode 100644 index 000000000..6bb28d562 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/opensmtpd.ini @@ -0,0 +1,49 @@ +[message failed] +log 1 pass = Aug 14 10:15:25 junction.example.com smtpd[28882]: smtp-in: Failed command on session 1f55bdcdf16e28a3: "MAIL FROM: " => 421 4.3.0: Temporary Error + +rule = 53501 +alert = 3 +decoder = smtpd + +[new session] +log 1 pass = Aug 17 01:26:02 ix smtpd[22704]: smtp-in: New session 08d856b172f69c5c from host ix.example.com [local] + +rule = 53502 +alert = 0 +decoder = smtpd + +[message accepted] +log 1 pass = Aug 17 01:26:02 ix smtpd[22704]: smtp-in: Accepted message 4296f490 on session 08d856b172f69c5c: from=, to=, size=1746, ndest=1, proto=ESMTP + +rule = 53504 +alert = 0 +decoder = smtpd + +[session closed] +log 1 pass = Aug 17 01:26:02 ix smtpd[22704]: smtp-in: Closing session 08d856b172f69c5c + +rule = 53503 +alert = 0 +decoder = smtpd + +[disconnect] +log 1 pass = Mar 4 00:11:00 ix smtpd[22421]: smtp-in: Received disconnect from session 427e7493ebe154ae + +rule = 53500 +alert = 0 +decoder = smtpd + +[no ssl] +log 1 pass = Mar 4 00:13:55 ix smtpd[22421]: smtp-in: Disconnecting session 427e7497e03518ef: IO error: No SSL error + +rule = 53507 +alert = 2 +decoder = smtpd + +[started tls] +log 1 pass = Mar 4 00:13:55 ix smtpd[22421]: smtp-in: Started TLS on session 427e749c2e46f809: version=TLSv1.2, cipher=EDH-RSA-DES-CBC3-SHA, bits=112 + +rule = 53500 +alert = 0 +decoder = smtpd + diff --git a/openarmor-rules/openarmor-testing/tests/pam.ini b/openarmor-rules/openarmor-testing/tests/pam.ini new file mode 100644 index 000000000..4c703d080 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/pam.ini @@ -0,0 +1,40 @@ +[User login failed.] +log 1 pass = Nov 11 22:46:29 localhost su(pam_unix)[23164]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=osaudit +log 2 pass = Jun 28 23:01:27 xxxx auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=lipjigaglgihgoeadcdaa.p.salmon@xxx.xxx.xxx.xxx rhost=91.195.103.44 + +rule = 5503 +alert = 5 +decoder = pam + +[Attempt to login with an invalid user.] +log 1 pass = Nov 11 22:46:29 localhost vsftpd(pam_unix)[25073]: check pass; user unknown +log 2 pass = Mar 29 00:42:09 server saslauthd[1230]: pam_succeed_if(smtp:auth): error retrieving information about user demo + +rule = 5504 +alert = 5 +decoder = pam + +[Login session opened.] +log 1 pass = Nov 11 22:46:29 localhost su(pam_unix)[14592]: session opened for user news by (uid=0) + +rule = 5501 +alert = 3 +decoder = pam + +[Login session closed.] +log 1 pass = Nov 11 22:46:29 localhost su(pam_unix)[14592]: session closed for user news + +rule = 5502 +alert = 3 +decoder = pam + +[User missed the password more than one time] +log 1 pass = Nov 11 22:46:29 localhost sshd(pam_unix)[15794]: 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.0.3.1 user=root + +rule = 2502 +alert = 10 +decoder = pam + + + + diff --git a/openarmor-rules/openarmor-testing/tests/postfix.ini b/openarmor-rules/openarmor-testing/tests/postfix.ini new file mode 100644 index 000000000..f8e45ce12 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/postfix.ini @@ -0,0 +1,14 @@ +[reject rcpt] +log 1 pass = May 8 08:26:55 mail postfix/postscreen[22055]: NOQUEUE: reject: RCPT from [157.122.148.242]:47407: 550 5.7.1 Service unavailable; client [157.122.148.242] blocked using bl.spamcop.net; from=, to=, proto=ESMTP, helo= + +rule = 3306 +alert = 6 +decoder = postfix-reject + +[domain not found] +log 1 pass = Jun 18 20:59:29 mybox postfix/postscreen[12181]: NOQUEUE: reject: RCPT from [213.158.187.41]:45263: 450 4.3.2 Service currently unavailable; from=, to=, proto=ESMTP, helo= + +rule = 3303 +alert = 5 +decoder = postfix-reject + diff --git a/openarmor-rules/openarmor-testing/tests/proftpd.ini b/openarmor-rules/openarmor-testing/tests/proftpd.ini new file mode 100644 index 000000000..84a26a281 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/proftpd.ini @@ -0,0 +1,32 @@ +[unable to open incoming connection (reason may vary)] +log 1 pass = Jan 04 22:51:57 server proftpd[26169] server.example.net: Fatal: unable to open incoming connection: Der Socket ist nicht verbunden +rule = 11222 +alert = 4 +decoder = proftpd + +[FTP Authentication success] +log 1 pass = Jan 04 22:51:57 hayaletgemi proftpd[26916]: hayaletgemi (85.101.218.135[85.101.218.135]) - ANON anonymous: Login successful. +log 2 pass = Jan 04 22:51:57 juf01 proftpd[12564]: juf01 (pD9EE35B1.dip.t-dialin.net[217.238.53.177]) - USER jufu: Login successful +log 3 pass = Jan 04 22:51:57 xx.yy.zz proftpd[30362] xx.yy.zz (aa.bb.cc[aa.bb.vv.dd]): USER backup: Login successful. +rule = 11205 +alert = 3 +decoder = proftpd + +[Connection refused by TCP Wrappers] +log 1 pass = Jan 04 22:51:57 server proftpd[2344]: refused connect from 192.168.1.2 (192.168.1.2) +rule = 11207 +alert = 5 +decoder = proftpd + +[Connection denied by ProFTPD configuration] +log 1 pass = Jan 04 22:51:57 valhalla proftpd[15181]: valhalla (crawl-66-249-66-80.googlebot.com[66.249.66.80]) - Connection from crawl-66-249-66-80.googlebot.com [66.249.66.80] denied. +rule = 11206 +alert = 5 +decoder = proftpd + +[Login failed accessing the FTP server] +log 1 pass = 2015-04-16 21:51:02,805 zuse proftpd[26189] zuse.domain.com (182.100.67.115[182.100.67.115]): USER root (Login failed): Incorrect password +rule = 11204 +alert = 5 +decoder = proftpd + diff --git a/openarmor-rules/openarmor-testing/tests/rsh.ini b/openarmor-rules/openarmor-testing/tests/rsh.ini new file mode 100644 index 000000000..9804df0c1 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/rsh.ini @@ -0,0 +1,8 @@ +[rshd: illegal] +log 1 pass = Dec 17 10:49:23 hostname rshd[347339]: Connection from 10.217.223.31 on illegal port +log 2 fail = Dec 17 10:49:23 hostname rhsd[347339]: Connection from 10.217.223.31 on illegal port + +rule = 2551 +alert = 10 +decoder = rshd + diff --git a/openarmor-rules/openarmor-testing/tests/samba.ini b/openarmor-rules/openarmor-testing/tests/samba.ini new file mode 100644 index 000000000..23a337216 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/samba.ini @@ -0,0 +1,23 @@ +[samba: denied connect] +log 1 pass = Dec 18 18:06:28 hostname smbd[832]: Denied connection from (192.168.3.23) + + +rule = 13102 +alert = 5 +decoder = smbd + +[samba: connect denied] +log 1 pass = Dec 18 18:06:28 hostname smbd[832]: Denied connection from (192.168.3.23) + + +rule = 13102 +alert = 5 +decoder = smbd + +[samba: permission denied] +log 1 fail = Dec 18 18:06:28 hostname smbd[17535]: Permission denied user not allowed to delete, pause, or resume print job. User name: ahmet. Printer name: prnq1. +log 2 fail = Dec 18 18:06:28 hostname smbd[17535]: Permission denied\-\- user not allowed to delete, pause, or resume print job. User name: ahmet. Printer name: prnq1. + +rule = 13102 +alert = 5 +decoder = smbd diff --git a/openarmor-rules/openarmor-testing/tests/sshd.ini b/openarmor-rules/openarmor-testing/tests/sshd.ini new file mode 100644 index 000000000..bde0b7d63 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/sshd.ini @@ -0,0 +1,163 @@ +[SSHD configuration error (AuthorizedKeysCommand)] +log 1 pass = Feb 9 11:44:56 someserver sshd[1234]: error: Could not stat AuthorizedKeysCommand "/usr/local/sbin/ssh-ldap-authorized_keys": No such file or directory + +rule = 5739 +alert = 4 +decoder = sshd + +[ssh connection reset by peer] +log 1 pass = Feb 10 23:21:05 someserver sshd[1234]: Read error from remote host 192.168.1.1: Connection reset by peer + +rule = 5740 +alert = 4 +decoder = sshd + +[ssh connection refused] +log 1 pass = Feb 11 06:41:50 someserver sshd[1234]: debug1: channel 5: connection failed: Connection refused + +rule = 5741 +alert = 4 +decoder = sshd + +[ssh connection timed out] +log 1 pass = Feb 12 17:45:09 someserver sshd[1234]: debug1: channel 3: connection failed: Connection timed out + +rule = 5742 +alert = 4 +decoder = sshd + +[ssh no route to host] +log 1 pass = Jan 30 18:55:24 someserver sshd[1234]: debug1: channel 1: connection failed: No route to host + +rule = 5743 +alert = 4 +decoder = sshd + +[ssh port forwarding issue] +log 1 pass = Feb 13 22:54:51 someserver sshd[1234]: debug1: server_input_channel_open: failure direct-tcpip + +rule = 5744 +alert = 4 +decoder = sshd + +[ssh transport endpoint is not connected] +log 1 pass = Feb 6 12:28:17 someserver sshd[1234]: debug1: getpeername failed: Transport endpoint is not connected + +rule = 5745 +alert = 4 +decoder = sshd + +[ssh get_remote_port failed] +log 1 pass = Feb 6 12:28:17 someserver sshd[1234]: debug1: get_remote_port failed + +rule = 5746 +alert = 4 +decoder = sshd + +[ssh bad client public DH value] +log 1 pass = Feb 4 23:05:57 someserver sshd[1234]: Disconnecting: bad client public DH value [preauth] +log 1 pass = Feb 4 23:05:57 someserver sshd[1234]: Disconnecting: bad client public DH value + +rule = 5747 +alert = 6 +decoder = sshd + +[ssh corrupted MAC on input] +log 1 pass = Feb 14 14:34:15 someserver sshd[1234]: Corrupted MAC on input. [preauth] +log 2 pass = Nov 22 19:24:55 server sshd[4046]: Corrupted MAC on input. + +rule = 5748 +alert = 6 +decoder = sshd + +[ssh bad packet length] +log 1 pass = Mar 4 13:34:59 someserver sshd[5396]: Bad packet length 4081586742. [preauth] +log 2 pass = Mar 4 13:34:59 someserver sshd[5396]: Bad packet length 4081586742. + +rule = 5749 +alert = 4 +decoder = sshd + +[ssh unable to negotiate] +log 1 pass = Mar 3 10:56:18 junction sshd[32065]: fatal: Unable to negotiate with 202.191.177.33 port 3579: no matching cipher found. Their offer: 3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc [preauth] + +rule = 5753 +alert = 2 +decoder = sshd + +[ssh no matching key exchange] +log 1 pass = Sep 16 05:46:56 junction sshd[1961]: fatal: Unable to negotiate with 108.229.36.174: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1 [preauth] +log 2 pass = Apr 18 21:27:08 web2 sshd[23484]: fatal: Unable to negotiate a key exchange method [preauth] + +rule = 5752 +alert = 2 +decoder = sshd + +[invalid user] +log 1 pass = 2013-10-30T14:51:21.901728+01:00 srv sshd[12664]: Postponed keyboard-interactive for invalid user warez from 192.241.237.101 port 54197 ssh2 [preauth] +log 2 pass = 2013-10-30T14:51:24.140565+01:00 srv sshd[12664]: Failed keyboard-interactive/pam for invalid user warez from 192.241.237.101 port 54197 ssh2 +log 3 fail = 2013-10-30T14:51:24.139258+01:00 srv sshd[12664]: error: PAM: User not known to the underlying authentication module for illegal user warez from 192.241.237.101 +log 4 pass = 2013-10-30T14:51:30.267401+01:00 srv sshd[12671]: Invalid user opcione from 192.241.237.101 +log 5 fail = 2013-10-30T14:51:30.267906+01:00 srv sshd[12671]: input_userauth_request: invalid user opcione [preauth] + +rule = 5710 +alert = 5 +decoder = sshd + +[failed to create session] +log 1 pass = May 4 17:48:43 collectd sshd[15044]: pam_systemd(sshd:session): Failed to create session: Access denied + +rule = 5754 +alert = 1 +decoder = sshd + +[bad authorized_keys] +log 1 pass = May 4 18:30:04 collectd sshd[15191]: Authentication refused: bad ownership or modes for file /home/ansible/.ssh/authorized_keys + +rule = 5755 +alert = 2 +decoder = sshd + +[subsystem failed] +log 1 pass = May 5 05:00:38 junction sshd[28395]: subsystem request for netconf by user checker failed, subsystem not found + +rule = 5756 +alert = 0 +decoder = sshd + +[login failed] +log 1 pass = Aug 18 07:30:25 192.168.1.5 sshd[20247]: [ID 800047 auth.notice] Failed none for root from 192.168.1.1 port 36942 ssh2 + +rule = 5716 +alert = 5 +decoder = sshd + +[bad dns] +log 1 pass = Oct 20 12:33:07 ar-agent sshd[3433]: Address 192.168.18.54 maps to nmap.18.168.192.in-addr.arpa, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! + +rule = 5757 +alert = 0 +decoder = sshd + +[max auth attempts] +log 1 pass = Dec 27 03:23:51 r1 sshd[21183]: error: maximum authentication attempts exceeded for root from 183.106.179.x port 34100 ssh2 [preauth] +log 2 fail = Aug 31 10:19:36 hostname sshd[12079]: error: maximum authentication attempts exceeded for invalid user service from 202.188.45.36 port 37313 ssh2 [preauth] + +rule = 5758 +alert = 8 +decoder = sshd + +[bad protocol] +log 1 pass = Jun 28 19:35:39 xxx sshd[30255]: Bad protocol version identification '' from 188.18.81.21 port 60787 + +rule = 5701 +alert = 8 +decoder = sshd + +[blocked by tcpwrapper] +log 1 pass = Aug 30 18:12:54 hostname sshd[25350]: refused connect from 103.79.143.159 (103.79.143.159) + +rule = 2503 +alert = 5 +decoder = sshd + diff --git a/openarmor-rules/openarmor-testing/tests/su.ini b/openarmor-rules/openarmor-testing/tests/su.ini new file mode 100644 index 000000000..023106b2d --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/su.ini @@ -0,0 +1,27 @@ +[su: failed ] +log 1 pass = Apr 27 15:22:23 niban su[2921936]: failed: ttyq4 changing from ldap to root +log 2 pass = Jun 20 17:19:59 dactyl su: FAILED SU (to root) mmoorcro on pts/0 +rule = 5302 +alert = 9 +decoder = su + +[su: bad pass] +log 1 pass = Apr 27 15:22:23 niban su[234]: BAD SU ger to fwmaster on /dev/ttyp0 +rule = 5301 +alert = 5 +decoder = su + +[su: pam - auth fail] +log 1 fail = Apr 27 15:22:23 niban su(pam_unix)[23164]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=osaudit +log 2 fail = Apr 27 15:22:23 niban su(pam_unix)[2298]: authentication failure; logname= uid=1342 euid=0 tty= ruser=dcid rhost= user=root +rule = 5503 +alert = 5 +decoder = su + + +[su: work fts] +log 1 pass = Apr 22 17:51:51 enigma su: dcid to root on /dev/ttyp1 +rule = 5305 +alert = 4 +decoder = su + diff --git a/openarmor-rules/openarmor-testing/tests/sudo.ini b/openarmor-rules/openarmor-testing/tests/sudo.ini new file mode 100644 index 000000000..cea4a17fa --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/sudo.ini @@ -0,0 +1,38 @@ +[sudo: all] +log 1 pass = Apr 27 15:22:23 niban sudo: dcid : TTY=pts/4 ; PWD=/home/dcid ; USER=root ; COMMAND=/usr/bin/tail /var/log/snort/alert.fast +log 2 pass = Apr 14 10:59:01 enigma sudo: dcid : TTY=ttyp3 ; PWD=/home/dcid/openarmor-hids.0.1a/src/analysisd ; USER=root ; COMMAND=/bin/cp -pr ../../bin/addagent ../../bin/osaudit-logaudit ../../bin/openarmor-execd ../../bin/openarmor-logcollector ../../bin/openarmor-maild ../../bin/openarmor-remoted /var/openarmor/bin +log 3 pass = Apr 19 14:52:02 enigma sudo: dcid : TTY=ttyp3 ; PWD=/var/www/alex ; USER=root ; COMMAND=/sbin/chown dcid.dcid . +log 4 pass = Dec 30 19:36:11 rheltest sudo: cplummer : TTY=pts/2 ; PWD=/home/cplummer1 ; USER=root ; TSID=0000UM ; COMMAND=/bin/bash + +rule = 5403 +alert = 4 +decoder = sudo + +[Failed attempt to run sudo] +log 1 pass = Jun 25 15:51:13 precise32 sudo: mike : 1 incorrect password attempt ; TTY=pts/0 ; PWD=/root ; USER=root ; COMMAND=/bin/ls + +rule = 5401 +alert = 5 +decoder = sudo + +[First time user executed sudo] +log 1 pass = Jun 25 15:48:21 precise32 sudo: mike : TTY=pts/0 ; PWD=/home/vagrant ; USER=root ; COMMAND=/bin/su - + +rule = 5403 +alert = 4 +decoder = sudo + +[3 incorrect password attempts] +log 1 pass = Jun 25 16:15:45 precise32 sudo: mike : 3 incorrect password attempts ; TTY=pts/0 ; PWD=/root ; USER=root ; COMMAND=/bin/ls + +rule = 5404 +alert = 10 +decoder = sudo + +[unauthorized user] +log 1 pass = Apr 13 08:36:31 ix sudo: ddp2 : user NOT in sudoers ; TTY=ttypZ ; PWD=/home/ddp2 ; USER=root ; COMMAND=/bin/ls + +rule = 5405 +alert = 5 +decoder = sudo + diff --git a/openarmor-rules/openarmor-testing/tests/syslog.ini b/openarmor-rules/openarmor-testing/tests/syslog.ini new file mode 100644 index 000000000..44c202994 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/syslog.ini @@ -0,0 +1,43 @@ +[Uninteresting nouveau error.] +log 1 fail = Jul 18 09:21:57 localhost kernel: nouveau E[ PGRAPH][0000:0f:00.0] DATA_ERROR BEGIN_END_ACTIVE + +rule = 2944 +alert = 1 +decoder = + +[Uninteresting nouveau error.] +log 1 fail = Jul 18 09:21:57 localhost kernel: nouveau E[ PGRAPH][0000:0f:00.0] DATA_ERROR + +rule = 2944 +alert = 1 +decoder = + +[Incorrect chain/target/match.] +log 3 fail = Jul 18 10:51:43 localhost NetworkManager[1366]: (enp1s0) firewall zone remove failed: (32) COMMAND_FAILED: '/sbin/iptables -D INPUT_ZONES -t filter -i enp1s0 -g IN_public' failed: ipta +bles: No chain/target/match by that name. + +rule = 2941 +alert = 3 +decoder = NetworkManager + +[rsyslog may be dropping messages due to rate-limiting.] +log 1 fail = Feb 5 13:07:52 plugh rsyslogd-2177: imuxsock begins to drop messages from pid 12105 due to rate-limiting + +rule = 2945 +alert = 4 +decoder = + +[Non-standard syslog-ng format with year.] +log 1 fail = 2015 2015 Nov 13 13:40:01 ether rsyslogd-2177: imuxsock begins to drop messages from pid 17840 due to rate-limiting + +rule = 2945 +alert = 4 +decoder = + +[useradd failed] +log 1 fail = May 4 18:21:10 collectd useradd[15178]: failed adding user 'ansible', data deleted + +rule = 5905 +alert = 0 +decoder = + diff --git a/openarmor-rules/openarmor-testing/tests/sysmon.ini b/openarmor-rules/openarmor-testing/tests/sysmon.ini new file mode 100644 index 000000000..2208b4af1 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/sysmon.ini @@ -0,0 +1,18 @@ +[Sysmon EventID#1 - Suspicious svchost process] +log 1 pass = 2014 Dec 20 14:29:48 (HME-TEST-01) 10.0.15.14->WinEvtLog 2014 Dec 20 09:29:47 WinEvtLog: Microsoft-Windows-Sysmon/Operational: INFORMATION(1): Microsoft-Windows-Sysmon: SYSTEM: NT AUTHORITY: WIN-U93G48C7BOP: Process Create: UtcTime: 12/20/2014 2:29 PM ProcessGuid: {00000000-87DB-5495-0000-001045F25A00} ProcessId: 3048 Image: C:\Windows\system32\svchost.exe CommandLine: "C:\Windows\system32\NOTEPAD.EXE" C:\Users\Administrator\Desktop\openarmor.log User: WIN-U93G48C7BOP\Administrator LogonGuid: {00000000-84B8-5494-0000-0020CB330200} LogonId: 0x233CB TerminalSessionId: 1 IntegrityLevel: High HashType: SHA1 Hash: 9FEF303BEDF8430403915951564E0D9888F6F365 ParentProcessGuid: {00000000-84B9-5494-0000-0010BE4A0200} ParentProcessId: 848 ParentImage: C:\Windows\Explorer.EXE ParentCommandLine: C:\Windows\Explorer.EXE +rule = 18501 +alert = 12 +decoder = Sysmon-EventID#1 + +[Sysmon EventID#1 - non-Suspicious svchost process] +log 1 pass = 2014 Dec 20 12:15:13 (HME-TEST-01) 10.0.15.14->WinEvtLog 2014 Dec 20 09:29:47 WinEvtLog: Microsoft-Windows-Sysmon/Operational: INFORMATION(1): Microsoft-Windows-Sysmon: SYSTEM: NT AUTHORITY: WIN-U93G48C7BOP: Process Create: UtcTime: 12/20/2014 12:15 PM ProcessGuid: {00000000-87DB-5495-0000-001045F25A00} ProcessId: 3048 Image: C:\Windows\system32\svchost.exe CommandLine: "C:\windows\system32\svchost.exe -k defragsvc" User: NT AUTHORITY\SYSTEM LogonGuid: {00000000-84B8-5494-0000-0020CB330200} LogonId: 0x233CB TerminalSessionId: 1 IntegrityLevel: High HashType: SHA1 Hash: 9FEF303BEDF8430403915951564E0D9888F6F365 ParentProcessGuid: {00000000-84B9-5494-0000-0010BE4A0200} ParentProcessId: 848 ParentImage: C:\Windows\System32\services.exe ParentCommandLine: C:\Windows\System32\services.exe +rule = 18502 +alert = 0 +decoder = Sysmon-EventID#1 + +[Windows Event] +2015 Mar 30 15:47:04 WinEvtLog: System: INFORMATION(1): Sysmon: UserName: SYSTEM-NAME: SYSTEM-NAME: Process Create: UtcTime: 3/30/2015 10:47:04.494 PM ProcessGuid: {7531FA7E-D268-5519-0000-00105DF81A06} ProcessId: 4388 Image: C:\WINDOWS\system32\cmd.exe CommandLine: "C:\windows\system32\cmd.exe" User: SYSTEM-NAME\UserName LogonGuid: {7531FA7E-CFE1-5519-0000-0020F62C1906} LogonId: 0x6192cf6 TerminalSessionId: 3 IntegrityLevel: no level HashType: SHA1 Hash: 254E37EC33C921C5AB253F14F9274F349B3CCC2D ParentProcessGuid: {7531FA7E-CFE2-5519-0000-0010CC5A1906} ParentProcessId: 1008 ParentImage: C:\WINDOWS\explorer.exe ParentCommandLine: C:\windows\Explorer.EXE +rule = 18101 +alert = 0 +decoder = Sysmon-EventID#1 + diff --git a/openarmor-rules/openarmor-testing/tests/systemd.ini b/openarmor-rules/openarmor-testing/tests/systemd.ini new file mode 100644 index 000000000..73b9f5052 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/systemd.ini @@ -0,0 +1,7 @@ +[Stale file handle.] +log 3 fail = Jul 19 07:28:02 localhost systemd: Failed to mark scope session-1024.scope as abandoned : Stale file handle + +rule = 40701 +alert = 0 +decoder = + diff --git a/openarmor-rules/openarmor-testing/tests/unbound.ini b/openarmor-rules/openarmor-testing/tests/unbound.ini new file mode 100644 index 000000000..d82ba1176 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/unbound.ini @@ -0,0 +1,30 @@ +;[Can't assign requested address.] +;log 1 pass = 2014-05-20T09:01:07.283219-04:00 arrakis unbound: [9405:0] notice: sendto failed: Can't assign requested address +; +;rule = 500100 +;alert = 2 +;decoder = unbound +; +;[DNS A request] +;log 1 pass = 2014-07-14T14:00:02.814490-04:00 arrakis unbound: [2541:0] info: 127.0.0.1 talkgadget.google.com. A IN +; +;rule = 500101 +;alert = 0 +;decoder = unbound +; +;[Info grouping.] +;log 1 pass = 2014-07-14T14:00:05.507848-04:00 arrakis unbound: [2541:0] info: server stats for thread 0: 3 queries, 2 answers from cache, 1 recursions, 0 prefetch +; +;rule = 500002 +;alert = 1 +;decoder = unbound +; +;[Info grouping.] +;log 1 pass = 2014-07-14T14:00:05.507955-04:00 arrakis unbound: [2541:0] info: server stats for thread 0: requestlist max 0 avg 0 exceeded 0 jostled 0 +; +;rule = 500002 +;alert = 1 +;decoder = unbound +; + + diff --git a/openarmor-rules/openarmor-testing/tests/vsftpd.ini b/openarmor-rules/openarmor-testing/tests/vsftpd.ini new file mode 100644 index 000000000..32edb78c3 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/vsftpd.ini @@ -0,0 +1,16 @@ +[CONNECT] +log 1 pass = Wed Jul 27 18:32:27 2016 [pid 2] CONNECT: Client "fe80::baac:6fff:fe7d:d2e0" +log 2 pass = Wed Jul 27 18:32:27 2016 [pid 2] CONNECT: Client "10.11.12.13" + +rule = 11401 +alert = 3 +decoder = vsftpd + +[LOGIN] +log 1 pass = Mon Oct 24 11:32:53 2016 [pid 1] [$ALOC$] FAIL LOGIN: Client "10.55.112.101" +log 2 pass = Mon Oct 24 11:32:53 2016 [pid 1] [$ALOC$] FAIL LOGIN: Client "fe80::baac:6fff:fe7d:d2e0" + +rule = 11403 +alert = 5 +decoder = vsftpd + diff --git a/openarmor-rules/openarmor-testing/tests/web_appsec.ini b/openarmor-rules/openarmor-testing/tests/web_appsec.ini new file mode 100644 index 000000000..22be8005e --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/web_appsec.ini @@ -0,0 +1,161 @@ +[WordPress Comment Spam (coming from a fake search engine UA).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-comments-post.php HTTP/1.1" 403 181 "-" "Googlebot/1 +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-comments-post.php HTTP/1.1" 403 181 "-" "msnbot/1 +log 3 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-comments-post.php HTTP/1.1" 403 181 "-" "BingBot/1 + +rule = 31501 +alert = 6 +decoder = web-accesslog + + +[TimThumb vulnerability exploit attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /examplethumb.php?src=example.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31502 +alert = 6 +decoder = web-accesslog + + +[osCommerce login.php bypass attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /example.php/login.php?cPath= HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31503 +alert = 6 +decoder = web-accesslog + + +[osCommerce file manager login.php bypass attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /admin/example.php/login.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31504 +alert = 6 +decoder = web-accesslog + + +[TimThumb backdoor access attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /example/cache/externalexample.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31505 +alert = 6 +decoder = web-accesslog + + +[Cart.php directory transversal attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /examplecart.php?exampletemplatefile=../ HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31506 +alert = 6 +decoder = web-accesslog + + +[MSSQL Injection attempt (ur.php, urchin.js).] + +rule = 31507 +alert = 6 +decoder = web-accesslog + +[Blacklisted user agent (known malicious user agent).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "ZmEu" +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "libwww-perl/1.1 (X11)" +log 3 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "the beast" +log 4 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "Morfeus" +log 5 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "ZmEu (X11)" +log 6 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "Nikto (X11)" +log 7 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "w3af.sourceforge.net (X11)" +log 8 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET / HTTP/1.1" 403 181 "-" "MJ12bot/v (X11)" + +rule = 31508 +alert = 6 +decoder = web-accesslog + + +[CMS (WordPress or Joomla) login attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /example/wp-login.php HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /administrator HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +rule = 31509 +alert = 3 +decoder = web-accesslog + + +# Can't yet test repeat logs +;[CMS (WordPress or Joomla) brute force attempt.] +; +;rule = 31510 +;alert = 8 +;decoder = web-accesslog + +[Blacklisted user agent (wget).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /index.html? HTTP/1.1" 200 4617 "-" "Wget/1.15 (linux-gnu)" + +rule = 31511 +alert = 0 +decoder = web-accesslog + +[Uploadify vulnerability exploit attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /example/uploadify.php?src=http://example.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31512 +alert = 6 +decoder = web-accesslog + +[BBS delete.php exploit attempt.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET example/delete.php?board_skin_path=http://example.php HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31513 +alert = 6 +decoder = web-accesslog + +[Simple shell.php command execution.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET example/shell.php?cmd= HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31514 +alert = 6 +decoder = web-accesslog + +[PHPMyAdmin scans (looking for setup.php).] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" + +rule = 31515 +alert = 6 +decoder = web-accesslog + +[Suspicious URL access.] +log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /db/config.php.swp HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 2 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /db/config.php.bak HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 3 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /db/.htaccess HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 4 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /server-status HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 5 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /.ssh HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" +log 6 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /.history HTTP/1.1" 404 4617 "-" "Mozilla/15 (linux-gnu)" + +rule = 31516 +alert = 6 +decoder = web-accesslog + +[POST request received.] +log 1 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST / HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" + +rule = 31530 +alert = 3 +decoder = web-accesslog + +[Ignoring often post requests inside /wp-admin and /admin.] +log 1 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-admin HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +log 2 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /admin HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +rule = 31531 +alert = 0 +decoder = web-accesslog + +# Can't currently test repeat requests +;[High amount of POST requests in a small period of time (likely bot).] +;log 1 fail = 10.1.1.5 - - [29/Dec/2014:11:37:47 -0500] POST / HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" +;rule = 31533 +;alert = 10 +;decoder = web-accesslog + +# This never matches due to Rule web_rules.xml id: '31104' Description: 'Common web attack.' +;[Anomaly URL query (attempting to pass null termination).] +;log 1 pass = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "GET /example.php?example%00 HTTP/1.1" 403 181 "-" "Mozilla/5.0 (X11)" +; +;rule = 31550 +;alert = 6 +;decoder = web-accesslog diff --git a/openarmor-rules/openarmor-testing/tests/web_rules.ini b/openarmor-rules/openarmor-testing/tests/web_rules.ini new file mode 100644 index 000000000..6c3125743 --- /dev/null +++ b/openarmor-rules/openarmor-testing/tests/web_rules.ini @@ -0,0 +1,29 @@ +[A web attack returned code 200 (success).] +log 1 pass = 2014-12-20 21:34:37 W3SVC58 XXX-XXWEB-01 1.2.3.4 GET /search/programdetails.aspx id=3542&print=');declare%20@c%20cursor;declare%20@d%20varchar(4000);set%20@c=cursor%20for%20select%20'update%20%5B'%2BTABLE_NAME%2B'%5D%20set%20%5B'%2BCOLUMN_NAME%2B'%5D=%5B'%2BCOLUMN_NAME%2B'%5D%2Bcase%20ABS(CHECKSUM(NewId()))%257%20when%200%20then%20''''%2Bchar(60)%2B''div%20style=%22display:none%22''%2Bchar(62)%2B''abortion%20pill%20prescription%20''%2Bchar(60)%2B''a%20href=%22http:''%2Bchar(47)%2Bchar(47)%2BREPLACE(case%20ABS(CHECKSUM(NewId()))%253%20when%200%20then%20''www.yeronimo.com@template''%20when%201%20then%20''www.tula-point.ru@template''%20else%20''blog.tchami.com@template''%20end,''@'',char(47))%2B''%22''%2Bchar(62)%2Bcase%20ABS(CHECKSUM(NewId()))%253%20when%200%20then%20''online''%20when%201%20then%20''i%20need%20to%20buy%20the%20abortion%20pill''%20else%20''abortion%20pill''%20end%20%2Bchar(60)%2Bchar(47)%2B''a''%2Bchar(62)%2B''%20where%20to%20buy%20abortion%20pill''%2Bchar(60)%2Bchar(47)%2B''div''%2Bchar(62)%2B''''%20else%20''''%20end'%20FROM%20sysindexes%20AS%20i%20INNER%20JOIN%20sysobjects%20AS%20o%20ON%20i.id=o.id%20INNER%20JOIN%20INFORMATION_SCHEMA.COLUMNS%20ON%20o.NAME=TABLE_NAME%20WHERE(indid=0%20or%20indid=1)%20and%20DATA_TYPE%20like%20'%25varchar'%20and(CHARACTER_MAXIMUM_LENGTH=-1%20or%20CHARACTER_MAXIMUM_LENGTH=2147483647);open%20@c;fetch%20next%20from%20@c%20into%20@d;while%20@@FETCH_STATUS=0%20begin%20exec%20(@d);fetch%20next%20from%20@c%20into%20@d;end;close%20@c-- 80 - 173.201.216.6 HTTP/1.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64;+rv:24.0)+Gecko/20100101+Firefox/24.0');declare+@c+cursor;declare+@d+varchar(4000);set+@c=cursor+for+select+'update+['+TABLE_NAME+']+set+['+COLUMN_NAME+']=['+COLUMN_NAME+']+case+ABS(CHECKSUM(NewId()))%7+when+0+then+''''+char(60)+''div+style="display:none"''+char(62)+''abortion+pill+prescription+''+char(60)+''a+href="http:''+char(47)+char(47)+REPLACE(case+ABS(CHECKSUM(NewId()))%3+when+0+then+''www.yeronimo.com@template''+when+1+then+''www.tula-point.ru@template''+else+''blog.tchami.com@template''+end,''@'',char(47))+''"''+char(62)+case+ABS(CHECKSUM(NewId()))%3+when+0+then+''online''+when+1+then+''i+need+to+buy+the+abortion+pill''+else+''abortion+pill''+end++char(60)+char(47)+''a''+char(62)+''+where+to+buy+abortion+pill''+char(60)+char(47)+''div''+char(62)+''''+else+''''+end'+FROM+sysindexes+AS+i+INNER+JOIN+sysobjects+AS+o+ON+i.id=o.id+INNER+JOIN+INFORMATION_SCHEMA.COLUMNS+ON+o.NAME=TABLE_NAME+WHERE(indid=0+or+indid=1)+and+DATA_TYPE+like+'%varchar'+and(CHARACTER_MAXIMUM_LENGTH=-1+or+CHARACTER_MAXIMUM_LENGTH=2147483647);open+@c;fetch+next+from+@c+into+@d;while+@@FETCH_STATUS=0+begin+exec+(@d);fetch+next+from+@c+into+@d;end;close+@c-- - http://google.com');declare+@c+cursor;declare+@d+varchar(4000);set+@c=cursor+for+select+'update+['+TABLE_NAME+']+set+['+COLUMN_NAME+']=['+COLUMN_NAME+']+case+ABS(CHECKSUM(NewId()))%7+when+0+then+''''+char(60)+''div+style="display:none"''+char(62)+''abortion+pill+prescription+''+char(60)+''a+href="http:''+char(47)+char(47)+REPLACE(case+ABS(CHECKSUM(NewId()))%3+when+0+then+''www.yeronimo.com@template''+when+1+then+''www.tula-point.ru@template''+else+''blog.tchami.com@template''+end,''@'',char(47))+''"''+char(62)+case+ABS(CHECKSUM(NewId()))%3+when+0+then+''online''+when+1+then+''i+need+to+buy+the+abortion+pill''+else+''abortion+pill''+end++char(60)+char(47)+''a''+char(62)+''+where+to+buy+abortion+pill''+char(60)+char(47)+''div''+char(62)+''''+else+''''+end'+FROM+sysindexes+AS+i+INNER+JOIN+sysobjects+AS+o+ON+i.id=o.id+INNER+JOIN+INFORMATION_SCHEMA.COLUMNS+ON+o.NAME=TABLE_NAME+WHERE(indid=0+or+indid=1)+and+DATA_TYPE+like+'%varchar'+and(CHARACTER_MAXIMUM_LENGTH=-1+or+CHARACTER_MAXIMUM_LENGTH=2147483647);open+@c;fetch+next+from+@c+into+@d;while+@@FETCH_STATUS=0+begin+exec+(@d);fetch+next+from+@c+into+@d;end;close+@c-- www.somesite.org 200 0 0 36560 3942 78 +rule = 31106 +alert = 6 +decoder = web-accesslog-iis6 + +[NOT A web attack returned code 200 (success).] +log 1 fail = 10.0.0.5 - - [1/Apr/2014:00:00:01 -0500] "POST /wp-admin HTTP/1.1" 200 181 "-" "Mozilla/5.0 (X11)" +rule = 31106 +alert = 6 +decoder = web-accesslog + +[A web page returned code 302 code] +log 1 pass = 2015-07-28 15:07:26 1.2.3.4 GET /QOsa/Browser/Default.aspx UISessionId=SN1234123&DeviceId=SN12312232SHARP+MX-4111N 80 - 31.3.3.7 OpenSystems/1.0;+product-family="85";+product-version="123ER123" 302 0 0 624 +rule = 31108 +alert = 0 +decoder = web-accesslog-iis-default + +[A web page returned code 404 (not found)] +log 1 pass = 2015-03-11 21:59:09 1.2.3.4 GET /console/faces/com_sun_web_ui/jsp/version/version_30.jsp - 80 - 31.3.3.7 Sun+Web+Console+Fingerprinter/7.15 - 404 0 2 0 +rule = 31101 +alert = 5 +decoder = web-accesslog-iis-default + +[A web attacked returned code 404] +log 1 pass = 2015-03-11 22:01:59 1.2.3.4 GET /CFIDE/adminapi/customtags/l10n.cfm attributes.id=test&attributes.file=../../administrator/mail/download.cfm&filename=../lib/password.properties&attributes.locale=it&attributes.var=it&attributes.jscript=false&attributes.type=text/html&attributes.charset=UTF-8&thisTag.executionmode=end&thisTag.generatedContent=test 443 - 31.3.3.7 - - 404 0 2 0 +rule = 31104 +alert = 6 +decoder = web-accesslog-iis-default diff --git a/openarmor-rules/rules.d/00-crs-rules_config.xml b/openarmor-rules/rules.d/00-crs-rules_config.xml new file mode 100644 index 000000000..c9ab28996 --- /dev/null +++ b/openarmor-rules/rules.d/00-crs-rules_config.xml @@ -0,0 +1,69 @@ + + + + + + syslog + Generic template for all syslog rules. + + + + + + firewall + Generic template for all firewall rules. + + + + + + ids + Generic template for all ids rules. + + + + + + web-log + Generic template for all web rules. + + + + + + squid + Generic template for all web proxy rules. + + + + + + windows + Generic template for all windows rules. + + + + + + openarmor + Generic template for all openarmor rules. + + + + + diff --git a/openarmor-rules/rules.d/00-crs-syslog_rules.xml b/openarmor-rules/rules.d/00-crs-syslog_rules.xml new file mode 100644 index 000000000..8ac832a7f --- /dev/null +++ b/openarmor-rules/rules.d/00-crs-syslog_rules.xml @@ -0,0 +1,725 @@ + + + + + + +core_dumped|failure|error|attack| bad |illegal |denied|refused|unauthorized|fatal|failed|Segmentation Fault|Corrupted + + + + + + ^Couldn't open /etc/securetty + File missing. Root access unrestricted. + + + + $BAD_WORDS + alert_by_email + Unknown problem somewhere in the system. + + + + Non standard syslog message (size too large). + + + + ^exiting on signal + Syslogd exiting (logging stopped). + + + + syslogd + ^restart + Syslogd restarted. + + + + ^syslogd \S+ restart + Syslogd restarted. + + + + file system full|No space left on device + File system full. + low_diskspace, + + + + killed by SIGTERM + Process exiting (killed). + service_availability, + + + + 1002 + terminated without error|can't verify hostname: getaddrinfo| + PPM exceeds tolerance + Ignoring known false positives on rule 1002.. + + + + segfault at + Process segfaulted. + service_availability, + + + + + + + + + + ^automount|^mount + NFS rules grouped. + + + + 2100 + nfs: mount failure + Unable to mount the NFS share. + + + + 2100 + reason given by server: Permission denied + Unable to mount the NFS directory. + + + + ^rpc\.mountd: refused mount request from + Unable to mount the NFS directory. + + + + 2100 + lookup for \S+ failed + Automount informative message + + + + + + + + + ^Deactivating service + Excessive number connections to a service. + + + + + + + + + FAILED LOGIN |authentication failure| + Authentication failed for|invalid password for| + LOGIN FAILURE|auth failure: |authentication error| + authinternal failed|Failed to authorize| + Wrong password given for|login failed|Auth: Login incorrect| + Failed to authenticate user + authentication_failed, + User authentication failure. + + + + more authentication failures;|REPEATED login failures + User missed the password more than one time + authentication_failed, + + + + ^refused connect from| + ^libwrap refused connection| + Connection from \S+ denied + Connection blocked by Tcp Wrappers. + access_denied, + + + + ILLEGAL ROOT LOGIN|ROOT LOGIN REFUSED + Illegal root login. + invalid_login, + + + + ^ROOT LOGIN on + Physical root login. + + + + ^Authentication passed + Pop3 Authentication passed. + + + + openldap + OpenLDAP group. + + + + 2507 + ACCEPT from + OpenLDAP connection open. + + + + 2507 + 2508 + + RESULT tag=97 err=49 + OpenLDAP authentication failed. + + + + + + + + + + rshd + rshd messages grouped. + + + + 2550 + ^Connection from \S+ on illegal port$ + Connection to rshd from unprivileged port. Possible network scan. + connection_attempt, + + + + + + + + + ^procmail + Ignoring procmail messages. + + + + + + + + + ^smart + Pre-match rule for smartd. + + + + 2800 + No configuration file /etc/smartd\.conf found + Smartd Started but not configured + + + + 2800 + Unable to register ATA device + Smartd configuration problem + + + + 2800 + No such device or address + Device configured but not available to Smartd + + + + + + + + + ^kernel + Pre-match rule for kernel messages + + + + 5100 + PCI: if you experience problems, try using option + Informative message from the kernel. + + + + 5100 + modprobe: Can't locate module sound + Informative message from the kernel + + + + 5100 + Oversized packet received from + Error message from the kernel. + Ping of death attack. + + + + 5100 + Promiscuous mode enabled| + device \S+ entered promiscuous mode + Interface entered in promiscuous(sniffing) mode. + promisc, + + + + 5100 + end_request: I/O error, dev fd0, sector 0| + Buffer I/O error on device fd0, logical block 0 + Invalid request to /dev/fd0 (bug on the kernel). + + + + 5100 + svc: unknown program 100227 \(me 100003\) + NFS incompatibility between Linux and Solaris. + + + + 5100 + svc: bad direction + NFS incompatibility between Linux and Solaris. + + + + 5100 + Out of Memory: + System running out of memory. + Availability of the system is in risk. + service_availability, + + + + 5100 + I/O error: dev |end_request: I/O error, dev + Kernel Input/Output error + + + + 5100 + Forged DCC command from + IRC misconfiguration + + + + 5100 + ipw2200: Firmware error detected\.| ACPI Error + Kernel device error. + + + + 5100 + usbhid: probe of + Kernel usbhid probe error (ignored). + + + + 5100 + Kernel log daemon terminating + system_shutdown, + System is shutting down. + + + + 5100 + ADSL line is down + Monitor ADSL line is down. + + + + 5100 + ADSL line is up + Monitor ADSL line is up. + + + + ^hpiod: unable to ParDevice + Ignoring hpiod for producing useless logs. + + + + + + + + + crond|crontab + Crontab rule group. + + + + 2830 + ^unable to exec + Wrong crond configuration + + + + 2830 + BEGIN EDIT + Crontab opened for editing. + + + + 2830 + REPLACE + Crontab entry changed. + + + + 2832 + ^\(root\) + Root's crontab entry changed. + + + + + + + + + + su + Initial grouping for su messages. + + + + 5300 + authentication failure; |failed|BAD su|^- + User missed the password to change UID (user id). + authentication_failed, + + + + 5301 + ^root + User missed the password to change UID to root. + authentication_failed, + + + + 5300 + session opened for user root|^'su root'| + ^\+ \S+ \S+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]root$|^\S+ to root on|^SU \S+ \S+ \+ \S+ \S+-root$ + User successfully changed UID to root. + authentication_success, + + + + 5300 + session opened for user|succeeded for| + ^\+|^\S+ to |^SU \S+ \S+ \+ + User successfully changed UID. + authentication_success, + + + + 5303, 5304 + + alert_by_email + First time (su) is executed by user. + + + + 5300 + unknown class + OpenBSD uses login classes, and an inappropriate login class was used. + A user has attempted to su to an unknown class. + + + + + + + + + + Integrity Check failed: File could not + Problems with the tripwire checking + + + + + + + + + ^new group + New group added to the system + + + + ^new user|^new account added + New user added to the system + + + + ^delete user|^account deleted|^remove group + Group (or user) deleted from the system + + + + ^changed user + Information from the user was changed + + + + useradd + failed adding user + useradd failed. + + + + + + + + + + sudo + Initial group for sudo messages + + + + 5400 + incorrect password attempt + Failed attempt to run sudo + + + + 5400 + ; USER=root ; COMMAND=| ; USER=root ; TSID=\S+ ; COMMAND= + Successful sudo to ROOT executed + + + + 5400 + alert_by_email + + First time user executed sudo. + + + + 5401 + 3 incorrect password attempts + Three failed attempts to run sudo + + + + 5400 + user NOT in sudoers + Unauthorized user attempted to use sudo. + + + + + + + + + ^pptpd + PPTPD messages grouped + + + + 9100 + ^GRE: \S+ from \S+ failed: status = -1 + PPTPD failed message (communication error) + http://poptop.sourceforge.net/dox/gre-protocol-unavailable.phtml + + + + 9100 + ^tcflush failed: Bad file descriptor + PPTPD communication error + + + + + + + + + authentication_success + alert_by_email + + authentication_success + First time user logged in. + + + + + + + ^squid + Squid syslog messages grouped + + + + 9200 + ^ctx: enter level|^sslRead|^urlParse: Illegal | + ^httpReadReply: Request not yet |^httpReadReply: Excess data + Squid debug message + + + + + + + windows-date-format + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} startup | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} status | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} remove | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} configure | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} install | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} purge | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} trigproc | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} conffile | + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} upgrade + Dpkg (Debian Package) log. + + + + 2900 + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} install + New dpkg (Debian Package) requested to install. + + + + 2900 + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} status installed + New dpkg (Debian Package) installed. + config_changed, + + + + 2900 + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} remove| + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} purge + Dpkg (Debian Package) removed. + config_changed, + + + + + + + ^yum + Yum logs. + + + + yum\.log$ + ^Installed|^Updated|^Erased + Yum logs. + + + + 2930,2931 + ^Installed + config_changed, + New Yum package installed. + + + + 2930,2931 + ^Updated + config_changed, + Yum package updated. + + + + 2930,2931 + ^Erased + config_changed, + Yum package deleted. + + + + + 5100 + mptscsih + Grouping for the mptscrih rules. + + + + 5100 + mptbase + Grouping for the mptbase rules. + + + + 2935 + FAILED + Possible Disk failure. SCSI controller error. + + + + 2936 + failed + SCSI RAID ARRAY ERROR, drive failed. + + + + 2936 + degraded + SCSI RAID is now in a degraded status. + + + + ^NetworkManager + NetworkManager grouping. + + + + 2940 + No chain/target/match by that name\.$ + Incorrect chain/target/match. + + + + 1002 + g_slice_set_config: assertion `sys_page_size == 0' failed + Uninteresting gnome error. + + + + ^nouveau + nouveau driver grouping + + + + 2943 + DATA_ERROR BEGIN_END_ACTIVE$| DATA_ERROR$ + Uninteresting nouveau error. + + + + ^rsyslogd + ^imuxsock begins to drop messages + https://isc.sans.edu/diary/Are+you+losing+system+logging+information+%28and+don%27t+know+it%29%3F/15106 + rsyslog may be dropping messages due to rate-limiting. + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-apache_rules.xml b/openarmor-rules/rules.d/50-crs-apache_rules.xml new file mode 100644 index 000000000..0d0fadaf4 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-apache_rules.xml @@ -0,0 +1,325 @@ + + + + + + apache-errorlog + Apache messages grouped. + + + + 30100 + ^\[error\] + Apache error messages grouped. + + + + 30100 + ^\[warn\] + Apache warn messages grouped. + + + + 30100 + ^\[notice\] + Apache notice messages grouped. + + + + 30103 + exit signal Segmentation Fault + Apache segmentation fault. + http://www.securityfocus.com/infocus/1633 + service_availability, + + + + 30101 + denied by server configuration + Attempt to access forbidden file or directory. + access_denied, + + + + 30101 + Directory index forbidden by rule + Attempt to access forbidden directory index. + access_denied, + + + + 30101 + Client sent malformed Host header + Code Red attack. + http://www.cert.org/advisories/CA-2001-19.html + CERT: Advisory CA-2001-19 "Code Red" Worm Exploiting Buffer Overflow In IIS Indexing Service DLL + automatic_attack, + + + + 30102 + authentication failed + User authentication failed. + authentication_failed, + + + + 30101 + user \S+ not found|user \S+ in realm .* not found + Attempt to login using a non-existent user. + invalid_login, + + + + 30101 + authentication failure + User authentication failed. + authentication_failed, + + + + 30101 + File does not exist: | + failed to open stream: No such file or directory| + Failed opening + Attempt to access an non-existent file (those are reported on the access.log). + unknown_resource, + + + + + 30101 + Invalid URI in request + Invalid URI (bad client request). + invalid_request, + + + + 30115 + + Multiple Invalid URI requests from + same source. + invalid_request, + + + + 30101 + File name too long|request failed: URI too long + Invalid URI, file name too long. + invalid_request, + + + + + 30101 + mod_security: Access denied|ModSecurity: Access denied + Access attempt blocked by Mod Security. + access_denied, + + + + 30118 + + Multiple attempts blocked by Mod Security. + access_denied, + + + + 30101 + Resource temporarily unavailable: + Apache without resources to run. + service_availability, + + + + ^mod_security-message: + Modsecurity alert. + + + + 30200 + ^mod_security-message: Access denied + Modsecurity access denied. + access_denied, + + + + 30201 + Multiple attempts blocked by Mod Security. + access_denied, + + + + + 30100 + \[\S*:error\] + Apache error messages grouped. + + + + 30100 + \[\S+:warn\] + Apache warn messages grouped. + + + + 30100 + \[\S+:notice\] + Apache notice messages grouped. + + + + 30303 + exit signal Segmentation Fault + Apache segmentation fault. + http://www.securityfocus.com/infocus/1633 + service_availability, + + + + 30301 + AH01630 + Attempt to access forbidden file or directory. + access_denied, + + + + 30301 + AH01276 + Attempt to access forbidden directory index. + access_denied, + + + + 30301 + AH00550 + Client sent malformed Host header. Possible Code Red attack. + http://www.cert.org/advisories/CA-2001-19.html + CERT: Advisory CA-2001-19 "Code Red" Worm Exploiting Buffer Overflow In IIS Indexing Service DLL + automatic_attack, + + + + 30301 + AH01617|AH01807|AH01694|AH01695|AH02009|AH02010 + User authentication failed. + authentication_failed, + + + + 30301 + AH01618|AH01808|AH01790 + Attempt to login using a non-existent user. + invalid_login, + + + + 30309 + + Multiple authentication failures with invalid user. + authentication_failures, + + + + 30301 + File does not exist: | + failed to open stream: No such file or directory| + Failed opening + Attempt to access an non-existent file (those are reported on the access.log). + unknown_resource, + + + + 30301 + AH00126 + Invalid URI (bad client request). + invalid_request, + + + + 30315 + + Multiple Invalid URI requests from + same source. + invalid_request, + + + + 30301 + AH00565 + Invalid URI, file name too long. + invalid_request, + + + + 30301 + PHP Notice: + PHP Notice in Apache log + + + + 30301 + AH00036 + File name too long: + File name too long. + + + + 30301 + Permission denied: | client denied by server configuration: + Permission denied. + + + + 30301 + AH02811 + script not found + A script cannot be accessed. + + + + + 30301 + ModSecurity: Warning + ModSecurity Warning messages grouped + + + + 30301 + ModSecurity: Access denied + ModSecurity Access denied messages grouped + + + + 30301 + ModSecurity: Audit log: + ModSecurity Audit log messages grouped + + + + 30402 + with code 403 + ModSecurity rejected a query + + + + + diff --git a/openarmor-rules/rules.d/50-crs-apparmor_rules.xml b/openarmor-rules/rules.d/50-crs-apparmor_rules.xml new file mode 100644 index 000000000..3e4722195 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-apparmor_rules.xml @@ -0,0 +1,51 @@ + + + + + + + + + + 5100 + iptables + apparmor= + Apparmor grouping + + + + 52000 + ALLOWED|STATUS + Ignore ALLOWED or STATUS + + + + 52000 + DENIED + apparmor= + Apparmor DENIED + + + + 52002 + exec + Apparmor DENIED exec operation. + + + + 52002 + mknod + Apparmor DENIED mknod operation. + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-arpwatch_rules.xml b/openarmor-rules/rules.d/50-crs-arpwatch_rules.xml new file mode 100644 index 000000000..6a2bb0687 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-arpwatch_rules.xml @@ -0,0 +1,89 @@ + + + + + + arpwatch + Grouping of the arpwatch rules. + + + + 7200 + alert_by_email + + Arpwatch new host detected. + new_host, + + + + 7200 + flip flop + Arpwatch "flip flop" message. + IP address/MAC relation changing too often. + ip_spoof, + + + + 7200 + reaper: pid + Arpwatch exiting. + service_availability, + + + + 7200 + changed ethernet address + Changed network interface for ip address. + ip_spoof, + + + + 7200 + bad interface eth0|exiting|Running as + Arpwatch startup/exiting messages. + + + + 7200 + sent bad addr len + Arpwatch detected bad address len (ignored). + + + + 7200 + /dev/bpf0: Permission denied + arpwatch probably run with wrong permissions + + + + 7200 + reused old ethernet address + An IP has reverted to an old ethernet address. + + + + 7200 + ethernet mismatch + Possible arpspoofing attempt. + ip_spoof, + + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-asterisk_rules.xml b/openarmor-rules/rules.d/50-crs-asterisk_rules.xml new file mode 100644 index 000000000..abcf9a3a7 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-asterisk_rules.xml @@ -0,0 +1,129 @@ + + + + + + + asterisk + Asterisk messages grouped. + + + + 6200 + ^NOTICE + Asterisk notice messages grouped. + + + + 6200 + ^WARN + Asterisk warning message. + + + + 6200 + ^ERROR + Asterisk error message. + + + + 6201 + Wrong password + Login session failed. + authentication_failed, + + + + 6201 + Username/auth name mismatch + Login session failed (invalid user). + invalid_login, + + + + 6201 + No matching peer found + Login session failed (invalid extension). + invalid_login, + + + + 6211 + + Multiple failed logins (user enumeration in process). + + + + 6210 + + Multiple failed logins. + + + + 6212 + + Extension enumeration. + + + + + + 6201 + No registration for peer + Login session failed (invalid iax user). + invalid_login, + + + + + 6253 + + Extension IAX Enumeration. + + + + + 6202 + Don't know how to respond via + Possible Registration Hijacking. + invalid_login, + + + + + 6201 + failed MD5 authentication + IAX peer Wrong Password. + invalid_login, + + + + + 6256 + + Multiple failed logins. + + + + 6201 + No matching peer found|extension not found in context + Login session failed (invalid extension). + invalid_login, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-cimserver_rules.xml b/openarmor-rules/rules.d/50-crs-cimserver_rules.xml new file mode 100644 index 000000000..54d8ee2eb --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-cimserver_rules.xml @@ -0,0 +1,36 @@ + + + + + cimserver + cimserver messages grouped. + + + + 9600 + Authentication failed + Compaq Insight Manager authentication failure. + authentication_failed, + + + + 9600 + Server stopped + Compaq Insight Manager stopped. + service_availability, + + + + diff --git a/openarmor-rules/rules.d/50-crs-cisco-ios_rules.xml b/openarmor-rules/rules.d/50-crs-cisco-ios_rules.xml new file mode 100644 index 000000000..a70c08d05 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-cisco-ios_rules.xml @@ -0,0 +1,96 @@ + + + + + + cisco-ios + Grouping of Cisco IOS rules. + + + + 4700 + -0- + Cisco IOS emergency message. + + + + + 4700 + -1- + Cisco IOS alert message. + + + + 4700 + -2- + Cisco IOS critical message. + + + + 4700 + -3- + Cisco IOS error message. + + + + 4700 + -4- + Cisco IOS warning message. + + + + 4700 + -5- + Cisco IOS notification message. + + + + 4700 + -6- + Cisco IOS informational message. + + + + 4700 + -7- + Cisco IOS debug message. + + + + 4715 + ^%SYS-5-CONFIG + Cisco IOS router configuration changed. + config_changed, + + + + 4715 + ^%SEC_LOGIN-5-LOGIN_SUCCESS + Successful login to the router. + authentication_success, + + + + 4714 + ^%SEC_LOGIN-4-LOGIN_FAILED + Failed login to the router. + authentication_failed, + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-clam_av_rules.xml b/openarmor-rules/rules.d/50-crs-clam_av_rules.xml new file mode 100644 index 000000000..ebc8da8f8 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-clam_av_rules.xml @@ -0,0 +1,69 @@ + + + + + clamd + Grouping of the clamd rules. + + + + freshclam + ClamAV database update + + + + 52500 + FOUND + Virus detected + virus + + + + 52500 + ^ERROR: + Clamd error + virus + + + + 52500 + ^WARNING: + Clamd warning + virus + + + + 52500 + clamd daemon + Clamd restarted + virus + + + + 52500 + Database modification detected + Clamd database updated + virus + + + + 52501 + ClamAV update process started + ClamAV database update + virus + + + + 52501 + Database updated + ClamAV database updated + virus + + + + 52501 + Incremental update failed|Error while reading database from|Update failed\. + Could not download the incremental virus definition updates. + + + diff --git a/openarmor-rules/rules.d/50-crs-courier_rules.xml b/openarmor-rules/rules.d/50-crs-courier_rules.xml new file mode 100644 index 000000000..faed2c505 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-courier_rules.xml @@ -0,0 +1,67 @@ + + + + + + + courier + Grouping for the courier rules. + + + + 3900 + ^Connection, + New courier (imap/pop3) connection. + connection_attempt, + + + + 3900 + ^LOGIN FAILED,| FAILED: + Courier (imap/pop3) authentication failed. + authentication_failed, + + + + 3900 + ^LOGOUT,|^DISCONNECTED + Courier logout/timeout. + + + + 3900 + ^LOGIN, + Courier (imap/pop3) authentication success. + authentication_success, + + + + 3902 + Courier brute force (multiple failed logins). + authentication_failures, + + + + + 3901 + + Multiple connection attempts from same source. + recon, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-dnsmasq_rules.xml b/openarmor-rules/rules.d/50-crs-dnsmasq_rules.xml new file mode 100644 index 000000000..cf9419572 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-dnsmasq_rules.xml @@ -0,0 +1,12 @@ + + + + dnsmasq + dnsmasq grouping rule. + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-dovecot_rules.xml b/openarmor-rules/rules.d/50-crs-dovecot_rules.xml new file mode 100644 index 000000000..a7c44a1ea --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-dovecot_rules.xml @@ -0,0 +1,91 @@ + + + + + + dovecot + Dovecot Messages Grouped. + + + + 9700 + login: Login: + Dovecot Authentication Success. + authentication_success, + + + + 9700 + Password mismatch$ + Dovecot Authentication Failed. + authentication_failed, + + + + 9700 + starting up + Dovecot is Starting Up. + + + + 9700 + ^Fatal: + alert_by_email + Dovecot Fatal Failure. + + + + 9700 + user not found|User not known|unknown user|auth failed + Dovecot Invalid User Login Attempt. + invalid_login,authentication_failed, + + + + 9700 + : Disconnected: + Dovecot Session Disconnected. + + + + 9700 + : Aborted login + Dovecot Aborted Login. + invalid_login, + + + + + + 9702 + + Dovecot Multiple Authentication Failures. + authentication_failures, + + + + 9705 + + Dovecot brute force attack (multiple auth failures). + authentication_failures, + + + + dovecot-info + dovecot-info grouping. + + + + 9770 + user not found|User not known|unknown user|auth failed + Dovecot Invalid User Login Attempt. + invalid_login,authentication_failed, + + + + diff --git a/openarmor-rules/rules.d/50-crs-dropbear_rules.xml b/openarmor-rules/rules.d/50-crs-dropbear_rules.xml new file mode 100644 index 000000000..159ebf019 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-dropbear_rules.xml @@ -0,0 +1,108 @@ + + + + + + + + + + dropbear + Grouping for dropbear rules. + + + + 51000 + Failed to get kex value + Failed to get key exchange value + + + + 51000 + Premature kexdh_init message received + Premature kexdh_init message + + + + 51000 + bad password attempt for + Bad password attempt. + authentication_failed, + + + + 51000 + attempt for nonexistent user + Bad password attempt for non existent user. + authentication_failed, + + + + authentication_failed + + dropbear + dropbear brute force attempt. + authentication_failures, + + + + 51000 + exit after auth \(\S+\): Disconnect received + User disconnected. + + + + 51000 + exit before auth + Client exited before authentication. + recon, + + + + 51000 + + dropbear brute force attempt. + authentication_failures, + + + + + 51000 + Incompatible remote version + Incompatible remote version. + recon, + + + + 51000 + password auth succeeded for + User successfully logged in using a password. + authentication_success, + + + + 51000 + Pubkey auth succeeded + User successfully logged in using a public key. + authentication_success, + + + + dropbear + 1002 + Error listening: Address already in use + Dropbear cannot listen on port. + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-exim_rules.xml b/openarmor-rules/rules.d/50-crs-exim_rules.xml new file mode 100644 index 000000000..dfb7028a1 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-exim_rules.xml @@ -0,0 +1,55 @@ + + + + + windows-date-format + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} SMTP + Exim SMTP Messages Grouped. + + + + windows-date-format + ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} dovecot + dovecot messages grouped. + + + + 13001 + authenticator failed + Exim Auth failed + invalid_login,authentication_failed, + + + + 13006 + + Exim brute force attack (multiple auth failures). + authentication_failures, + + + + 13000 + connection count = + Exim connection + + + + 13000 + lost$ + Exim connection lost + + + + 13000 + dropped: too many syntax or protocol errors + Exim syntax or protocol errors + + + diff --git a/openarmor-rules/rules.d/50-crs-firewall_rules.xml b/openarmor-rules/rules.d/50-crs-firewall_rules.xml new file mode 100644 index 000000000..c398f25d1 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-firewall_rules.xml @@ -0,0 +1,48 @@ + + + + + + firewall + Firewall rules grouped. + + + + + 4100 + DROP + no_log + Firewall drop event. + firewall_drop, + + + + 4100 + Deny + no_log + Firewall drop event. + firewall_drop, + + + + 4101 + + Multiple Firewall drop events from same source. + multiple_drops, + + diff --git a/openarmor-rules/rules.d/50-crs-firewalld_rules.xml b/openarmor-rules/rules.d/50-crs-firewalld_rules.xml new file mode 100644 index 000000000..792752c64 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-firewalld_rules.xml @@ -0,0 +1,25 @@ + + + ^firewalld + firewalld grouping + + + + 40900 + ERROR: + firewalld error + + + + 40901 + No chain/target/match by that name\.$ + Incorrect chain/target/match. + + + + 40901 + ZONE_ALREADY_SET$ + firewalld: zone already set. + + + diff --git a/openarmor-rules/rules.d/50-crs-ftpd_rules.xml b/openarmor-rules/rules.d/50-crs-ftpd_rules.xml new file mode 100644 index 000000000..c7bb99134 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-ftpd_rules.xml @@ -0,0 +1,103 @@ + + + + + + ftpd + Grouping for the ftpd rules. + + + + 11100 + FTP LOGIN REFUSED + FTP connection refused. + authentication_failed,access_denied, + + + + 11100 + created + File created via FTP + + + + 11100 + deleted + File deleted via FTP + + + + 11100 + FTPD: IMPORT file + User uploaded a file to server. + + + + 11100 + FTPD: EXPORT file + User downloaded a file to server. + + + + 11100 + FTP LOGIN FROM|connection from|connect from + connection_attempt + Remote host connected to FTP server. + + + + 11100 + refused connect from + access_denied, + Connection blocked by Tcp Wrappers. + + + + 11100 + warning: can't verify hostname: |gethostbyaddr: + Reverse lookup error (bad ISP config). + client_misconfig, + + + + 11100 + repeated login failures + Multiple FTP failed login attempts. + authentication_failures, + + + + 11100 + timed out after + User disconnected due to time out. + + + + 11100 + PAM_ERROR_MSG: Account is disabled + Attempt to login with disabled account. + authentication_failed, + + + + 11100 + ^Failed authentication from + FTP authentication failure. + authentication_failed, + + + + 11100 + ^login \S+ from \S+ failed + FTP authentication failure. + authentication_failed, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-hordeimp_rules.xml b/openarmor-rules/rules.d/50-crs-hordeimp_rules.xml new file mode 100644 index 000000000..a4a43d35e --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-hordeimp_rules.xml @@ -0,0 +1,78 @@ + + + + + + horde_imp + Grouping for the Horde imp rules. + + + + 9300 + ^\[info\] + Horde IMP informational message. + + + + 9300 + ^\[notice\] + Horde IMP notice message. + + + + 9300 + ^\[error\] + Horde IMP error message. + + + + 9300 + ^\[emergency\] + Horde IMP emergency message. + service_availability, + + + + 9302 + Login success for + Horde IMP successful login. + authentication_success, + + + + 9303 + FAILED LOGIN + Horde IMP Failed login. + authentication_failed, + + + + 9306 + + Horde brute force (multiple failed logins). + authentication_failures, + + + + 9304 + Multiple Horde emergency messages. + service_availability, + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-ids_rules.xml b/openarmor-rules/rules.d/50-crs-ids_rules.xml new file mode 100644 index 000000000..8d6fb18cb --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-ids_rules.xml @@ -0,0 +1,104 @@ + + + +8 + + + + ids + + First time this IDS alert is generated. + fts, + + + + ids + srcip, id + IDS event. + + + + + 20100, 20101 + snort + + ^1:1852:|^1:368:|^1:384:|^1:366:|^1:402:|^1:408:|^1:1365:| + ^1:480:|^1:399:|^1:2925: + Ignored snort ids. + + + + + 20100, 20101 + dragon-nids + + ^EOL$|^SOF$|^HEARTBEAT$|^DYNAMIC-TCP$|^DYNAMIC-UDP$ + Ignored snort ids. + + + + 20101 + + id + Multiple IDS alerts for same id. + + + + 20101 + + srcip, id + Multiple IDS events from same source ip. + + + + + + 20151 + + + srcip, id + Multiple IDS events from same source ip + (ignoring now this srcip and id). + + + + 20152 + + id + Multiple IDS alerts for same id + (ignoring now this id). + + diff --git a/openarmor-rules/rules.d/50-crs-imapd_rules.xml b/openarmor-rules/rules.d/50-crs-imapd_rules.xml new file mode 100644 index 000000000..88c42e645 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-imapd_rules.xml @@ -0,0 +1,52 @@ + + + +6 + + + + imapd + Grouping of the imapd rules. + + + + 3600 + Login failed user=|AUTHENTICATE LOGIN failure + Imapd user login failed. + authentication_failed, + + + + 3600 + Authenticated user= + Imapd user login. + authentication_success, + + + + 3600 + Logout user= + Imapd user logout. + + + + 3601 + + Multiple failed logins from same source ip. + authentication_failures, + + + diff --git a/openarmor-rules/rules.d/50-crs-kesl_rules.xml b/openarmor-rules/rules.d/50-crs-kesl_rules.xml new file mode 100644 index 000000000..e2ec81760 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-kesl_rules.xml @@ -0,0 +1,122 @@ + + + + + kesl + kesl messages grouped + + + + 53801 + UpdateError + An error occurred during an Update Task. + + + + 53801 + AVBasesAreOutOfDate + AVBasesAreOutOfDate (kesl Task: update) + + + + 53801 + AVBasesAreTotallyOutOfDate + AVBasesAreTotallyOutOfDate (kesl Task: update) + + + + 53801 + TaskStateChanged + Started|Stopped + ^Rollback + An Update Rollback Task has been started / stopped + + + + 53801 + AVBasesRollbackError + An error occurred during AVBases Update Rollback Task + + + + 53801 + TaskStateChanged + Started|Stopped + ^Retranslate + An update distribution (Retranslate) Task has been started / stopped + + + + 53801 + RetranslationError + An error occurred during an update distribution (Retranslate) Task + + + + 53801 + TaskStateChanged + Started + A kesl Task has been started. + + + + 53801 + TaskStateChanged + Suspended + A kesl Task has been suspended. + + + + 53801 + TaskStateChanged + Stopped + ^Backup|^License|^OAS + A kesl Task has been stopped. + + + + 53801 + TaskStateChanged + Stopped + ^ODS|^BootScan|^MemoryScan|^Update + A kesl Task has been stopped. + + + + 53801 + ThreatDetected + Kesl detected a Threat (kesl Task: File_Monitoring) + + + + 53801 + ObjectSavedToBackup + Threat Object was saved to Backup (kesl Task: File_Monitoring) + + + + 53801 + ObjectNotDisinfected + Threat Object could not be disinfected (kesl Task: File_Monitoring) + + + + 53801 + ObjectDeleted + Threat Object was deleted (kesl Task: File_Monitoring) + + + + 53801 + ObjectProcessingError + An error occurred during kesl scan + + + diff --git a/openarmor-rules/rules.d/50-crs-lighttpd_rules.xml b/openarmor-rules/rules.d/50-crs-lighttpd_rules.xml new file mode 100644 index 000000000..5bbddb991 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-lighttpd_rules.xml @@ -0,0 +1,8 @@ + + + lighttpd + fastcgi + FastCGI error message. + + + diff --git a/openarmor-rules/rules.d/50-crs-linux_usbdetect_rules.xml b/openarmor-rules/rules.d/50-crs-linux_usbdetect_rules.xml new file mode 100644 index 000000000..933e16255 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-linux_usbdetect_rules.xml @@ -0,0 +1,43 @@ + + + + + + kernel + usb + Linux USB detection messages grouped + + + + + 53600 + New USB device found + A new USB device was found by the system + linux, + + + + + 53600 + new low-speed USB device + New Low-Speed USB Device was connected. + linux, + + + + + 53600 + new high-speed USB device + New High-Speed USB Device was connected + linux, + + + + + 53600 + USB disconnect + USB device was disconnected + linux, + + + diff --git a/openarmor-rules/rules.d/50-crs-mailscanner_rules.xml b/openarmor-rules/rules.d/50-crs-mailscanner_rules.xml new file mode 100644 index 000000000..3658b9548 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-mailscanner_rules.xml @@ -0,0 +1,51 @@ + + + + + + mailscanner + Grouping of mailscanner rules. + + + + 3700 + not + Non spam message. Ignored. + + + + 3700 + spam + Mail Scanner spam detected. + spam, + + + + 3702 + + Multiple attempts of spam. + multiple_spam, + + + + 1002 + update\.bad\.phishing\.sites + ^Phishing bad sites list updated + ignore + + + + diff --git a/openarmor-rules/rules.d/50-crs-mhn_cowrie_rules.xml b/openarmor-rules/rules.d/50-crs-mhn_cowrie_rules.xml new file mode 100644 index 000000000..7517dd9b0 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-mhn_cowrie_rules.xml @@ -0,0 +1,26 @@ + + + + + + + + + cowrie + SSH login attempted on cowrie honeypot + SSH login attempted on cowrie honeypot + + + + cowrie + SSH session on cowrie honeypot + SSH session established on cowrie honeypot + + + + cowrie + command attempted on cowrie honeypot + A command was attempted in SSH session on cowrie honeypot + + + diff --git a/openarmor-rules/rules.d/50-crs-mhn_dionaea_rules.xml b/openarmor-rules/rules.d/50-crs-mhn_dionaea_rules.xml new file mode 100644 index 000000000..78ac1d5ff --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-mhn_dionaea_rules.xml @@ -0,0 +1,13 @@ + + + + + + + + + dionaea + Connection to Dionaea Honeypot identified + + + diff --git a/openarmor-rules/rules.d/50-crs-ms-exchange_rules.xml b/openarmor-rules/rules.d/50-crs-ms-exchange_rules.xml new file mode 100644 index 000000000..19be4753d --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-ms-exchange_rules.xml @@ -0,0 +1,56 @@ + + + + + + + + + msexchange + Grouping of Exchange rules. + + + + 3800 + RCPT + ^550 + E-mail rcpt is not valid (invalid account). + spam, + + + + 3800 + ^5 + E-mail 500 error code. + spam, + + + + 3801 + + Multiple e-mail attempts to an invalid account. + multiple_spam, + + + + 3802 + + Multiple e-mail 500 error code (spam). + multiple_spam, + + + + diff --git a/openarmor-rules/rules.d/50-crs-ms_dhcp_rules.xml b/openarmor-rules/rules.d/50-crs-ms_dhcp_rules.xml new file mode 100644 index 000000000..6d9106759 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-ms_dhcp_rules.xml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + ms-dhcp-ipv4 + Grouping for the MS-DHCP rules. + + + + 6300 + ^00 + The log was started. + service_start, + + + + 6300 + ^01 + The log was stopped. + service_availability, + + + + 6300 + ^02 + The log was temporarily paused due to low disk space. + system_error, + + + + 6300 + ^10 + A new IP address was leased to a client. + dhcp_lease_action, + + + + 6300 + ^11 + A lease was renewed by a client. + dhcp_lease_action, + + + + 6300 + ^12 + A lease was released by a client. + dhcp_lease_action, + + + + 6300 + ^13 + An IP address was found to be in use on the network. + dhcp_lease_action, + + + + 6300 + ^14 + A lease request could not be satisfied because the scope's address pool was exhausted. + service_availability,dhcp_lease_action, + + + + 6300 + ^15 + A lease was denied. + dhcp_lease_action, + + + + 6300 + ^16 + A lease was deleted. + dhcp_lease_action, + + + + 6300 + ^17 + A lease was expired and DNS records for an expired leases have not been deleted. + dhcp_lease_action, + + + + 6300 + ^18 + A lease was expired and DNS records were deleted. + dhcp_lease_action,dhcp_dns_maintenance + + + + 6300 + ^20 + A BOOTP address was leased to a client. + dhcp_lease_action, + + + + 6300 + ^21 + A dynamic BOOTP address was leased to a client. + dhcp_lease_action, + + + + + 6300 + ^22 + A BOOTP request could not be satisfied because the scope's address pool for BOOTP was exhausted. + dhcp_lease_action, + + + + 6300 + ^23 + A BOOTP IP address was deleted after checking to see it was not in use. + dhcp_lease_action, + + + + 6300 + ^24 + IP address cleanup operation has began. + dhcp_maintenance, + + + + 6300 + ^25 + IP address cleanup statistics. + dhcp_maintenance, + + + + 6300 + ^30 + DNS update request to the named DNS server. + dhcp_dns_maintenance, + + + + 6300 + ^31 + DNS update failed. + dhcp_dns_maintenance, + + + + 6300 + ^32 + DNS update successful. + dhcp_dns_maintenance, + + + + 6300 + ^33 + Packet dropped due to NAP policy. + dhcp_lease_action, + + + + + 6300 + ^5 + Codes above 50 are used for Rogue Server Detection information. + dhcp_rogue_server, + + + + + + + + + ms-dhcp-ipv6 + Grouping for the MS-DHCP rules. + + + + 6350 + ^11000 + Solicit. + dhcp_ipv6, + + + + 6350 + ^11001|^11002 + Advertise. + dhcp_ipv6, + + + + 6350 + ^11003 + Confirm. + dhcp_ipv6, + + + + 6350 + ^11004 + Renew. + dhcp_ipv6, + + + + 6350 + ^11005 + Rebind. + dhcp_ipv6, + + + + + 6350 + ^11006 + DHCP Decline. + dhcp_ipv6, + + + + 6350 + ^11007 + Release. + dhcp_ipv6, + + + + 6350 + ^11008 + Information Request. + dhcp_ipv6, + + + + 6350 + ^11009 + Scope Full. + dhcp_ipv6, + + + + 6350 + ^11010 + Started. + service_start, + + + + 6350 + ^11011 + Stopped. + service_availability, + + + + 6350 + ^11012 + Audit log paused. + service_availability, + + + + + 6350 + ^11013 + DHCP Log File. + system_error, + + + + 6350 + ^11014 + Bad Address. + dhcp_ipv6, + + + + 6350 + ^11015 + Address is already in use. + dhcp_ipv6, + + + + 6350 + ^11016 + Client deleted. + dhcp_ipv6, + + + + 6350 + ^11017 + DNS record not deleted. + dhcp_ipv6, + + + + 6350 + ^11018 + Expired. + dhcp_ipv6, + + + + 6350 + ^11019 + Expired and Deleted count. + dhcp_ipv6, + + + + 6350 + ^11020 + Database cleanup begin. + dhcp_ipv6, + + + + + 6350 + ^11021 + Database cleanup end. + dhcp_ipv6, + + + + 6350 + ^11023 + Service not authorized in AD. + dhcp_ipv6, + + + + 6350 + ^11024 + Service authorized in AD. + dhcp_ipv6, + + + + 6350 + ^11025 + Service has not determined if it is authorized in AD. + dhcp_ipv6, + + + diff --git a/openarmor-rules/rules.d/50-crs-ms_ftpd_rules.xml b/openarmor-rules/rules.d/50-crs-ms_ftpd_rules.xml new file mode 100644 index 000000000..5ffd5062c --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-ms_ftpd_rules.xml @@ -0,0 +1,73 @@ + + + + + + msftp + Grouping for the Microsoft ftp rules. + + + + 11500 + USER + New FTP connection. + connection_attempt, + + + + 11500 + PASS + 530 + FTP Authentication failed. + authentication_failed, + + + + 11500 + PASS + 230 + FTP Authentication success. + authentication_success, + + + + 11500 + ^5 + FTP client request failed. + + + + 11502 + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11501 + + Multiple connection attempts from same source. + recon, + + + + 11504 + + Multiple FTP errors from same source. + + + + + diff --git a/openarmor-rules/rules.d/50-crs-msauth_rules.xml b/openarmor-rules/rules.d/50-crs-msauth_rules.xml new file mode 100644 index 000000000..0d66f1e77 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-msauth_rules.xml @@ -0,0 +1,969 @@ + + + +6 + + + + windows + Group of windows rules. + + + + 18100 + ^INFORMATION + Windows informational event. + + + + 18100 + ^WARNING + Windows warning event. + + + + 18100 + ^ERROR + Windows error event. + system_error, + + + + 18100 + ^AUDIT_SUCCESS|^success + Windows audit success event. + + + + 18100 + ^AUDIT_FAILURE|^failure + Windows audit failure event. + + + + 18105 + ^529$|^530$|^531$|^532$|^533$|^534$|^535$|^536$|^537$|^539$|^4625$ + Windows Logon Failure. + win_authentication_failed, + + + + 18104 + ^528$|^540$|^673$|^4624$|^4769$ + Windows Logon Success. + authentication_success, + + + + 18105 + ^577$|^4673$ + Failed attempt to perform a privileged + operation. + + + + 18104 + ^682$|^683$|^4778$|^4779$ + Session reconnected/disconnected to winstation. + + + + 18104 + ^624$|^626$|^4720$|^4722$ + User account enabled or created. + adduser,account_changed, + + + + 18104 + ^628$|^642$|^685$|^4738$|^4781$ + User account changed. + account_changed, + + + + 18104 + ^630$|^629$|^4725$|^4726$ + User account disabled or deleted. + adduser,account_changed, + + + + 18104 + ^612$|^643$|^4719$|^4907$|^4912$|^4719$ + Windows Audit Policy changed. + policy_changed, + + + + 18104 + ^632$|^4728$|^633$|^4729$|^636$|^4732$|^637$|^4733$|^639$|^4735$| + ^641$|^4737$|^637$|^4733$|^659$|^4755$|^660$|^4766$|^668$|^4764$| + ^649$|^4745$|^650$|^4746$|^651$|^4747$|^654$|^4750$|^655$|^4751$| + ^656$|^4752$|^659$|^4755$|^660$|^4756$|^661$|^4757$|^664$|^4760$| + ^665$|^4761$|^666$|^4762$ + Group Account Changed + group_changed,win_group_changed, + + + + 18104 + ^640$ + General account database changed. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=640 + adduser,account_changed, + + + + 18104 + ^644$|^4740$ + User account locked out (multiple login errors). + authentication_failures, + + + + 18104 + ^513$|^4609$ + Windows is shutting down. + system_shutdown, + + + + 18104 + ^517$|^1102$ + Windows audit log was cleared. + logs_cleared, + + + + 18107 + alert_by_email + + First time this user logged in this system. + authentication_success, + + + + 18105 + ^680$ + Windows login attempt (ignored). Duplicated. + + + + 18102, 18103 + ^20187$|^20014$|^20078$|^20050$|^20049$|^20189$ + Remote access login failure. + authentication_failed, + + + + 18101 + ^20158$ + Remote access login success. + authentication_success, + + + + 18104 + ^646$|^645$|^647$|^4741$|^4742$|^4743$ + Computer account added/changed/deleted. + account_changed, + + + + + ^65xxx + Group account added/changed/deleted. + This rule has been deprecated + account_changed, + + + + 18103 + ^13570$ + Windows file system full. + low_diskspace, + + + + + + 18106 + ^529$|^4625$ + Logon Failure - Unknown user or bad password. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=4625 + win_authentication_failed, + + + + 18106 + ^530$ + Logon Failure - Account logon time restriction + violation. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=530 + win_authentication_failed,login_denied, + + + + 18106 + ^531$ + Logon Failure - Account currently disabled. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=531 + win_authentication_failed,login_denied, + + + + 18106 + ^532$ + Logon Failure - Specified account expired. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=532 + win_authentication_failed,login_denied, + + + + 18106 + ^533$ + Logon Failure - User not allowed to login at + this computer. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=533 + win_authentication_failed,login_denied, + + + + 18106 + ^534$ + Logon Failure - User not granted logon type. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=534 + win_authentication_failed, + + + + 18106 + ^535$ + Logon Failure - Account's password expired. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=535 + win_authentication_failed, + + + + 18106 + ^536$|^537$ + Logon Failure - Internal error. + win_authentication_failed, + + + + 18106 + ^539$ + Logon Failure - Account locked out. + win_authentication_failed, + + + + 18105 + ^673$|^675$|^681$|^4769$ + Windows DC Logon Failure. + win_authentication_failed, + + + + 18104 + ^520$|^4616$ + System time changed. + time_changed, + + + + 18102 + ^1076$ + unexpected shutdown + system_error, system_shutdown, + Unexpected Windows shutdown. + + + + 18104 + ^671$|^4767$ + User account unlocked. + https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=4767 + account_changed, + + + + 18114 + ^631$|^635$|^658$ + Security enabled group created. + adduser,account_changed, + + + + 18114 + ^634$|^638$|^662$ + Security enabled group deleted. + adduser,account_changed, + + + + + 18101 + ^7040$ + policy_changed, + Service startup type was changed. + This does not appear to be logged on Windows 2000. + + + + 18101 + ^11724$ + alert_by_email + Application Uninstalled. + + + + 18101 + ^11707$ + alert_by_email + Application Installed. + + + + 18104 + ^4608$ + Windows is starting up. + + + + 18104 + ^538$|^551$|^4634$|^4647$ + Windows User Logoff. + + + + + + 18104 + ^631$|^4727$|^635$|^4731$|^658$|^4754$|^648$|^4744$|^653$|^4749$| + ^663$|^4759$ + Group Account Created + group_created,win_group_created, + + + + 18104 + ^634$|^4730$|^638$|^4734$|^662$|^4758$|^652$|^4748$|^657$|^4753$| + ^667$|^4763$ + Group Account Deleted + group_deleted,win_group_deleted, + + + + 18200 + ^631$|^4727$ + Security Enabled Global Group Created + group_created,win_group_created, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=631 + + + + 18114 + ^632$|^4728$ + Security Enabled Global Group Member Added + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=632 + + + + 18114 + ^633$|^4729$ + Security Enabled Global Group Member Removed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=633 + + + + 18201 + ^634$|^4730$ + Security Enabled Global Group Deleted + group_deleted,win_group_deleted, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=634 + + + + 18200 + ^635$|^4731$ + Security Enabled Local Group Created + group_created,win_group_created, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=635 + + + + 18114 + ^636$|^4732$ + Security Enabled Local Group Member Added + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=636 + + + + 18114 + ^637$|^4733$ + Security Enabled Local Group Member Removed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=637 + + + + 18201 + ^638$|^4734$ + Security Enabled Local Group Deleted + group_deleted,win_group_deleted, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=638 + + + + 18114 + ^639$|^4735$ + Security Enabled Local Group Changed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=639 + + + + 18114 + ^641$|^4737$ + Security Enabled Global Group Changed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=641 + + + + 18200 + ^658$|^4754$ + Security Enabled Universal Group Created + group_created,win_group_created, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=658 + + + + 18114 + ^659$|^4755$ + Security Enabled Universal Group Changed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=659 + + + + 18114 + ^660$|^4756$ + Security Enabled Universal Group Member Added + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=660 + + + + 18114 + ^661$|^4757$ + Security Enabled Universal Group Member Removed + group_changed,win_group_changed, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=661 + + + + 18201 + ^662$|^4758$ + Security Enabled Universal Group Deleted + group_deleted,win_group_deleted, + http://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=662 + + + + 18207,18208 + ID:[ ]+[()*+,.:;\<=>?\[\]!"'#%&$|{}-]*S-1-5-32-544 + Administrators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-1-0\}| ID:[ ]+S-1-1-0 + Everyone Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-9\}| ID:[ ]+S-1-5-9 + Enterprise Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-11\}| ID:[ ]+S-1-5-11 + Authenticated Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-13\}| ID:[ ]+S-1-5-13 + Terminal Server Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-512\}| ID:[ ]+S-1-5-21\S+-512 + Domain Admins Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-513\}| ID:[ ]+S-1-5-21\S+-513 + Domain Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18223,18203 + Target Account Name: None + Local User Group NONE + Bogus group user added to upon creation + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-514\}| ID:[ ]+S-1-5-21\S+-514 + Domain Guests Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-515\}| ID:[ ]+S-1-5-21\S+-515 + Domain Computers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-516\}| ID:[ ]+S-1-5-21\S+-516 + Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-21\S+-517\}| ID:[ ]+S-1-5-21\S+-517 + Cert Publishers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21.+-518\}| ID:[ ]+S-1-5-21.+-518 + Schema Admins Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-519\}| ID:[ ]+S-1-5-21\S+-519 + Enterprise Admins Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18203,18204 + ID:[ ]+%\{S-1-5-21\S+-520\}| ID:[ ]+S-1-5-21\S+-520 + Group Policy Creator Owners Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-21\S+-553\}| ID:[ ]+S-1-5-21\S+-553 + RAS and IAS Servers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-545\}| ID:[ ]+S-1-5-32-545 + Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-546\}| ID:[ ]+S-1-5-32-546 + Guests Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-547\}| ID:[ ]+S-1-5-32-547 + Power Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-548\}| ID:[ ]+S-1-5-32-548 + Account Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-549\}| ID:[ ]+S-1-5-32-549 + Server Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-550\}| ID:[ ]+S-1-5-32-550 + Print Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-551\}| ID:[ ]+S-1-5-32-551 + Backup Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-552\}| ID:[ ]+S-1-5-32-552 + Replicators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-554\}| ID:[ ]+S-1-5-32-554 + Pre-Windows 2000 Compatible Access Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-555\}| ID:[ ]+S-1-5-32-555 + Remote Desktop Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-556\}| ID:[ ]+S-1-5-32-556 + Network Configuration Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-557\}| ID:[ ]+S-1-5-32-557 + Incoming Forest Trust Builders Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-558\}| ID:[ ]+S-1-5-32-558 + Performance Monitor Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-559\}| ID:[ ]+S-1-5-32-559 + Performance Log Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-560\}| ID:[ ]+S-1-5-32-560 + Windows Authorization Access Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-561\}| ID:[ ]+S-1-5-32-561 + Terminal Server License Servers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-562\}| ID:[ ]+S-1-5-32-562 + Distributed COM Users Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-498\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-498 + Enterprise Read-only Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-529\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-529 + Read-only Domain Controllers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-569\}| ID:[ ]+S-1-5-32-569 + Cryptographic Operators Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-571\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-571 + Allowed RODC Password Replication Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-[ ]*21.+[ ]*-572\}| ID:[ ]+S-1-5-[ ]*21.+[ ]*-572 + Denied RODC Password Replication Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-573\}| ID:[ ]+S-1-5-32-573 + Event Log Readers Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18207,18208 + ID:[ ]+%\{S-1-5-32-574\}| ID:[ ]+S-1-5-32-574 + Certificate Service DCOM Access Group Changed + group_changed,win_group_changed, + http://support.microsoft.com/kb/243330 + + + + 18101 + ^200$|^300$|^302$ + TS Gateway login success. + authentication_success, + https://technet.microsoft.com/en-us/library/cc775181(v=ws.10).aspx + + + + 18102, 18103 + ^201$|^203$|^204$|^301$|^304$|^305$|^306$|^1001$ + TS Gateway login failure. + authentication_failed, + https://technet.microsoft.com/en-us/library/cc775181(v=ws.10).aspx + + + + 18101 + ^202$|^303$ + TS Gateway user disconnected. + https://technet.microsoft.com/en-us/library/cc775181(v=ws.10).aspx + + + + + 18107,18149 + ^528$|^538$|^540$|^4624$ + ^LOCAL SERVICE|^NETWORK SERVICE|^ANONYMOUS LOGON + Windows Logon Success (ignored). + + + + + + 18139 + Failure Code: 0x1F + Windows DC integrity check on decrypted + field failed. + + win_authentication_failed,attacks, + + + + 18139 + Failure Code: 0x22 + Windows DC - Possible replay attack. + + win_authentication_failed,attacks, + + + + 18139 + Failure Code: 0x25 + Windows DC - Clock skew too great. + + win_authentication_failed,attacks, + + + + + + 18105 + ^18456$ + win_authentication_failed, + MS SQL Server Logon Failure. + + + + 18104 + ^18454$|^18453$ + MS SQL Server Logon Success. + authentication_success, + + + + + 18107 + ^4624$ + Logon Type: 8 + MS Exchange Logon Success. + + + + 18149 + ^4634$ + Logon Type: 8 + User Logoff Exchange. + + + + + + 18108 + + Multiple failed attempts to perform a + privileged operation by the same user. + + + + win_authentication_failed + Multiple Windows Logon Failures. + authentication_failures, + + + + 18105 + Multiple Windows audit failure events. + + + + 18103 + Multiple Windows error events. + + + + 18102 + Multiple Windows warning events. + + + + 18125 + Multiple remote access login failures. + authentication_failures, + + + + 18258 + Multiple TS Gateway login failures. + authentication_failures, + + + + + 18103 + : chromoting: .* Access denied for client: + Chrome Remote Desktop attempt - access denied + + + + 18101 + : chromoting: .* Client connected: + Chrome Remote Desktop attempt - connected + + + + 18101 + : chromoting: .* Client disconnected: + Chrome Remote Desktop attempt - disconnected + + + + + diff --git a/openarmor-rules/rules.d/50-crs-mysql_rules.xml b/openarmor-rules/rules.d/50-crs-mysql_rules.xml new file mode 100644 index 000000000..c50df5f07 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-mysql_rules.xml @@ -0,0 +1,85 @@ + + + + + + + mysql_log + MySQL messages grouped. + + + + 50100 + ^MySQL log: \d+ \S+ \d+ Connect + Database authentication success. + authentication_success, + + + + 50105 + Access denied for user + Database authentication failure. + authentication_failed, + + + + 50100 + ^MySQL log: \d+ \S+ \d+ Query + Database query. + + + + 50100 + ^MySQL log: \d+ \S+ \d+ Quit + User disconnected from database. + + + + 50100 + mysqld ended|Shutdown complete + Database shutdown message. + service_availability, + + + + 50100 + mysqld started|mysqld restarted + Database startup message. + service_availability, + + + + 50100 + ^MySQL log: \d+ \S+ \d+ \[ERROR\] + Database error. + + + + 50125 + Fatal error: + Database fatal error. + service_availability, + + + + 50125 + Multiple database errors. + service_availability, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-named_rules.xml b/openarmor-rules/rules.d/50-crs-named_rules.xml new file mode 100644 index 000000000..654e75b75 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-named_rules.xml @@ -0,0 +1,325 @@ + + + + + + named + Grouping of the named rules + + + + 12100 + dropping source port zero packet from + Invalid DNS packet. Possibility of attack. + invalid_access, + + + + 12100 + denied AXFR from + Failed attempt to perform a zone transfer. + access_denied, + + + + 12100 + denied update from|unapproved update from + DNS update denied. + Generally mis-configuration. + http://seclists.org/incidents/2000/May/217 + client_misconfig, + + + + 12100 + unable to rename log file + Log permission misconfiguration in Named. + system_error, + + + + 12100 + unexpected RCODE + Unexpected error while resolving domain. + + + + 12100 + refused notify from non-master + DNS configuration error. + + + + 12100 + update \S+ denied + DNS update using RFC2136 Dynamic protocol. + + + + 12100 + query \(cache\) denied|: query \(cache\) + Query cache denied (probably config error). + http://www.reedmedia.net/misc/dns/errors.html + connection_attempt, + + + + 12100 + exiting \(due to fatal error\) + Named fatal error. DNS service going down. + service_availability, + + + + ^zone \S+ serial number \S+ received from master + \S+ \S ours (\S+) + Serial number from master is lower + than stored. + system_error, + + + + ^transfer of \S+ from \S+ failed while receiving \S+ REFUSED + Unable to perform zone transfer. + system_error, + + + + ^zone \S+: expired + Zone transfer error. + + + + 12100 + zone transfer deferred due to quota + Zone transfer deferred. + + + + 12100 + bad owner name \(check-names\) + Hostname contains characters that check-names does not like. + + + + 12100 + loaded serial|transferred serial + Zone transfer. + + + + 12100 + syntax error near| + reloading configuration failed: unexpected token + Syntax error in a named configuration file. + + + + + 12100 + refresh: retry limit for master \S+ exceeded + Zone transfer rety limit exceeded + + + + 12100 + already exists previous definition + Zone has been duplicated. + + + + 12100 + starting BIND + BIND has been started + + + + 12100 + has no address records + Missing A or AAAA record + + + + 12100 + zone \S+: \(master\) removed + Zone has been removed from a master server + + + + 12100 + loading from master file \S+ failed: not at top of zone$ + Origin of zone and owner name of SOA do not match. + + + + 12100 + already exists previous definition + Zone has been duplicated + + + + 12100 + reloading configuration failed: unexpected end of input + BIND Configuration error. + + + + 12100 + zone \S+: \(master\) removed + Zone has been removed from a master server + + + + 12100 + loading from master file \S+ failed: not at top of zone$ + Origin of zone and owner name of SOA do not match. + + + + 12100 + ^transfer of| + AXFR started$ + Zone transfer. + + + + 12128 + failed to connect: connection refused + Zone transfer failed, unable to connect to master. + + + + 12100 + IPv6 interfaces failed + Could not listen on IPv6 interface. + + + + 12100 + failed; interface ignored + Could not bind to an interface. + + + + 12128 + failed while receiving responses: not authoritative + Master is not authoritative for zone. + + + + 12100 + open: \S+: permission denied$ + Could not open configuration file, permission denied. + + + + 12100 + loading configuration: permission denied + Could not open configuration file, permission denied. + + + + 12100 + IN SOA -E + Domain in SOA -E. + + + + 12128 + failed to connect: host unreachable + Master appears to be down. + + + + 12100 + IN AXFR - + Domain is queried for a zone transferred. + + + + 12100 + IN A \+ + Domain A record found. + + + + 12100 + client \S+: bad zone transfer request: \S+: non-authoritative zone \(NOTAUTH\) + Bad zone transfer request. + + + + 12100 + refresh: failure trying master + Cannot refresh a domain from the master server. + + + + 12100 + SOA record not at top of zone + Origin of zone and owner name of SOA do not match. + + + + 12100 + command channel listening on + named command channel is listening. + + + + 12100 + automatic empty zone + named has created an automatic empty zone. + + + + 12100 + reloading configuration failed: out of memory + Server does not have enough memory to reload the configuration. + + + + 12100 + zone transfer \S+ denied + zone transfer denied + + + + 12100 + error sending response: host unreachable$ + Cannot send a DNS response. + + + + 12100 + update forwarding .+ denied$ + Cannot update forwarding domain. + + + + 12100 + : parsing failed$ + Parsing of a configuration file has failed. + + + + 12108 + + Multiple query (cache) failures. + connection_attempt, + + + diff --git a/openarmor-rules/rules.d/50-crs-netscreenfw_rules.xml b/openarmor-rules/rules.d/50-crs-netscreenfw_rules.xml new file mode 100644 index 000000000..239697205 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-netscreenfw_rules.xml @@ -0,0 +1,123 @@ + + + + + + netscreenfw + Grouping for the Netscreen Firewall rules + + + + 4500 + notification + Netscreen notification message. + + + + 4500 + warning + Netscreen warning message. + + + + 4500 + critical + Netscreen critical/alert message. + + + + 4500 + alert + Netscreen critical/alert message. + + + + 4500 + information + Netscreen informational message. + + + + + 4503 + ^00027 + Netscreen Erase sequence started. + service_availability, + + + + 4501 + ^00002 + Successfull admin login to the Netscreen firewall + authentication_success, + + + + 4502 + ^00515 + Successfull admin login to the Netscreen firewall + authentication_success, + + + + 4501 + ^00018 + Firewall policy changed. + config_changed, + + + + 4504 + ^00767 + Firewall configuration changed. + config_changed, + + + + 4503 + + Multiple Netscreen critical messages from + same source IP. + + + + 4503 + Multiple Netscreen critical messages. + + + + 4513 + + Multiple Netscreen alert messages from + same source IP. + + + + 4513 + Multiple Netscreen alert messages. + + + + 4500 + SYN flood! + netscreen detected a SYN flood. + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-nginx_rules.xml b/openarmor-rules/rules.d/50-crs-nginx_rules.xml new file mode 100644 index 000000000..0a7b311c8 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-nginx_rules.xml @@ -0,0 +1,88 @@ + + + + + + nginx-errorlog + Nginx messages grouped. + + + + 31300 + ^\S+ \S+ \[error\] + Nginx error message. + + + + 31300 + ^\S+ \S+ \[warn\] + Nginx warning message. + + + + 31300 + ^\S+ \S+ \[crit\] + Nginx critical message. + + + + 31301 + failed \(2: No such file or directory\)|is not found \(2: No such file or directory\) + Server returned 404 (reported in the access.log). + + + + 31301 + accept\(\) failed \(53: Software caused connection abort\) + Incomplete client request. + + + + 31301 + no user/password was provided for basic authentication + Initial 401 authentication request. + + + + 31301 + password mismatch, client| was not found in + Web authentication failed. + authentication_failed, + + + + 31315 + + Multiple web authentication failures. + authentication_failures, + + + + 31303 + failed \(2: No such file or directory + Common cache error when files were removed. + + + + 31301 + failed \(36: File name too long\) + Invalid URI, file name too long. + invalid_request, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-openarmor_rules.xml b/openarmor-rules/rules.d/50-crs-openarmor_rules.xml new file mode 100644 index 000000000..162da22d1 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-openarmor_rules.xml @@ -0,0 +1,359 @@ + + + + + + + openarmor + openarmor + Grouping of openarmor rules. + + + + 500 + + alert_by_email + Agent started + New openarmor agent connected. + + + + 500 + alert_by_email + openarmor started + openarmor server started. + + + + 500 + alert_by_email + Agent started + openarmor agent started. + + + + 500 + alert_by_email + Agent disconnected + openarmor agent disconnected. + + + + openarmor + rootcheck + Rootcheck event. + rootcheck, + + + + 509 + Host-based anomaly detection event (rootcheck). + rootcheck, + + + + + 510 + ^NTFS Alternate data stream found.*(?:Thumbs\.db:encryptable'\.|:Zone\.Identifier'\.|Exchsrvr/Mailroot/vsi) + Ignored common NTFS ADS entries. + rootcheck, + + + + 510 + ^Windows Audit + Windows Audit event. + rootcheck, + + + + 510 + ^Windows Malware + Windows malware detected. + rootcheck, + + + + 510 + ^Application Found + Windows application monitor event. + rootcheck, + + + + 510 + ^Starting rootcheck scan|^Ending rootcheck scan\.| + ^Starting syscheck scan|^Ending syscheck scan\. + Ignoring rootcheck/syscheck scan messages. + rootcheck,syscheck + + + + 510 + ^System Audit + System Audit event. + rootcheck, + + + + 514 + Adware|Spyware + Windows Adware/Spyware application found. + rootcheck, + + + + 516 + ^System Audit: Web vulnerability + System Audit: Vulnerable web application found. + rootcheck, + + + + + 500 + ^openarmor: output: + openarmor process monitoring rules. + process_monitor, + + + + 530 + openarmor: output: 'df -P': /dev/.*100% + Partition usage reached 100% (disk space monitor). + low_diskspace, + + + + 531 + cdrom|/media|usb|/mount|floppy|dvd + Ignoring external medias. + + + + 530 + openarmor: output: 'netstat -tan + + Listened ports status (netstat) changed (new port opened or closed). + + + + 530 + openarmor: output: 'w' + + no_log + List of logged in users. It will not be alerted by default. + + + + 530 + openarmor: output: 'last -n + + no_log + List of the last logged in users. + + + + openarmor + syscheck_integrity_changed + Integrity checksum changed. + syscheck, + + + + openarmor + syscheck_integrity_changed_2nd + Integrity checksum changed again (2nd time). + syscheck, + + + + openarmor + syscheck_integrity_changed_3rd + Integrity checksum changed again (3rd time). + syscheck, + + + + openarmor + syscheck_deleted + File deleted. Unable to retrieve checksum. + syscheck, + + + + openarmor + syscheck_new_entry + File added to the system. + syscheck, + + + + 500 + ^openarmor: agentless: + Integrity checksum for agentless device changed. + syscheck,agentless + + + + + openarmor + hostinfo_modified + Host information changed. + hostinfo, + + + + openarmor + hostinfo_new + Host information added. + hostinfo, + + + + + + 500 + ^openarmor: File rotated + Log file rotated. + + + + 500 + ^openarmor: File size reduced + Log file size reduced. + attacks, + + + + 500 + ^openarmor: Event log cleared + Microsoft Event log cleared. + logs_cleared, + + + + openarmor + 550 + syscheck-registry + syscheck, + Registry Integrity Checksum Changed + + + + openarmor + 551 + syscheck-registry + syscheck, + Registry Integrity Checksum Changed Again (2nd time) + + + + openarmor + 552 + syscheck-registry + syscheck, + Registry Integrity Checksum Changed Again (3rd time) + + + + openarmor + 553 + syscheck-registry + syscheck, + Registry Entry Deleted. Unable to Retrieve Checksum + + + + openarmor + 554 + syscheck-registry + syscheck, + Registry Entry Added to the System + + + + + + ar_log + Active Response Messages Grouped + active_response, + + + + 600 + firewall-drop.sh + add + Host Blocked by firewall-drop.sh Active Response + active_response, + + + + 600 + firewall-drop.sh + delete + Host Unblocked by firewall-drop.sh Active Response + active_response, + + + + 600 + host-deny.sh + add + Host Blocked by host-deny.sh Active Response + active_response, + + + + 600 + host-deny.sh + delete + Host Unblocked by host-deny.sh Active Response + active_response, + + + + 600 + route-null.sh + add + Host Blocked by route-null.sh Active Response + active_response, + + + + 600 + route-null.sh + delete + Host Unblocked by route-null.sh Active Response + active_response, + + + + openarmor + openarmor-logcollector + Logcollector Messages Grouped + + + + 700 + INFO: + Ignore informational messages (usually at startup) + + + diff --git a/openarmor-rules/rules.d/50-crs-openbsd_rules.xml b/openarmor-rules/rules.d/50-crs-openbsd_rules.xml new file mode 100644 index 000000000..c84f6938c --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-openbsd_rules.xml @@ -0,0 +1,310 @@ + + + + + + + + + + bsd_kernel + Grouping of bsd_kernel alerts + + + + 51500 + ichiic0: abort failed, status 0x40 + A timeout occurred waiting for a transfer. + + + + 51500 + Check Condition \(error 0x70\) on opcode 0x0 + Check media in optical drive. + + + + 51500 + BBB bulk-in clear stall failed + A disk has timed out. + + + + 51500 + arp info overwritten for + arp info has been overwritten for a host + + + + 51500 + was not properly unmounted + A filesystem was not properly unmounted, likely system crash + + + + 51500 + UKC> quit + UKC was used, possibly modifying a kernel at boot time. + + + + 51500 + Michael MIC failure + Michael MIC failure: Checksum failure in the tkip protocol. + + + + 51500 + soft error \(corrected\) + A soft error has been corrected on a hard drive, + this is a possible early sign of failure. + + + + 51500 + acpithinkpad\d: unknown event + Unknown acpithinkpad event + + + + 51500 + Critical temperature, shutting down + System shutdown due to temperature + + + + 51500 + _AL0\[0\] _PR0 failed + Unknown ACPI event (bug 6299 in OpenBSD bug tracking system). + + + + 51500 + ehci_freex: xfer=0xffff8000003ef800 not busy, 0x4f4e5155 + USB diagnostic message. + + + + 51500 + ichiic0: abort failed, status 0x0 + Possible APM or ACPI event. + + + + 51500 + Filesystem is not clean - run fsck + Unclean filesystem, run fsck. + + + + 51500 + atascsi_passthru_done, timeout + Timeout in atascsi_passthru_done. + + + + 51500 + RTC BIOS diagnostic error 80\ + Clock battery error 80 + + + + 51500 + i/o error on block + I/O error on a storage device + + + + 51500 + kbc: cmd word write error + kbc error. + + + + 51500 + BBB reset failed, IOERROR + USB reset failed, IOERROR. + + + + groupdel + Grouping for groupdel rules. + groupdel, + + + + 51521 + group deleted + Group deleted. + groupdel, + + + + savecore + no core dump + No core dumps. + + + + reboot + rebooted by + System was rebooted. + + + + ^ftp-proxy + proxy cannot connect to server + ftp-proxy cannot connect to a server. + + + + bsd_kernel + uncorrectable data error reading fsbn + Hard drive is dying. + + + + bsd_kernel + ^carp + state transition + MASTER -> BACKUP + CARP master to backup. + + + + bsd_kernel + duplicate IP6 address + Duplicate IPv6 address. + + + + bsd_kernel + failed loadfirmware of file + Could not load a firmware. + + + + ^hotplugd + Permission denied$ + hotplugd could not open a file. + + + + open-userdel + user removed: name= + User account deleted. + account_changed, + + + + ntpd + bad peer from + Bad ntp peer. + + + + ^dhclient$ + 1002 + receive_packet failed on + dhclient receive_packet failed. + + + + 51533 + Input/output error$ + dhclient receive_packet failed due to I/O error. + + + + ^dhclient$ + 1002 + SIOCDIFADDR failed + SIOCDIFADDR failed + + + + 51535 + Device not configured$ + dhclient: device not configured. + + + + + + + + doas + doas grouping + + + + 51550 + cannot stat + doas cannot stat a file. + + + + 51551 + : Permission denied$ + doas cannot stat a file due to permissions. + + + + 51550 + path not secure$ + A critical path for doas does not have secure permissions. + + + + 51550 + failed command for + Failed doas command. + + + + 51550 + ran command + A command was run using doas. + + + + 51555 + as root + A doas command was run as root. + + + + 51550 + failed auth for + doas authentication failed. + + + + sendsyslog + ^dropped + sendsyslog dropped log messages. + + + + ntpd + Connection refused$ + ntpd peer connection refused. + + + + ntpd + recvmsg + ntpd peer connection refused. + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-opensmtpd_rules.xml b/openarmor-rules/rules.d/50-crs-opensmtpd_rules.xml new file mode 100644 index 000000000..bc0134c7d --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-opensmtpd_rules.xml @@ -0,0 +1,68 @@ + + + + + + smtpd + OpenSMTPd grouping. + + + + smtpd + 53500 + Failed + Message failed. + + + + smtpd + 53500 + New session + New session created. + + + + smtpd + 53500 + Closing session + Session closed. + + + + smtpd + 53500 + Accepted + Message accepted. + + + + smtpd + 53500 + delivery: Ok + Email delivered. + + + + 53501 + Command not supported$ + SMTP command not supported. + + + + smtpd + 53500 + IO error: No SSL error$ + OpenSMTPd: no SSL + + + + smtpd + 53500 + Server certificate verification failed + Server TLS certificate verification failed. + + + diff --git a/openarmor-rules/rules.d/50-crs-pam_rules.xml b/openarmor-rules/rules.d/50-crs-pam_rules.xml new file mode 100644 index 000000000..2ab982e83 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-pam_rules.xml @@ -0,0 +1,117 @@ + + + + + + pam + Grouping of the pam_unix rules. + + + + 5500 + session opened for user + Login session opened. + authentication_success, + + + + 5500 + session closed for user + Login session closed. + + + + 5500 + authentication failure; logname= + User login failed. + authentication_failed, + + + + 5500 + check pass; user unknown|error retrieving information about user + Attempt to login with an invalid user. + invalid_login + + + + + 5501 + ^CRON$ + ^pam_unix\(cron:session\): session opened for user + Ignoring Annoying Ubuntu/debian cron login events. + + + + 5502 + ^CRON$ + ^pam_unix\(cron:session\): session closed for user + Ignoring Annoying Ubuntu/debian cron login events. + + + + 5504 + ^pam_unix\S+: check pass; user unknown$ + Ignoring events with a user or a password. + + + + 5503 + + Multiple failed logins in a small period of time. + authentication_failures, + + + + 5500 + gdm:auth\): conversation failed + PAM and gdm are not playing nicely. + + + + login + cannot open shared object file: No such file or directory + PAM misconfiguration. + + + + login + illegal module type: + PAM misconfiguration. + + + + : password changed for + User changed password. + + + + unix_chkpwd + unix_chkpwd grouping. + + + + 5556 + password check failed + Password check failed. + authentication_failure + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-php_rules.xml b/openarmor-rules/rules.d/50-crs-php_rules.xml new file mode 100644 index 000000000..08ed5834c --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-php_rules.xml @@ -0,0 +1,111 @@ + + + + + + 31301, 30101 + PHP Warning: + PHP Warning message. + + + + 31301, 30101 + PHP Fatal error: + PHP Fatal error. + + + + 31301, 30101 + PHP Parse error: + PHP Parse error. + + + + ^PHP Warning: + PHP Warning message. + + + + ^PHP Fatal error: + PHP Fatal error. + + + + ^PHP Parse error: + PHP Parse error. + + + + + + 31401, 31404 + PHP Warning message. + + + + 31410 + expects parameter 1 to be string, array given in + attack, + PHP web attack. + + + + 31410 + Failed opening|failed to open stream + PHP internal error (missing file). + alert_by_email + + + + 31410 + bytes written, possibly out of free disk space in + PHP internal error (server out of space). + alert_by_email + low_diskspace, + + + + + + 31402, 31405 + PHP Fatal error. + + + + 31420 + Failed opening required |Call to undefined function + PHP internal error (missing file or function). + alert_by_email + + + + + + + 31403, 31406 + PHP Parse error. + alert_by_email + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-pix_rules.xml b/openarmor-rules/rules.d/50-crs-pix_rules.xml new file mode 100644 index 000000000..53ce8fabf --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-pix_rules.xml @@ -0,0 +1,237 @@ + + + + + + + + + pix + Grouping of PIX rules + + + + 4300 + ^1- + PIX alert message. + + + + 4300 + ^2- + PIX critical message. + + + + 4300 + ^3- + PIX error message. + + + + 4300 + ^4- + PIX warning message. + + + + 4300 + ^5-|^6- + PIX notification/informational message. + + + + 4300 + ^7- + PIX debug message. + + + + 4314 + ^6-605004 + Failed login attempt at the PIX firewall. + authentication_failed, + + + + 4314 + ^5-502103 + Privilege changed in the PIX firewall. + + + + 4314 + ^6-605005 + Successful login to the PIX firewall. + authentication_success, + + + + 4314 + ^6-308001 + Password mismatch while running 'enable' + on the PIX. + authentication_failed, + + + + 4313 + ^4-405001 + ARP collision detected by the PIX. + + + + 4313 + ^4-401004 + Attempt to connect from a blocked (shunned) IP. + access_denied, + + + + 4313 + ^4-710004 + Connection limit exceeded. + + + + 4310 + ^1-106021|^1-106022 + Attack in progress detected by the PIX. + + + + 4311 + ^2-106012|^2-106017|^2-106020 + Attack in progress detected by the PIX. + + + + 4313 + ^4-4000 + Attack in progress detected by the PIX. + + + + + 4330, 4331, 4332 + Attack in progress detected by the PIX. + ids, + + + + 4314 + ^6-113005 + AAA (VPN) authentication failed. + authentication_failed, + + + + 4314 + ^6-113004 + AAA (VPN) authentication successful. + authentication_success, + + + + 4314 + ^6-113006 + AAA (VPN) user locked out. + authentication_failed, + + + + 4312 + ^3-201008 + The PIX is disallowing new connections. + service_availability, + + + + 4310 + ^1-105005|^1-105009|^1-105043 + Failed|Lost Failover + Firewall failover pair communication problem. + service_availability, + + + + 4314 + ^5-111003 + Firewall configuration deleted. + config_changed, + + + + 4314 + ^5-111005|^5-111004|^5-111002|^5-111007 + Firewall configuration changed. + config_changed, + + + + 4314 + ^5-111008|^7-111009 + Firewall command executed (for accounting only). + + + + 4314 + ^5-502101|^5-502102 + User created or modified on the Firewall. + adduser,account_changed, + + + + 4310 + Multiple PIX alert messages. + + + + 4311 + Multiple PIX critical messages. + + + + 4312 + Multiple PIX error messages. + system_error, + + + + 4313 + Multiple PIX warning messages. + + + + 4333 + + Multiple attack in progress messages. + + + + 4334 + Multiple AAA (VPN) authentication failures. + authentication_failures, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-postfix_rules.xml b/openarmor-rules/rules.d/50-crs-postfix_rules.xml new file mode 100644 index 000000000..49c47809e --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-postfix_rules.xml @@ -0,0 +1,162 @@ + + +6 + + + + postfix-reject + Grouping of the postfix reject rules. + + + + 3300 + ^554$ + Attempt to use mail server as relay + (client host rejected). + spam, + + + + 3300 + ^550$ + Rejected by access list + (Requested action not taken). + spam, + + + + 3300 + ^450$ + Sender domain is not found + (450: Requested mail action not taken). + spam, + + + + 3300 + ^503$ + Improper use of SMTP command pipelining + (503: Bad sequence of commands). + spam, + + + + 3300 + ^504$ + Recipient address must contain FQDN + (504: Command parameter not implemented). + spam, + + + + 3301, 3302 + blocked using + IP Address deny-listed by anti-spam (blocked). + spam, + + + + postfix + Grouping of the postfix rules. + + + + 3320 + defer service failure|Resource temporarily unavailable| + ^fatal: the Postfix mail system is not running + Postfix process error. + service_availability, + + + + 3320 + authentication failed + Postfix SASL authentication failure. + authentication_failed, + + + + 3300 + ^452 + Postfix insufficient disk space error. + service_availability, + + + + 3320 + ^daemon started + Postfix started. + + + + 3320 + ^terminating on signal + Postfix stopped. + service_availability, + + + + 3301 + + Multiple relaying attempts of spam. + multiple_spam, + + + + 3302 + + Multiple attempts to send e-mail from a + rejected sender IP (access). + multiple_spam, + + + + 3303 + + Multiple attempts to send e-mail from + invalid/unknown sender domain. + multiple_spam, + + + + 3304 + + Multiple misuse of SMTP service + (bad sequence of commands). + multiple_spam, + + + + 3305 + + Multiple attempts to send e-mail to + invalid recipient or from unknown sender domain. + multiple_spam, + + + + 3306 + + Multiple attempts to send e-mail from + deny-listed IP address (blocked). + multiple_spam, + + + + 3332 + + Multiple SASL authentication failures. + authentication_failures, + + + + ^clamsmtpd: + Grouping of the clamsmtpd rules. + + diff --git a/openarmor-rules/rules.d/50-crs-postgresql_rules.xml b/openarmor-rules/rules.d/50-crs-postgresql_rules.xml new file mode 100644 index 000000000..5b3f82c6c --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-postgresql_rules.xml @@ -0,0 +1,102 @@ + + + + + + + postgresql_log + PostgreSQL messages grouped. + + + + 50500 + ^LOG + PostgreSQL log message. + + + + 50500 + ^NOTICE|INFO + PostgreSQL informational message. + + + + 50500 + ^ERROR + PostgreSQL error message. + + + + 50500 + ^FATAL + PostgreSQL error message. + + + + 50500 + ^DEBUG + PostgreSQL debug message. + + + + 50501 + duration: | statement: + Database query. + + + + 50501 + connection authorized + Database authentication success. + authentication_success, + + + + 50504 + authentication failed + Database authentication failure. + authentication_failed, + + + + 50504 + terminating connection due + Database shutdown message. + service_availability, + + + + 50501 + aborting any active transactions|shutting down + Database shutdown message. + service_availability, + + + + 50504 + Multiple database errors. + service_availability, + + + + 50503 + Multiple database errors. + service_availability, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-proftpd_rules.xml b/openarmor-rules/rules.d/50-crs-proftpd_rules.xml new file mode 100644 index 000000000..f56caf58c --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-proftpd_rules.xml @@ -0,0 +1,195 @@ + + + + + + + proftpd + Grouping for the proftpd rules. + + + + 11200 + FTP session opened\.$ + FTP session opened. + connection_attempt, + + + + 11200 + FTP session closed\.$ + FTP session closed. + + + + 11200 + no such user + Attempt to login using a non-existent user. + invalid_login, + + + + 11200 + Incorrect password\.$|Login failed + Login failed accessing the FTP server + authentication_failed, + + + + 11200 + Login successful + FTP Authentication success. + authentication_success, + + + + 11200 + Connection from \S+ \[\S+\] denied + Connection denied by ProFTPD configuration. + access_denied, + + + + 11200 + refused connect from + Connection refused by TCP Wrappers. + access_denied, + + + + 11200 + unable to find open port in PassivePorts range + Small PassivePorts range in config file. + Server misconfiguration. + + + + 11200 + Refused PORT + Attempt to bypass firewall that can't adequately + keep state of FTP traffic. + http://www.kb.cert.org/vuls/id/328867 + US-Cert Note VU#328867: Multiple vendors' firewalls do not adequately keep state of FTP traffic + + + + 11200 + Maximum login attempts + Multiple failed login attempts. + authentication_failures, + + + + 11200 + host name/name mismatch|host name/address mismatch + Mismatch in server's hostname. + + + + 11200 + warning: can't verify hostname: + Reverse lookup error (bad ISP config). + + + + 11200 + connect from + Remote host connected to FTP server. + connection_attempt, + + + + 11200 + FTP no transfer timeout, disconnected + Remote host disconnected due to inactivity. + + + + 11200 + FTP login timed out, disconnected + Remote host disconnected due to login time out. + + + + 11200 + FTP session idle timeout, disconnected + Remote host disconnected due to time out. + + + + 11200 + Data transfer stall timeout: + Data transfer stalled. + + + + 11200 + ProFTPD terminating \(signal 11\) + FTP process crashed. + service_availability, + + + + 11200 + Reallocating sreaddir buffer + FTP server Buffer overflow attempt. + + + + 11200 + listen\(\) failed in + Unable to bind to adress. + + + + 11200 + error setting IPV6_V6ONLY: Protocol not available| + - mod_delay/|PAM\(setcred\): System error| + PAM\(close_session\): System error|cap_set_proc failed|reverting to normal operation|error retrieving information about user + IPv6 error and mod-delay info (ignored). + + + + 11200 + unable to open incoming connection + Couldn't open the incoming connection. + Check log message for reason. + + + + 11204 + + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11201 + + Multiple connection attempts from same source. + recon, + + + + 11215 + + Multiple timed out logins from same source. + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-pure-ftpd_rules.xml b/openarmor-rules/rules.d/50-crs-pure-ftpd_rules.xml new file mode 100644 index 000000000..8579e7d81 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-pure-ftpd_rules.xml @@ -0,0 +1,91 @@ + + + + + + pure-ftpd + Grouping for the pure-ftpd rules. + + + + 11300 + \[INFO\] New connection from + New FTP connection. + connection_attempt, + + + + 11300 + \[WARNING\] Authentication failed for user + FTP Authentication failed. + authentication_failed, + + + + 11300 + \[INFO\] Logout| \[INFO\] Timeout + FTP user logout/timeout + + + + 11300 + \[NOTICE\] + FTP notice messages + + + + 11300 + \[INFO\] Can't change directory to + Attempt to access invalid directory + + + + 11302 + + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11301 + + Multiple connection attempts from same source. + recon, + + + + 11300 + is now logged in + FTP Authentication success. + authentication_success, + + + + pure-transfer + Rule grouping for pure ftpd transfers. + + + + 11310 + PUT + File added to ftpd. + + + + 11310 + GET + File retrieved from ftpd. + + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-racoon_rules.xml b/openarmor-rules/rules.d/50-crs-racoon_rules.xml new file mode 100644 index 000000000..a045baff6 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-racoon_rules.xml @@ -0,0 +1,71 @@ + + + + + + + + racoon + Grouping of racoon rules. + + + + racoon-failed + VPN authentication failed. + authentication_failed, + + + + 14100 + INFO + Racoon informational message. + + + + 14100 + ERROR + Racoon error message. + + + + 14100 + WARNING + Racoon warning message. + + + + 14110 + ISAKMP-SA established + authentication_success + VPN established. + + + + 14111 + such policy does not already exist + Roadwarrior configuration (ignored error). + + + + 14112 + ignore INITIAL-CONTACT notification + Roadwarrior configuration (ignored warning). + + + + 14111 + ERROR: invalid attribute|ERROR: rejected + Invalid configuration settings (ignored error). + + + + 14101 + + Multiple failed VPN logins. + + diff --git a/openarmor-rules/rules.d/50-crs-roundcube_rules.xml b/openarmor-rules/rules.d/50-crs-roundcube_rules.xml new file mode 100644 index 000000000..45d00645f --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-roundcube_rules.xml @@ -0,0 +1,44 @@ + + + + + roundcube + Roundcube messages grouped. + + + + 9400 + failed \(LOGIN\)| Login failed | Authentication failed| Failed login + Roundcube authentication failed. + authentication_failed, + + + + 9400 + Successful login + Roundcube authentication succeeded. + authentication_success, + + + + 9401 + + Roundcube brute force (multiple failed logins). + authentication_failures, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-sendmail_rules.xml b/openarmor-rules/rules.d/50-crs-sendmail_rules.xml new file mode 100644 index 000000000..8e8bb77ff --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-sendmail_rules.xml @@ -0,0 +1,150 @@ + + + + + + sendmail-reject + Grouping of the sendmail rules. + + + + 3100 + reject= + Grouping of the sendmail reject rules. + + + + 3101 + reject=451 4\.1\.8 + Sender domain does not have any valid + MX record (Requested action aborted). + spam, + + + + 3101 + reject=550 5\.0\.0 |reject=553 5\.3\.0 + Rejected by access list + (55x: Requested action not taken). + spam, + + + + 3101 + reject=550 5\.7\.1 + Attempt to use mail server as relay + (550: Requested action not taken). + spam, + + + + 3101 + reject=553 5\.1\.8 + Sender domain is not found + (553: Requested action not taken). + spam, + + + + 3101 + reject=553 5\.5\.4 + Sender address does not have domain + (553: Requested action not taken). + spam, + + + + 3101 + Sendmail rejected message. + + + + 3100 + rejecting commands from + Sendmail rejected due to pre-greeting. + spam, + + + + 3100 + savemail panic + Sendmail save mail panic. + system_error, + + + + 3102 + + Sender domain has bogus MX record. + It should not be sending e-mail. + multiple_spam, + + + + 3103 + + Multiple attempts to send e-mail from a + previously rejected sender (access). + multiple_spam, + + + + 3104 + + Multiple relaying attempts of spam. + multiple_spam, + + + + 3105 + + Multiple attempts to send e-mail + from invalid/unknown sender domain. + multiple_spam, + + + + 3106 + + Multiple attempts to send e-mail from + invalid/unknown sender. + multiple_spam, + + + + 3107 + + Multiple rejected e-mails from same source ip. + multiple_spam, + + + + 3108 + + Multiple pre-greetings rejects. + multiple_spam, + + + + + + smf-sav-reject + Grouping of the smf-sav sendmail milter rules. + smf-sav, + + + + 3190 + ^sender check failed|^sender check tempfailed + SMF-SAV sendmail milter unable to verify + address (REJECTED). + smf-sav,spam, + + + diff --git a/openarmor-rules/rules.d/50-crs-smbd_rules.xml b/openarmor-rules/rules.d/50-crs-smbd_rules.xml new file mode 100644 index 000000000..28b1b4b59 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-smbd_rules.xml @@ -0,0 +1,97 @@ + + + + + + + smbd + Grouping for the smbd rules. + + + + 13100 + getpeername failed\. Error was Transport endpoint + Samba network problems. + + + + 13100 + Denied connection from|Connection denied from + Samba connection denied. + access_denied, + + + + 13100 + Connection reset by peer + Samba network problems. + + + + 13100 + Permission denied-- + User action denied by configuration. + access_denied, + + + + 13100 + Unable to connect to CUPS server + Samba network problems (unable to connect). + + + + nmbd + + + + 13100 + smbd is already running + An attempt has been made to start smbd but the process is already running. + + + + 13106 + nmbd is already running + An attempt has been made to start nmbd but the process is already running. + + + + 13100 + Connection denied from + Connection was denied. + + + + 13100 + Socket is not connected + Socket is not connected, write failed. + + + + iptables + gvfsd-smb.* segfault at \S+ ip \S+ sp \S+ error \d+ in + Segfault in gvfs-smb. + + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-solaris_bsm_rules.xml b/openarmor-rules/rules.d/50-crs-solaris_bsm_rules.xml new file mode 100644 index 000000000..c08f41f28 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-solaris_bsm_rules.xml @@ -0,0 +1,65 @@ + + + + + + + solaris_bsm + Solaris BSM Auditing messages grouped. + + + + 6100 + ^failed + Auditing session failed. + + + + 6100 + ^ok + Auditing session succeeded. + + + + 6102 + ^login + Login session succeeded. + authentication_success, + + + + 6101 + ^login + Login session failed. + authentication_failed, + + + + 6102 + ^su + User successfully changed UID. + authentication_success, + + + + 6103 + ^su + User failed to change UID (user id). + authentication_failed, + + + + diff --git a/openarmor-rules/rules.d/50-crs-sonicwall_rules.xml b/openarmor-rules/rules.d/50-crs-sonicwall_rules.xml new file mode 100644 index 000000000..dba0cf106 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-sonicwall_rules.xml @@ -0,0 +1,93 @@ + + + + + + + sonicwall + SonicWall messages grouped. + + + + 4800 + ^1 + SonicWall critical message. + + + + 4800 + ^2 + SonicWall critical message. + + + + 4800 + ^3 + SonicWall error message. + + + + 4800 + ^4 + SonicWall warning message. + + + + 4800 + ^5 + SonicWall notice message. + + + + 4800 + ^6 + SonicWall informational message. + + + + 4800 + ^7 + SonicWall debug message. + + + + 4806 + ^236$ + Firewall administrator login. + authentication_success, + + + + 4801 + ^30$|^32$ + Firewall authentication failure. + authentication_failed, + + + + 4804 + Multiple firewall warning messages. + service_availability, + + + + 4803 + Multiple firewall error messages. + service_availability, + + + + diff --git a/openarmor-rules/rules.d/50-crs-spamd_rules.xml b/openarmor-rules/rules.d/50-crs-spamd_rules.xml new file mode 100644 index 000000000..ca1eecbb8 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-spamd_rules.xml @@ -0,0 +1,31 @@ + + + + + + + ^spamd + Grouping for the spamd rules + + + + 3500 + : result: + SPAMD result message (not very usefull here). + + + + 3500 + checking message | processing message + Spamd debug event (reading message). + + + + + diff --git a/openarmor-rules/rules.d/50-crs-squid_rules.xml b/openarmor-rules/rules.d/50-crs-squid_rules.xml new file mode 100644 index 000000000..14d2a3ba0 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-squid_rules.xml @@ -0,0 +1,212 @@ + + + + + + + +8 + + + + + squid + Squid messages grouped. + + + + + + 35000 + ^4|^5|^6 + Squid generic error codes. + + + + 35002 + ^400 + Bad request/Invalid syntax. + + + + 35002 + ^401 + Unauthorized: Failed attempt to access + authorization-required file or directory. + + + + 35002 + ^403 + Forbidden: Attempt to access forbidden file + or directory. + + + + 35002 + ^404 + Not Found: Attempt to access non-existent + file or directory. + + + + 35002 + ^407 + Proxy Authentication Required: User is not + authorized to use proxy. + + + + 35002 + ^4 + Squid 400 error code (request failed). + + + + 35002 + ^5|^6 + Squid 500/600 error code (server error). + + + + 35009 + ^503 + Squid 503 error code (server unavailable). + + + + + 35006 + blst\.php|xxx3\.php|ngr7\.php|ngr2\.php|/nul\.php$|/mul\.php$|/444\.php + Attempt to access a Beagle worm (or variant) + file. + http://www.symantec.com/avcenter/venc/data/w32.beagle.dp.html + W32.Beagle.DP is a Worm that drops Trojan.Lodear and opens a back door on the compromised computer. + automatic_attack, + + + + + 35006 + /jk/exp\.wmf$|/PopupSh\.ocx$ + Attempt to access a worm/trojan related site. + automatic_attack, + + + + + 35004, 35005, 35006, 35009 + \.jpg|\.gif|favicon\.ico$|\.png$|\.swf|\.txt$|\.zip|\.css|\.xml|\.js|\.bmp$| + windowsupdate/redir/wuredir\.cab| + ^http://codecs\.microsoft\.com/isapi/ocget\.dll| + ^http://activex\.microsoft\.com/objects/ocget\.dll| + ^http://webmessenger\.msn\.com/session/null| + ^http://sqm\.msn\.com/sqm/wmp/sqmserver\.dll| + ^http://config\.messenger\.msn\.com/Config/MsgrConfig\.asmx| + kaspersky-labs\.com/| + ^http://liveupdate\.symantecliveupdate\.com/| + _vti_bin/owssvr\.dll|MSOffice/cltreq\.asp| + google\.com/mt\?| + google\.com/kh\?| + ^http://kh\.google\.com/flatfile + + + + Ignored files on a 40x error. + + + + + 35005 + + + Multiple attempts to access forbidden file + or directory from same source ip. + + + + 35007 + + Multiple unauthorized attempts to use proxy. + + + + 35003 + + + Multiple Bad requests/Invalid syntax. + + + + 35021 + + Infected machine with W32.Beagle.DP. + http://www.symantec.com/avcenter/venc/data/w32.beagle.dp.html + W32.Beagle.DP is a Worm that drops Trojan.Lodear and opens a back door on the compromised computer. + + + + 35006 + + + Multiple attempts to access a non-existent file. + + + + 35022 + + Multiple attempts to access a worm/trojan/virus + related web site. System probably infected. + + + + 35008 + + + Multiple 400 error codes (requests failed). + + + + 35009 + + + Multiple 500/600 error codes (server error). + + + + 35055 + + Ignoring multiple attempts from same source ip + (alert only once). + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-sshd_rules.xml b/openarmor-rules/rules.d/50-crs-sshd_rules.xml new file mode 100644 index 000000000..fb791feb5 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-sshd_rules.xml @@ -0,0 +1,404 @@ + + + + + + + sshd + SSHD messages grouped. + + + + 5700 + Bad protocol version identification|error: Protocol major versions differ + Possible attack on the ssh server + (or version gathering). + + + + 5700 + ^reverse mapping.*failed - POSSIBLE BREAK + Reverse lookup error (bad ISP or attack). + + + + 5702 + Possible breakin attempt + (high number of reverse lookup errors). + + + + 5700 + fatal: Timeout before authentication for + Timeout while logging in (sshd). + + + + 5704 + Possible scan or breakin attempt + (high number of login timeouts). + + + + 5700 + Did not receive identification string from + SSH insecure connection attempt (scan). + recon, + + + + 5700 + fatal: buffer_get_string: bad string + OpenSSH challenge-response exploit. + exploit_attempt, + + + + 5700 + error: Could not get shadow information for NOUSER| + fatal: Read from socket failed: |error: ssh_msg_send: write| + ^syslogin_perform_logout: |^pam_succeed_if\(sshd:auth\): error retrieving information about user|can't verify hostname: getaddrinfo + Useless SSHD message without an user/ip and context. + + + + 5700 + illegal user|invalid user + Attempt to login using a non-existent user + invalid_login,authentication_failed, + + + + 5700 + authentication failure; logname= uid=0 euid=0 tty=ssh| + input_userauth_request: invalid user| + PAM: User not known to the underlying authentication module for illegal user| + error retrieving information about user + Useless/Duplicated SSHD message without a user/ip. + + + + 5710 + SSHD brute force trying to get access to + the system. + + authentication_failures, + + + + 5700 + Corrupted check bytes on + Corrupted bytes on SSHD. + + + + 5713 + Local: crc32 compensation attack + SSH CRC-32 Compensation attack + 2001-0144 + http://www.securityfocus.com/bid/2347/info/ + exploit_attempt, + + + + 5700 + ^Accepted|authenticated\.$ + SSHD authentication success. + authentication_success, + + + + 5700 + ^Failed|^error: PAM: Authentication + SSHD authentication failed. + authentication_failed, + + + + 5700 + error: Bad prime description in line + SSHD configuration error (moduli). + + + + 5700 + not allowed because + Attempt to login using a denied user. + invalid_login, + + + + 5718 + Multiple access attempts using a denied user. + invalid_login, + + + + 5716 + + Multiple SSHD authentication failures. + authentication_failures, + + + + 5700 + Received disconnect from + System disconnected from sshd. + + + + 5700 + Connection closed + ssh connection closed. + + + + 5700 + error: buffer_get_bignum2_ret: negative numbers not supported + This maybe a bad key in authorized_keys. + SSHD key error. + + + + 5700 + fatal: buffer_get_bignum2: buffer error + This error may relate to ssh key handling. + SSHD key error. + + + + 5700 + fatal: Write failed: Host is down + Host ungracefully disconnected. + + + + 5700 + error: PAM: Module is unknown for + Unknown PAM module, PAM misconfiguration. + + + + 5700 + failed: Address already in use\. + Attempt to start sshd when something already bound to the port. + + + + 5700 + Authentication service cannot retrieve user credentials + May be related to PAM module errors. + Authentication services were not able to retrieve user credentials. + authentication_failed + + + + 5700 + debug1: attempt + Debug message. + + + + 5700 + error: connect to \S+ port \d+ failed: Connection refused + SSHD is not accepting connections. + + + + 5700 + AKASSH_Version_Mapper1\. + SSH Scanning. + recon, + + + + 5700 + error: connect_to + Possible port forwarding failure. + + + + 5700 + Invalid credentials + User entered incorrect password. + authentication_failures, + + + + 5700 + Could not load host key + sshd could not load one or more host keys. + This may be related to an upgrade to OpenSSH. + + + + 5700 + Write failed: Broken pipe + Failed write due to one host disappearing. + + + + 5700 + ^error: setsockopt SO_KEEPALIVE: Connection reset by peer$| + ^error: accept: Software caused connection abort$ + Connection reset or aborted. + + + + 5700 + ^fatal: Cannot bind any address\.$ + sshd cannot bind to configured address. + + + + 5700 + set_loginuid failed opening loginuid$ + pam_loginuid could not open loginuid. + authentication_failed, + + + + 5700 + ^error: Could not stat AuthorizedKeysCommand + SSHD configuration error (AuthorizedKeysCommand) + + + + 5700 + Connection reset by peer$ + ssh connection reset by peer + + + + 5700 + Connection refused$ + ssh connection refused + + + + 5700 + Connection timed out$ + ssh connection timed out + + + + 5700 + No route to host$ + ssh no route to host + + + + 5700 + failure direct-tcpip$ + ssh port forwarding issue + + + + 5700 + Transport endpoint is not connected$ + ssh transport endpoint is not connected + + + + 5700 + get_remote_port failed$ + ssh get_remote_port failed + + + + + 5700 + bad client public DH value + ssh bad client public DH value + + + + + 5700 + Corrupted MAC on input\. + ssh corrupted MAC on input + + + + 5700 + ^Bad packet length + ssh bad packet length + + + + sshd + 5700 + Unable to negotiate with |Unable to negotiate a key + sshd could not negotiate with client. + + + + sshd + 5700 + no hostkey alg \[preauth\] + No hostkey alg. + + + + 5750 + no matching key exchange method found\.|Unable to negotiate a key exchange method + Client did not offer an acceptable key exchange method. + + + + 5750 + no matching cipher found\. + sshd could not negotiate with client, no matching cipher. + + + + 5700 + Failed to create session: + sshd failed to create a session. + + + + 5700 + bad ownership or modes for file + Authentication refused due to owner/permissions of authorized_keys. + authentication_failed, + + + + 5700 + failed, subsystem not found$ + sshd subsystem request failed. + + + + sshd + but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!$ + Bad DNS mapping. + + + + sshd + ^error: maximum authentication attempts exceeded + Maximum authentication attempts exceeded. + authentication_failed, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-symantec-av_rules.xml b/openarmor-rules/rules.d/50-crs-symantec-av_rules.xml new file mode 100644 index 000000000..227566a8a --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-symantec-av_rules.xml @@ -0,0 +1,51 @@ + + + + + + + + + symantec-av + Grouping of Symantec AV rules. + + + + windows + ^Symantec AntiVirus + Grouping of Symantec AV rules from eventlog. + + + + 7300, 7301 + ^5$|^17$ + virus + Virus detected. + + + + 7300, 7301 + ^2$|^3$|^4$|^13$ + Virus scan updated,started or stopped. + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-symantec-ws_rules.xml b/openarmor-rules/rules.d/50-crs-symantec-ws_rules.xml new file mode 100644 index 000000000..bc8781735 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-symantec-ws_rules.xml @@ -0,0 +1,64 @@ + + + + + + + + + + symantec-websecurity + Grouping of Symantec Web Security rules. + + + + 7400 + ^3=2,2=1 + Login failed accessing the web proxy. + authentication_failed, + + + + 7400 + ^3=1,2=1 + Login success accessing the web proxy. + authentication_success, + + + + 7415 + virtadmin + Admin Login success to the web proxy. + authentication_success, + + + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-sysmon_rules.xml b/openarmor-rules/rules.d/50-crs-sysmon_rules.xml new file mode 100644 index 000000000..bb1c32a1e --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-sysmon_rules.xml @@ -0,0 +1,173 @@ + + + + + + + + + 18100 + svchost\.exe + Sysmon - Suspicious Process - svchost.exe + + + + 18501 + \\services\.exe + Sysmon - Legitimate Parent Image - svchost.exe + + + + + 18100 + lsm\.exe + Sysmon - Suspicious Process - lsm.exe + + + + 18511 + wininit\.exe + Sysmon - Legitimate Parent Image - lsm.exe + + + + 18100 + lsm\.exe + Sysmon - Suspicious Process - lsm.exe is a Parent Image + + + + + 18100 + csrss\.exe + Sysmon - Suspicious Process - csrss.exe + + + + 18521 + smss\.exe + Sysmon - Legitimate Parent Image - csrss.exe + + + + + 18100 + lsass\.exe + Sysmon - Suspicious Process - lsass + + + + 18531 + wininit\.exe + Sysmon - Legitimate Parent Image - lsass.exe + + + + 18100 + lsass\.exe + Sysmon - Suspicious Process - lsass.exe is a Parent Image + + + + + 18100 + winlogon\.exe + Sysmon - Suspicious Process - winlogon.exe + + + + 18541 + smss\.exe + Sysmon - Legitimate Parent Image - winlogon.exe + + + + + 18100 + wininit\.exe + Sysmon - Suspicious Process - wininit + + + + 18551 + smss\.exe + Sysmon - Legitimate Parent Image - wininit.exe + + + + + 18100 + smss\.exe + Sysmon - Suspicious Process - smss.exe + + + + 18561 + system + Sysmon - Legitimate Parent Image - smss.exe + + + + + 18100 + taskhost\.exe + Sysmon - Suspicious Process - taskhost.exe + + + + 18571 + services\.exe|svchost\.exe + Sysmon - Legitimate Parent Image - taskhost.exe + + + + + 18100 + /services\.exe + Sysmon - Suspicious Process - services.exe + + + + 18581 + wininit\.exe + Sysmon - Legitimate Parent Image - services.exe + + + + + 18100 + dllhost\.exe + Sysmon - Suspicious Process - dllhost.exe + + + + 18591 + svchost\.exe|services\.exe + Sysmon - Legitimate Parent Image - dllhost.exe + + + + + 18100 + \\explorer\.exe + Sysmon - Suspicious Process - explorer.exe + + + + 18601 + userinit\.exe + Sysmon - Legitimate Parent Image - explorer.exe + + + + diff --git a/openarmor-rules/rules.d/50-crs-systemd_rules.xml b/openarmor-rules/rules.d/50-crs-systemd_rules.xml new file mode 100644 index 000000000..f8cec7714 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-systemd_rules.xml @@ -0,0 +1,27 @@ + + + + ^systemd$|^systemctl$ + Systemd rules + + + + 40700 + Stale file handle$ + Stale file handle. + + + + 40700 + Failed to get unit file state for + Failed to get unit state for service. This means that the .service file is missing + + + + 40700 + entered failed state + Service has entered a failed state, and likely has not started. + + + + diff --git a/openarmor-rules/rules.d/50-crs-telnetd_rules.xml b/openarmor-rules/rules.d/50-crs-telnetd_rules.xml new file mode 100644 index 000000000..711a43426 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-telnetd_rules.xml @@ -0,0 +1,45 @@ + + + + + + telnetd + Grouping for the telnetd rules + + + + 5600 + refused connect from + Connection refused by TCP Wrappers. + + + + 5600 + : connect from + Remote host established a telnet connection. + + + + ttloop: peer died:|ttloop: read: + 5602 + Remote host invalid connection. + + + + warning: can't verify hostname: + Reverse lookup error (bad hostname config). + + + + 5602 + + Multiple connection attempts from same source + (possible scan). + + + diff --git a/openarmor-rules/rules.d/50-crs-trend-osce_rules.xml b/openarmor-rules/rules.d/50-crs-trend-osce_rules.xml new file mode 100644 index 000000000..0f54ab252 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-trend-osce_rules.xml @@ -0,0 +1,56 @@ + + + + + + + + + trend-osce + Grouping of Trend OSCE rules. + + + + 7600 + ^0|$|^1$|^2$|^33|^10$|^11$|^12$ + virus + Virus detected and cleaned/quarantined/removed + + + + 7600 + ^5$|^6$|^7$|^8$|^14$|^15$|^16$ + virus + Virus detected and unable to clean up. + + + + 7600 + ^4$|^13$ + Virus scan completed with no errors detected. + + + + 7600 + ^25$ + Virus scan passed by found potential security risk. + + + + + diff --git a/openarmor-rules/rules.d/50-crs-unbound_rules.xml b/openarmor-rules/rules.d/50-crs-unbound_rules.xml new file mode 100644 index 000000000..9bf089b35 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-unbound_rules.xml @@ -0,0 +1,65 @@ + + + + + + unbound + Unbound grouping. + + + + 53760 + notice: + Notice grouping. + + + + 53760 + info: + Info grouping. + + + + 53761 + sendto failed: Can't assign requested address + Can't assign requested address. + + + + 53762 + A IN$ + DNS A request. + + + + 53762 + AAAA IN$ + DNS AAAA request. + + + + 53771,53772 + \.top\.|\.to\.|\.gq\.|\.cf\.|\.men\.|\.loan\.|\.ml\.|\.work\.|\.click\.|\.tk\.|\.country\.|\.pw\.|\.party\.|\.trade\.|\.review\.|\.club\.|\.bid\.|\.country\.|\.stream\.|\.download\.|\.xin\.|\.gdn\.|\.racing\.|\.jetzt\.|\.win\.|\.vip\.|\.ren\.|\.kim\.|\.mom\.|\.date\.|\.wang\.|\.accountants\.|\.science\.|\.work\.|\.ninja\.|\.xyz\.|\.faith\.|\.zip\.|\.racing\.|\.cricket\.|\.space\.|\.realtor\.|\.christmas\.|\.gdn\.|\.pro\. + Maybe critical URL requested + + + + 53760 + info: validation failure + DNSSEC validation failure + + + + 53774 + no keys have a DS with algorithm + Algorithm mismatch. + + + diff --git a/openarmor-rules/rules.d/50-crs-vmpop3d_rules.xml b/openarmor-rules/rules.d/50-crs-vmpop3d_rules.xml new file mode 100644 index 000000000..361e919cb --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-vmpop3d_rules.xml @@ -0,0 +1,32 @@ + + + + + + vm-pop3d + Grouping for the vm-pop3d rules. + + + + 9800 + failed auth + authentication_failed, + Login failed accessing the pop3 server. + + + + 9801 + + POP3 brute force (multiple failed logins). + authentication_failures, + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-vmware_rules.xml b/openarmor-rules/rules.d/50-crs-vmware_rules.xml new file mode 100644 index 000000000..e27e7be7a --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-vmware_rules.xml @@ -0,0 +1,157 @@ + + + + + + + vmware + VMWare messages grouped. + + + + vmware-syslog + VMWare ESX syslog messages grouped. + + + + 19100 + ^crit|^fatal + VMware ESX critical message. + + + + 19100 + ^error + VMware ESX error message. + + + + 19100 + ^warn + VMware ESX warning message. + + + + 19100 + ^notice + VMware ESX notice message. + + + + 19100 + ^info + VMware ESX informational message. + + + + 19100 + ^verbose + VMware ESX verbose message. + + + + + + + 19106 + logged in$ + VMWare ESX authentication success. + authentication_success, + + + + 19106 + Failed login attempt for + VMWare ESX authentication failure. + authentication_failed, + + + + 19101 + vmware-hostd|vmware-authd + Accepted password for|login from + VMWare ESX user login. + authentication_success, + + + + 19101 + vmware-hostd|vmware-authd + Rejected password for + VMWare ESX user authentication failure. + authentication_failed, + + + + + + 19106 + -> VM_STATE_OFF + Virtual machine state changed to OFF. + service_availability, + + + + 19106 + -> VM_STATE_POWERING_ON + Virtual machine being turned ON. + + + + 19106 + -> VM_STATE_ON + Virtual machine state changed to ON. + alert_by_email + + + + 19106 + -> VM_STATE_RECONFIGURING + Virtual machine being reconfigured. + config_changed, + alert_by_email + + + + + + + 19104 + Multiple VMWare ESX warning messages. + service_availability, + + + + 19103 + Multiple VMWare ESX error messages. + service_availability, + + + + 19111 + Multiple VMWare ESX authentication failures. + authentication_failures, + + + + 19113 + Multiple VMWare ESX user authentication failures. + authentication_failures, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-vpn_concentrator_rules.xml b/openarmor-rules/rules.d/50-crs-vpn_concentrator_rules.xml new file mode 100644 index 000000000..86d44c687 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-vpn_concentrator_rules.xml @@ -0,0 +1,60 @@ + + + + + + + + + cisco-vpn-concentrator + Grouping of Cisco VPN concentrator rules + + + + 14200 + ^IKE/52$ + VPN authentication successful. + authentication_success, + + + + 14200 + ^AUTH/5$|^AUTH/9$|^IKE/167$|^PPP/9$|^SSH/33$|^PSH/23$ + VPN authentication failed. + authentication_failed, + + + + 14200 + ^HTTP/47$|^SSH/16$ + alert_by_email + VPN Admin authentication successful. + authentication_success, + + + + 14202 + + Multiple VPN authentication failures. + authentication_failures, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-vpopmail_rules.xml b/openarmor-rules/rules.d/50-crs-vpopmail_rules.xml new file mode 100644 index 000000000..8a33e455a --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-vpopmail_rules.xml @@ -0,0 +1,68 @@ + + + + + + vpopmail + Grouping for the vpopmail rules. + + + + 9900 + password fail + authentication_failed, + Login failed for vpopmail. + + + + 9900 + vpopmail user not found + invalid_login, + Attempt to login to vpopmail with invalid username. + + + + 9900 + null password given + authentication_failed, + Attempt to login to vpopmail with empty password. + + + + 9900 + login success + authentication_success, + Vpopmail successful login. + + + + + 9901 + + Vpopmail brute force (multiple failed logins). + authentication_failures, + + + + 9902 + + Vpopmail brute force (email harvesting). + authentication_failures, + + + + 9903 + + VPOPMAIL brute force (empty password). + authentication_failures, + + + + + diff --git a/openarmor-rules/rules.d/50-crs-vsftpd_rules.xml b/openarmor-rules/rules.d/50-crs-vsftpd_rules.xml new file mode 100644 index 000000000..ef63b2bd5 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-vsftpd_rules.xml @@ -0,0 +1,62 @@ + + + + + + vsftpd + Grouping for the vsftpd rules. + + + + 11400 + CONNECT: Client + connection_attempt + FTP session opened. + + + + 11400 + OK LOGIN: + FTP Authentication success. + authentication_success, + + + + 11400 + FAIL LOGIN: + Login failed accessing the FTP server. + authentication_failed, + + + + 11400 + OK UPLOAD: + FTP server file upload. + + + + 11403 + + FTP brute force (multiple failed logins). + authentication_failures, + + + + 11401 + + Multiple FTP connection attempts from + same source IP. + recon, + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-web_rules.xml b/openarmor-rules/rules.d/50-crs-web_rules.xml new file mode 100644 index 000000000..54cdeb777 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-web_rules.xml @@ -0,0 +1,225 @@ + + + + + + web-log + Access log messages grouped. + + + + 31100 + ^2|^3 + is_simple_http_request + Ignored URLs (simple queries). + + + + 31100 + ^4 + Web server 400 error code. + + + + 31101 + \.jpg$|\.gif$|favicon\.ico$|\.png$|robots\.txt$|\.css$|\.js$|\.jpeg$ + is_simple_http_request + Ignored extensions on 400 error codes. + + + + 31100,31108 + =select%20|select\+|insert%20|%20from%20|%20where%20|union%20| + union\+|where\+|null,null|xp_cmdshell + SQL injection attempt. + attack,sql_injection, + + + + 31100 + + + %027|%00|%01|%7f|%2E%2E|%0A|%0D|\.\./\.\.|\.\.\\\.\.|echo;| + cmd\.exe|root\.exe|_mem_bin|msadc|/winnt/|/boot\.ini| + /x90/|default\.ida|/sumthin|nsiislog\.dll|chmod%|wget%|cd%20| + exec%20|\.\./\.\.//|%5C\.\./%5C|\./\./\./\./|2e%2e%5c%2e|\\x5C\\x5C + Common web attack. + attack, + + + + 31100 + %3Cscript|%3C%2Fscript|script>|script%3E|SRC=javascript|IMG%20| + %20ONLOAD=|INPUT%20|iframe%20 + XSS (Cross Site Scripting) attempt. + attack, + + + + 31103, 31104, 31105 + ^200 + A web attack returned code 200 (success). + attack, + + + + 31100 + \?-d|\?-s|\?-a|\?-b|\?-w + PHP CGI-bin vulnerability attempt. + attack, + + + + 31100 + \+as\+varchar + %2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\)%2Bchar\(\d+\) + MSSQL Injection attempt (/ur.php, urchin.js) + attack, + + + + + + 31103, 31104, 31105 + ^/search\.php\?search=|^/index\.php\?searchword= + Ignored URLs for the web attacks + + + + 31100 + URL too long. Higher than allowed on most + browsers. Possible attack. + invalid_access, + + + + + + 31100 + ^50 + Web server 500 error code (server error). + + + + 31120 + ^501 + Web server 501 error code (Not Implemented). + + + + 31120 + ^500 + alert_by_email + Web server 500 error code (Internal Error). + system_error, + + + + 31120 + ^503 + alert_by_email + Web server 503 error code (Service unavailable). + + + + + + 31101 + is_valid_crawler + Ignoring google/msn/yahoo bots. + + + + + 31101 + ^499 + Ignored 499's on nginx. + + + + + 31101 + + Multiple web server 400 error codes + from same source ip. + web_scan,recon, + + + + 31103 + + Multiple SQL injection attempts from same + source ip. + attack,sql_injection, + + + + 31104 + + Multiple common web attacks from same source ip. + attack, + + + + 31105 + + Multiple XSS (Cross Site Scripting) attempts + from same source ip. + attack, + + + + 31121 + + Multiple web server 501 error code (Not Implemented). + web_scan,recon, + + + + 31122 + + Multiple web server 500 error code (Internal Error). + system_error, + + + + 31123 + + Multiple web server 503 error code (Service unavailable). + web_scan,recon, + + + + 31100 + =%27|select%2B|insert%2B|%2Bfrom%2B|%2Bwhere%2B|%2Bunion%2B + SQL injection attempt. + attack,sqlinjection, + + + + 31100 + %EF%BC%87|%EF%BC%87|%EF%BC%87|%2531|%u0053%u0045 + SQL injection attempt. + attack,sqlinjection, + + + diff --git a/openarmor-rules/rules.d/50-crs-wordpress_rules.xml b/openarmor-rules/rules.d/50-crs-wordpress_rules.xml new file mode 100644 index 000000000..686d6f299 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-wordpress_rules.xml @@ -0,0 +1,69 @@ + + + + + wordpress + Wordpress messages grouped. + + + + 9500 + User authentication failed + Wordpress authentication failed. + authentication_failed, + + + + 9500 + User logged in + Wordpress authentication succeeded. + authentication_success, + + + + 9500 + WPsyslog was successfully initiali + WPsyslog was successfully initialized. + + + + 9500 + Plugin deactivated + Wordpress plugin deactivated. + + + + 9500 + Warning: Comment flood attempt + Wordpress Comment Flood Attempt. + + + + 9500 + Warning: IDS: + Attack against Wordpress detected. + + + + 9501 + + Multiple wordpress authentication failures. + authentication_failures, + + + + + + diff --git a/openarmor-rules/rules.d/50-crs-zeus_rules.xml b/openarmor-rules/rules.d/50-crs-zeus_rules.xml new file mode 100644 index 000000000..768719408 --- /dev/null +++ b/openarmor-rules/rules.d/50-crs-zeus_rules.xml @@ -0,0 +1,75 @@ + + + + + + + + + zeus + Grouping of Zeus rules. + + + + 31200 + ^\[\S+ \S+\] INFO:|^\[\S+ \S+\] SSL: + Grouping of Zeus informational logs. + + + + 31200 + ^\[\S+ \S+\] WARN: + Zeus warning log. + + + + 31200 + ^\[\S+ \S+\] SERIOUS: + Zeus serious log. + + + + 31200 + ^\[\S+ \S+\] FATAL: + Zeus fatal log. + + + + 31202 + admin:Authentication failure + Admin authentication failed. + authentication_failed, + + + + 31202 + Unknown directive + Configuration warning (ignored). + + + + 31202 + Multiple Zeus warnings. + + + + + diff --git a/openarmor-rules/rules.d/55-crs-msft-firewall_rules.xml b/openarmor-rules/rules.d/55-crs-msft-firewall_rules.xml new file mode 100644 index 000000000..3f2e1c1f4 --- /dev/null +++ b/openarmor-rules/rules.d/55-crs-msft-firewall_rules.xml @@ -0,0 +1,173 @@ + + + + + + 18104 + ^5024$ + Windows Firewall Service has started successfully + windows_firewall + + + + 18104 + ^5025$ + Windows Firewall Service has been stopped + windows_firewall + + + + 18104 + ^5027$ + Windows Firewall Service was unable to retrieve the security policy from the local storage. Windows Firewall will continue to enforce the current policy + windows_firewall + + + + 18104 + ^5028$ + Windows Firewall was unable to parse the new security policy. Windows Firewall will continue to enforce the current policy + windows_firewall + + + + 18104 + ^5029$ + The Windows Firewall service failed to initialize the driver. Windows Firewall will continue to enforce the current policy + windows_firewall + + + + 18104 + ^5030$ + Windows Firewall Service failed to start + windows_firewall + + + + 18105 + ^5031$ + Windows Firewall Service blocked an application from accepting incoming connections on the network + windows_firewall + + + + 18105 + ^5032$ + Windows Firewall was unable to notify the user that it blocked an application from accepting incoming connections on the network + windows_firewall + + + + 18104 + ^5033$ + Windows Firewall Driver started successfully + windows_firewall + + + + 18104 + ^5034$ + Windows Firewall Driver was stopped + windows_firewall + + + + 18105 + ^5035$ + Windows Firewall Driver failed to start + windows_firewall + + + + 18105 + ^5037$ + Windows Firewall Driver detected a critical runtime error, terminating + windows_firewall + + + + 18104 + ^4946$ + A rule was added to Windows Firewall exception list + windows_firewall + + + + 18104 + ^4947$ + A rule was modified from Windows Firewall exception list + windows_firewall + + + + 18104 + ^4948$ + A rule was deleted from Windows Firewall exception list + windows_firewall + + + + 18104 + ^4949$ + Windows Firewall settings were restored to the default values + windows_firewall + + + + 18104 + ^4950$ + A Windows Firewall setting was changed + windows_firewall + + + + 18105 + ^4951$ + Windows Firewall ignored a rule because its major version number is not recognized. + windows_firewall + + + + 18105 + ^4952$ + Windows Firewall ignored parts of a rule because its minor version number is not recognized. Other parts of the rule will be enforced + windows_firewall + + + + 18105 + ^4953$ + Windows Firewall ignored a rule because it could not be parsed + windows_firewall + + + + 18104 + ^4954$ + Group Policy settings for Windows Firewall were changed, and the new settings were applied + windows_firewall + + + + 18104 + ^4956$ + Windows Firewall changed the active profile + windows_firewall + + + + 18105 + ^4957$ + Windows Firewall did not apply some rules + windows_firewall + + + + 18105 + ^4958$ + Windows Firewall did not apply some rules because the rule referred to items not configured on this computer + windows_firewall + + + diff --git a/openarmor-rules/rules.d/55-crs-topleveldomain_rules.xml b/openarmor-rules/rules.d/55-crs-topleveldomain_rules.xml new file mode 100644 index 000000000..18813763a --- /dev/null +++ b/openarmor-rules/rules.d/55-crs-topleveldomain_rules.xml @@ -0,0 +1,14 @@ + + + + + + + + + 31100 + \.top:|\.to:|\.gq:|\.cf:|\.men:|\.loan:|\.ml:|\.work:|\.click:|\.tk:|\.country:|\.pw:|\.party:|\.trade:|\.review:|\.club:|\.bid:|\.country:|\.stream:|\.download:|\.xin:|\.gdn:|\.racing:|\.jetzt:|\.win:|\.vip:|\.ren:|\.kim:|\.mom:|\.date:|\.wang:|\.accountants:|\.science:|\.work:|\.ninja:|\.xyz:|\.faith:|\.zip:|\.racing:|\.cricket:|\.space:|\.realtor:|\.christmas:|\.gdn:|\.pro: + Maybe critical URL access attempt + + + diff --git a/openarmor-rules/rules.d/60-crs-attack_rules.xml b/openarmor-rules/rules.d/60-crs-attack_rules.xml new file mode 100644 index 000000000..9d97230e4 --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-attack_rules.xml @@ -0,0 +1,122 @@ + + + + +^apache$|^mysql$|^www$|^nobody$|^nogroup$|^portmap$|^named$|^rpc$|^mail$|^ftp$|^shutdown$|^halt$|^daemon$|^bin$|^postfix$|^shell$|^info$|^guest$|^psql$|^user$|^users$|^console$|^uucp$|^lp$|^sync$|^sshd$|^cdrom$|^openarmor$ + + + + + + authentication_success + $SYS_USERS + System user successfully logged to the system. + invalid_login, + + + + ^rpc\.statd\[\d+\]: gethostbyname error for [^A-Za-z0-9@_-]+ + Buffer overflow attack on rpc.statd + exploit_attempt, + + + + ftpd\[\d+\]: \S+ FTP LOGIN FROM .+ 0bin0sh + Buffer overflow on WU-FTPD versions prior to 2.6 + exploit_attempt, + + + + \?{21} + Possible buffer overflow attempt. + exploit_attempt, + + + + changed by \(\(null\) + "Null" user changed some information. + exploit_attempt, + + + + @{25} + Buffer overflow attempt (probably on yppasswd). + exploit_attempt, + + + + cachefsd: Segmentation Fault - core dumped + Heap overflow in the Solaris cachefsd service. + 2002-0033 + exploit_attempt, + + + + attempt to execute code on stack by + Stack overflow attempt or program exiting + with SEGV (Solaris). + http://snap.nlc.dcccd.edu/reference/sysadmin/julian/ch18/389-392.html + exploit_attempt, + + + + authentication_failed + Multiple authentication failures. + authentication_failures, + + + + authentication_success + authentication_failures + + Multiple authentication failures followed + by a success. + + + + virus + Multiple viruses detected - Possible outbreak. + virus, + + + + + + + + + + adduser + attacks + Attacks followed by the addition + of an user. + + + + + + + + + connection_attempt + Network scan from same source ip. + + http://project.honeynet.org/papers/enemy2/ + + + + + diff --git a/openarmor-rules/rules.d/60-crs-mcafee_av_rules.xml b/openarmor-rules/rules.d/60-crs-mcafee_av_rules.xml new file mode 100644 index 000000000..533f98db3 --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-mcafee_av_rules.xml @@ -0,0 +1,125 @@ + + +^259$|^100$|^1000$|^1001$|^1002$|^1003$|^1004$|^1005$|^1006$|^1007$|^1008$|^5003$|^5005$|^5008$|^5010$|^5011$|^5019$|^5020$|^5021$|^5022$|^5030$|^5031$|^5032$|^5033$|^5034$|^5035$|^5046$|^5047$|^5048$|^5049$|^5051$|^5054$|^5057$|^5059$|^5060$|^5063$|^5063$ +^258$|^5001$|^5028$|^5036$|^5037$|^5038$|^5039$|^5040$|^5041$|^5053$|^5056$|^5061$|^5062$|^5065$ +^257$|^5000$|^5026$|^5052$|^5055$ +quarantined|moved to quarantine|file was deleted|deleted successfully|has been deleted|message deleted|deleted after|cleaned|successfully deleted +The file \.+ contain|infected with|User defined detection|scan found|error attempting to clean +10 + + + + 18101,18102,18103 + windows + ^McLogEvent + Grouping of McAfee Windows AV rules. + + + + 7500 + $MCAFEE_INFO + McAfee Windows AV informational event. + + + + 7500 + $MCAFEE_WARN + McAfee Windows AV warning event. + + + + 7500 + $MCAFEE_ERROR + McAfee Windows AV error event. + + + + 7500 + $MCAFEE_VIRUS + virus + McAfee Windows AV - Virus detected and not removed. + + + + 7504 + $MCAFEE_VIRUS_OK + virus + McAfee Windows AV - Virus detected and properly removed. + + + + 7504 + Will be deleted + virus + McAfee Windows AV - Virus detected and file will be deleted. + + + + 7500 + scan started|scan stopped + McAfee Windows AV - Scan started or stopped. + + + + 7501 + ^257 + completed\. No detections + McAfee Windows AV - Scan completed with no viruses found. + + + + 7500 + scan was cancelled |has taken too long + McAfee Windows AV - Virus scan cancelled. + + + + 7500 + scan was canceled because + McAfee Windows AV - Virus scan cancelled due to shutdown. + + + + 7500 + update was successful + McAfee Windows AV - Virus program or DAT update succeeded. + + + + 7500 + update failed + McAfee Windows AV - Virus program or DAT update failed. + + + + 7500 + update was cancelled + McAfee Windows AV - Virus program or DAT update cancelled. + + + + 7505 + contains the EICAR test file + alert_by_email + McAfee Windows AV - EICAR test file detected. + + + + + + 7502 + Multiple McAfee AV warning events. + + + + diff --git a/openarmor-rules/rules.d/60-crs-ms-se_rules.xml b/openarmor-rules/rules.d/60-crs-ms-se_rules.xml new file mode 100644 index 000000000..7fc4011f7 --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-ms-se_rules.xml @@ -0,0 +1,131 @@ + + + + + + + + windows + 18101,18102,18103 + ^Microsoft Antimalware + Grouping of Microsoft Security Essentials rules. + + + + 7701 + ^1118$|^1119$ + virus + Microsoft Security Essentials - Virus detected, but unable to remove. + + + + 7701 + ^1107$ + virus + Microsoft Security Essentials - Virus detected and properly removed. + + + + 7701 + ^1119$|^1118$|^1117$|^1116$ + virus + Microsoft Security Essentials - Virus detected. + + + + 7701 + ^1015$ + virus, + Microsoft Security Essentials - Suspicious activity detected. + + + + 7701 + ^5007$ + Microsoft Security Essentials - Configuration changed. + policy_changed, + + + + 7701 + ^5008$ + Microsoft Security Essentials - Service failed. + + + + 7701 + ^3002$ + Microsoft Security Essentials - Real time protection failed. + + + + 7701 + ^2012$ + Microsoft Security Essentials - Cannot use Dynamic Signature Service. + + + + 7701 + ^2004$ + Microsoft Security Essentials - Loading definitions failed. Using last good set. + + + + 7701 + ^2003$ + Microsoft Security Essentials - Engine update failed. + + + + 7701 + ^2001$ + Microsoft Security Essentials - Definitions update failed. + + + + 7701 + ^1005$ + Microsoft Security Essentials - Scan error. Scan has stopped. + + + + 7701 + ^1002$ + Microsoft Security Essentials - Scan stopped before completion. + + + + + 7711, 7712 + Virus:DOS/EICAR_Test_File + alert_by_email + Microsoft Security Essentials - EICAR test file detected. + + + + + 7711 + Multiple Microsoft Security Essentials AV warnings detected. + + + + 7712 + Multiple Microsoft Security Essentials AV warnings detected. + + + + + diff --git a/openarmor-rules/rules.d/60-crs-ms1016_usbdetect_rules.xml b/openarmor-rules/rules.d/60-crs-ms1016_usbdetect_rules.xml new file mode 100644 index 000000000..af4dfcf37 --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-ms1016_usbdetect_rules.xml @@ -0,0 +1,10 @@ + + + + + 18104 + ^6416$ + A new external device was recognized by the System + windows, + + diff --git a/openarmor-rules/rules.d/60-crs-msft-ipsec_rules.xml b/openarmor-rules/rules.d/60-crs-msft-ipsec_rules.xml new file mode 100644 index 000000000..d0584555c --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-msft-ipsec_rules.xml @@ -0,0 +1,149 @@ + + + + + + + 18104 + ^4646$ + IKE DoS-prevention mode started + windows, + + + + + 18105 + ^4652$|^4653$ + An IPsec Main Mode negotiation failed + windows, + + + + + 18105 + ^4654$ + An IPsec Quick Mode negotiation failed + windows, + + + + + 18104 + ^4983$|^4984$ + An IPsec Extended Mode negotiation failed + windows, + + + + + 18104 + ^4960$ + IPsec dropped an inbound packet that failed an integrity check + windows, + + + + + 18104 + ^4961$|^4962$ + IPsec dropped an inbound packet that failed a replay check + windows, + + + + + 18104 + ^4963$ + IPsec dropped an inbound clear text packet that should have been secured + windows, + + + + + 18104 + ^4965$ + IPsec received a packet from a remote computer with an incorrect Security Parameter Index (SPI) + windows, + + + + + 18104 + ^4976$ + During Main Mode negotiation, IPsec received an invalid negotiation packet + windows, + + + + + 18104 + ^4977$ + During Quick Mode negotiation, IPsec received an invalid negotiation packet + windows, + + + + + 18104 + ^4978$ + During Extended Mode negotiation, IPsec received an invalid negotiation packet + windows, + + + + + 18104 + ^5453$ + An IPsec negotiation with a remote computer failed because the IKE and AuthIP IPsec Keying Modules (IKEEXT) service is not started + windows, + + + + + 18105 + ^5480$ + IPsec Services failed to get the complete list of network interfaces on the computer + windows, + + + + + 18105 + ^5483$ + IPsec Services failed to initialize RPC server. IPsec Services could not be started + windows, + + + + + 18105 + ^5484$ + IPsec Services has experienced a critical failure and has been shut down + windows, + + + + + 18105 + ^5485$ + IPsec Services failed to process some IPsec filters on a plug-and-play event for network interfaces + windows, + + + + + 18104 + ^4710$ + IPsec Services was disabled + windows, + + + + + 18105 + ^4712$ + IPsec Services encountered a potentially serious failure + windows, + + + diff --git a/openarmor-rules/rules.d/60-crs-msft-powershell_rules.xml b/openarmor-rules/rules.d/60-crs-msft-powershell_rules.xml new file mode 100644 index 000000000..24fd12cfe --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-msft-powershell_rules.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + 18101 + ^400$ + PowerShell + Windows PowerShell was started. + + + + 18101 + ^800$ + PowerShell + Windows PowerShell command executed. + + + + 18101 + ^403$ + PowerShell + Windows PowerShell was stopped. + + + + 20501 + Set-StrictMode -Version 1; .+[A-Za-z0-9@_-]+ + A wrong/misspelled command was tried + + + + 20501 + CommandLine= CommandInvocation + Powershell background activity + + + + 20501 + Set-ExecutionPolicy|Mimikatz|EncodedCommand|Payload|Find-AVSignature|DllInjection|ReflectivePEInjection|Invoke-Shellcode|Invoke--Shellcode|Invoke-ShellcodeMSIL|Get-GPPPassword|Get-Keystrokes|Get-TimedScreenshot|Get-VaultCredential|Invoke-CredentialInjection|Invoke-NinjaCopy|Invoke-TokenManipulation|Out-Minidump|Set-MasterBootRecord|New-ElevatedPersistenceOption|Invoke-CallbackIEX|Invoke-PSInject|Invoke-DllEncode|Get-ServiceUnquoted|Get-ServiceEXEPerms|Get-ServicePerms|Invoke-ServiceUserAdd|Invoke-ServiceCMD|Write-UserAddServiceBinary|Write-CMDServiceBinary|Write-UserAddMSI|Write-ServiceEXE|Write-ServiceEXECMD|Restore-ServiceEXE|Invoke-ServiceStart|Invoke-ServiceStop|Invoke-ServiceEnable|Invoke-ServiceDisable|Invoke-FindDLLHijack|Invoke-FindPathHijack|Get-RegAlwaysInstallElevated|Get-RegAutoLogon|Get-UnattendedInstallFiles|Get-Webconfig|Get-Webconfig|Get-ApplicationHost|Invoke-AllChecks|Invoke-MassCommand|Invoke-MassMimikatz|Invoke-MassSearch|Invoke-MassTemplate|Invoke-MassTokens|HTTP-Backdoor|Add-ScrnSaveBackdoor|Gupt-Backdoor|Invoke-ADSBackdoor|Execute-OnTime|DNS_TXT_Pwnage|Out-Word|Out-Excel|Out-Java|Out-Shortcut|Out-CHM|Out-HTA|Enable-DuplicateToken|Remove-Update|Execute-DNSTXT-Code|Download-Execute-PS|Execute-Command-MSSQL|Download_Execute|Get-PassHashes|Invoke-CredentialsPhish|Get-LsaSecret|Get-Information|Invoke-MimikatzWDigestDowngrade|Copy-VSS|Check-VM|Invoke-NetworkRelay|Create-MultipleSessions|Run-EXEonRemote|Invoke-BruteForce|Port-Scan|Invoke-PowerShellIcmp|Invoke-PowerShellUdp|Invoke-PsGcatAgent|Invoke-PoshRatHttps|Invoke-PowerShellTcp|Invoke-PoshRatHttp|Invoke-PowerShellWmi|Invoke-PSGcat|Remove-PoshRat|TexttoEXE|Invoke-Encode|Invoke-Decode|Base64ToString|StringtoBase64|Do-Exfiltration|Parse_Keys|Add-Exfiltration|Add-Persistence|Remove-Persistence|Invoke-CreateCertificate|powercat|Find-PSServiceAccounts|Get-PSADForestKRBTGTInfo|Discover-PSMSSQLServers|Discover-PSMSExchangeServers|Get-PSADForestInfo|Get-KerberosPolicy|Discover-PSInterestingServices + Possibly Dangerous Command Detected (https://gist.github.com/gfoss/2b39d680badd2cad9d82#file-powershell-command-line-logging) + + + diff --git a/openarmor-rules/rules.d/60-crs-web_appsec_rules.xml b/openarmor-rules/rules.d/60-crs-web_appsec_rules.xml new file mode 100644 index 000000000..ba77c64a5 --- /dev/null +++ b/openarmor-rules/rules.d/60-crs-web_appsec_rules.xml @@ -0,0 +1,190 @@ + + + + + + + + + + + 31100 + POST /.*(?:Googlebot|MSNBot|BingBot) + /wp-comments-post\.php + WordPress Comment Spam (coming from a fake search engine UA). + + + + + 31100 + thumb\.php|timthumb\.php + "GET \S+thumb\.php\?src=\S+\.php + TimThumb vulnerability exploit attempt. + + + + + 31100 + login\.php + "POST /\S+\.php/login\.php\?cPath= + osCommerce login.php bypass attempt. + + + + + 31100 + login\.php + /admin/[A-Za-z0-9@_-]+\.php/login\.php + osCommerce file manager login.php bypass attempt. + + + + + 31100 + /cache/external + "GET /\S+/cache/external\S+\.php + TimThumb backdoor access attempt. + + + + + 31100 + cart\.php + "GET /\S+cart\.php\?\S+templatefile=\.\./ + Cart.php directory transversal attempt. + + + + + 31100 + DECLARE%20@S%20CHAR|%20AS%20CHAR + MSSQL Injection attempt (ur.php, urchin.js). + + + + + 31100 + "ZmEu"| "libwww-perl/|"the beast"|"Morfeus|"ZmEu|"Nikto|"w3af\.sourceforge\.net|MJ12bot/v| Jorgee"|"Proxy Gear Pro|"DataCha0s + Blacklisted user agent (known malicious user agent). + + + + + 31108 + wp-login\.php|/administrator + \] "POST \S+wp-login\.php| "POST /administrator + CMS (WordPress or Joomla) login attempt. + + + + + 31509 + + CMS (WordPress or Joomla) brute force attempt. + + + + + 31100 + " "Wget/ + Blacklisted user agent (wget). + + + + + 31100 + uploadify\.php + "GET /\S+/uploadify\.php\?src=http://\S+\.php + Uploadify vulnerability exploit attempt. + + + + + 31100 + delete\.php + "GET \S+/delete\.php\?board_skin_path=http://\S+\.php + BBS delete.php exploit attempt. + + + + + 31100 + shell\.php + "GET \S+/shell\.php\?cmd= + Simple shell.php command execution. + + + + + 31100 + phpMyAdmin/scripts/setup\.php + PHPMyAdmin scans (looking for setup.php). + + + + + 31100 + \.swp$|\.bak$|/\.htaccess|/server-status|/\.ssh|/\.history|/wallet\.dat + Suspicious URL access. + + + + + 31100 + \] "POST + no_log + POST request received. + + + + 31530 + /wp-admin/|/administrator/|/admin/ + Ignoring often post requests inside /wp-admin and /admin. + + + + 31530 + + High amount of POST requests in a small period of time (likely bot). + + + + + 31100 + %00 + "GET /\S+\.php\?\S+%00 + Anomaly URL query (attempting to pass null termination). + + + + diff --git a/openarmor-rules/rules.d/70-crs-last_rootlogin_rules.xml b/openarmor-rules/rules.d/70-crs-last_rootlogin_rules.xml new file mode 100644 index 000000000..f3d38d894 --- /dev/null +++ b/openarmor-rules/rules.d/70-crs-last_rootlogin_rules.xml @@ -0,0 +1,13 @@ + + + + + + + + 535 + root|reboot|admin|superuser|administrator|supervisor|toor + sensitive login detected + + + diff --git a/openarmor-rules/rules.d/70-crs-nsd_rules.xml b/openarmor-rules/rules.d/70-crs-nsd_rules.xml new file mode 100644 index 000000000..f671889ff --- /dev/null +++ b/openarmor-rules/rules.d/70-crs-nsd_rules.xml @@ -0,0 +1,97 @@ + + + + + nsd + NSD grouping. + + + + 53200 + unrecognized RR type + Syntax error in nsd configuration. + + + + nsd + 53200 + server initialization failed|syntax error$ + Syntax error in nsd configuration. + + + + 53200 + ^NSTATS|^XSTATS + nsd statistics + + + + nsd + Can't bind + Cannot bind to a socket. + + + + nsd + nsd is already running + nsd is already running. + + + + nsd + 53200 + received notify response error NOT IMPL + Notify is not implemented. + + + + nsd + 53200 + read with \d+ errors$ + Zone file read with errors. + + + + nsd + 53200 + received error code + Error grouping. + + + + nsd + 53208 + NOT IMPL + Zone xfer not implemented. + + + + 53200 + tcp: Connection reset by peer$ + tcp connection reset. + + + + 53200 + received error code NOT IMPL + Attempted zone transfer not configured. + + + + 53208 + received error code SERVER NOT AUTHORITATIVE FOR ZONE + Server not authoritative for zone transfer. + + + + + + diff --git a/openarmor-rules/rules.d/70-crs-openbsd-dhcp_rules.xml b/openarmor-rules/rules.d/70-crs-openbsd-dhcp_rules.xml new file mode 100644 index 000000000..f06e17f3a --- /dev/null +++ b/openarmor-rules/rules.d/70-crs-openbsd-dhcp_rules.xml @@ -0,0 +1,84 @@ + + + + + + dhcpd + dhcpd grouping. + + + + 53000 + ^DHCPREQUEST|^DHCPOFFER |^DHCPDISCOVER|^DHCPACK + Normal dhcp. + + + + 53000 + answers a ping after sending a release|Possible release spoof + A host issued a release but is responding to pings. + + + + 53000 + expecting left brace\.$| + fixed-address parameter not allowed here\.$| + parameters not allowed after first declaration\.$| + Configuration file errors encountered + Configuration errors. + + + + 53000 + exiting\.$ + dhcpd is exiting. + + + + 53000 + Can't listen on + dhcpd cannot listen to an interface. + + + + 53006 + has no subnet declaration for + dhcpd is not configured to listen to an interface. + + + + 53000 + Listening on + dhcpd has been started. + + + + 53000 + ^Address range + Message with address range. + + + + 53009 + not on net + Defined address range is not on the configured network. + + + + 53000 + ^no free leases + DHCP server has run out of leases. + + + + 53000 + ^already acking lease + Multiple acks. + + + + + diff --git a/openarmor-rules/rules.d/70-crs-owncloud_rules.xml b/openarmor-rules/rules.d/70-crs-owncloud_rules.xml new file mode 100644 index 000000000..49d4c83ed --- /dev/null +++ b/openarmor-rules/rules.d/70-crs-owncloud_rules.xml @@ -0,0 +1,58 @@ + + + owncloud + ownCloud messages grouped. + + + + 53300 + Login failed: + ownCloud authentication failed. + authentication_failed, + + + + 53301 + + ownCloud brute force (multiple failed logins). + authentication_failures, + + + + 53300 + Passed filename is not valid, might be malicious + ownCloud possible malicious request. + web,appsec,attack, + + + + 53300 + ^4$ + ownCloud FATAL message. + + + + 53300 + ^3$ + ownCloud ERROR message. + + + + 53300 + ^2$ + ownCloud WARN message. + + + + 53300 + ^1$ + ownCloud INFO message. + + + + 53300 + ^0$ + ownCloud DEBUG message. + + + \ No newline at end of file diff --git a/openarmor-rules/rules.d/70-crs-proxmox-ve_rules.xml b/openarmor-rules/rules.d/70-crs-proxmox-ve_rules.xml new file mode 100644 index 000000000..c81fe759d --- /dev/null +++ b/openarmor-rules/rules.d/70-crs-proxmox-ve_rules.xml @@ -0,0 +1,28 @@ + + + pvedaemon + pvedaemon messages grouped. + + + + 53400 + authentication failure; + Proxmox VE authentication failed. + authentication_failed, + + + + 53401 + + Proxmox VE brute force (multiple failed logins). + authentication_failures, + + + + 53400 + successful auth for user + Proxmox VE authentication succeeded. + authentication_success, + + + \ No newline at end of file diff --git a/openarmor-rules/rules.d/70-crs-psad_rules.xml b/openarmor-rules/rules.d/70-crs-psad_rules.xml new file mode 100644 index 000000000..c3f1a6d4a --- /dev/null +++ b/openarmor-rules/rules.d/70-crs-psad_rules.xml @@ -0,0 +1,51 @@ + + + psad + psad + PSAD group + + + + 53700 + scan detected + PSAD group scan detected + + + 53700 + added iptables + PSAD group added iptables + + + + 53701 + DL: 4|DL: 5 + PSAD portscan + + + 53702 + auto-block against + PSAD auto-block + + + + 53701 + DL: 3 + PSAD level 3 warning + + + 53713 + + many PSAD level 3 warnings from same source + + + 53713 + + many PSAD level 3 warnings from same source (slow scan) + + + + 53700 + signature match: + PSAD signature match + + diff --git a/openarmor-rules/rules.d/99-crs-policy_rules.xml b/openarmor-rules/rules.d/99-crs-policy_rules.xml new file mode 100644 index 000000000..157c2e2ac --- /dev/null +++ b/openarmor-rules/rules.d/99-crs-policy_rules.xml @@ -0,0 +1,36 @@ + + + + + + authentication_success + + Successful login during non-business hours. + login_time, + no_ar + + + + authentication_success + weekends + Successful login during weekend. + login_day, + no_ar + + + + + diff --git a/openarmor-rules/shared/acsc_office2016_rcl.txt b/openarmor-rules/shared/acsc_office2016_rcl.txt new file mode 100644 index 000000000..e6a5ee1bd --- /dev/null +++ b/openarmor-rules/shared/acsc_office2016_rcl.txt @@ -0,0 +1,427 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# Hardening Checks for Microsoft Office 2016 +# Based on Australian Cyper Security Centre Hardening Microsoft Office Guide - May 2018 (https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf) +# +# +#7 Ensure Attack Surface Reduction is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7 Ensure Attack Surface Reduction is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> ExploitGuard_ASR_Rules -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> !ExploitGuard_ASR_Rules; +# +# +#7a Ensure 'Block executable content from email client and webmail' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7a Ensure 'Block executable content from email client and webmail' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550; +# +# +#7b Ensure 'block Office applications from creating child processes' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7b Ensure 'block Office applications from creating child processes' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D4F940AB-401B-4EFC-AADC-AD5F3C50688A -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D4F940AB-401B-4EFC-AADC-AD5F3C50688A; +# +# +#7c Ensure 'block Office applications from creating executable content' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7c Ensure 'block Office applications from creating executable content' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 3B576869-A4EC-4529-8536-B80A7769E899 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !3B576869-A4EC-4529-8536-B80A7769E899; +# +# +#7d Ensure 'block Office applications from injecting code into other processes' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7d Ensure 'block Office applications from injecting code into other processes' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84; +# +# +#7e Ensure 'block JavaScript and VBScript from launching downloaded executable content' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7e Ensure 'block JavaScript and VBScript from launching downloaded executable content' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D3E037E1-3EB8-44C8-A917-57927947596D -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D3E037E1-3EB8-44C8-A917-57927947596D; +# +# +#7f Ensure 'block execution of potentially obfuscated scripts' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7f Ensure 'block execution of potentially obfuscated scripts' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !5BEB7EFE-FD9A-4556-801D-275E5FFC04CC; +# +# +#7g Ensure 'block Win32 API calls from Office macro' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7g Ensure 'block Win32 API calls from Office macro' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B; +# +# +#17 Ensure 'Disable All Active X' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 17 Ensure 'Disable All Active X' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\common\security -> disableallactivex -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\common\security -> !disableallactivex; +# +# +#19a Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Excel +[ACSC - Microsoft Office 2016 - 19a Ensure'Block all unmanaged add-ins' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency -> restricttolist -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency -> !restricttolist; +# +# +#19b Ensure 'List of managed add-ins' is set to 'Enabled' for Excel +[ACSC - Microsoft Office 2016 - 19b Ensure 'List of managed add-ins' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency\addinlist -> policyon -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency\addinlist -> !policyon; +# +# +#19c Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Excel +[ACSC - Microsoft Office 2016 - 19c Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency -> restricttolist -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency -> !restricttolist; +# +# +#19d Ensure 'List of managed add-ins' is set to 'Enabled' for PowerPoint +[ACSC - Microsoft Office 2016 - 19d Ensure 'List of managed add-ins' is set to 'Enabled' for PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency\addinlist -> policyon -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency\addinlist -> !policyon; +# +# +#19e Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Word +[ACSC - Microsoft Office 2016 - 19e Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency -> restricttolist -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency -> !restricttolist; +# +# +#19f Ensure 'List of managed add-ins' is set to 'Enabled' for Word +[ACSC - Microsoft Office 2016 - 19f Ensure 'List of managed add-ins' is set to 'Enabled' for Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency\addinlist -> policyon -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency\addinlist -> !policyon; +# +# +#21 Ensure if Extension Hardening functionality in Microsoft Excel is enabled +[ACSC - Microsoft Office 2016 - 21 Ensure if Extension Hardening functionality in Microsoft Excel is enabled] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security -> extensionhardening -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security -> !extensionhardening; +# +# +#23a Ensure dBase III / IV files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23a Ensure dBase III / IV files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> dbasefiles -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !dbasefiles; +# +# +#23b Ensure Dif and Sylk files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23b Ensure Dif and Sylk files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> difandsylkfiles -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !difandsylkfiles; +# +# +#23c Ensure Excel 2 macrosheets and add-in files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23c Ensure Excel 2 macrosheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl2macros -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl2macros; +# +# +#23d Ensure Excel 2 worksheets are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23d Ensure Excel 2 worksheets are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl2worksheets -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl2worksheets; +# +# +#23e Ensure Excel 3 macrosheets and add-in files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23e Ensure Excel 3 macrosheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl3macros -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl3macros; +# +# +#23f Ensure Excel 3 worksheets and add-in files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23f Ensure Excel 3 worksheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl3worksheets -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl3worksheets; +# +# +#23g Ensure Excel 4 macrosheets and add-in files are blocked in Microsoft Escel +[ACSC - Microsoft Office 2016 - 23g Ensure Excel 4 macrosheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl4macros -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl4macros; +# +# +#23h Ensure Excel 4 workbooks are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23h Ensure Excel 4 workbooks are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl4workbooks -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl4workbooks; +# +# +#23i Ensure Excel 4 worksheets are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23i Ensure Excel 4 worksheets are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl4worksheets -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl4worksheets; +# +# +#23j Ensure Excel 95 workbooks are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23j Ensure Excel 95 workbooks are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl95workbooks -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl95workbooks; +# +# +#23k Ensure Excel 95-97 workbooks and templates are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23k Ensure Excel 95-97 workbooks and templates are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl9597workbooksandtemplates -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl9597workbooksandtemplates; +# +# +#23l Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Excel +[ACSC - Microsoft Office 2016 - l Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !openinprotectedview; +# +# +#23m Ensure Web pages and Excel 2003 XML spreadsheets are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23m Ensure Web pages and Excel 2003 XML spreadsheets are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> htmlandxmlssfiles -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !htmlandxmlssfiles; +# +# +#23n Ensure PowerPoint beta converters are blocked in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 23n Ensure PowerPoint beta converters are blocked in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> powerpoint12betafilesfromconverters -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> !powerpoint12betafilesfromconverters; +# +# +#23o Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Powerpoint +[ACSC - Microsoft Office 2016 - 23o Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Powerpoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> !openinprotectedview; +# +# +#23p Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Word +[ACSC - Microsoft Office 2016 - 23p Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !openinprotectedview; +# +# +#23q Ensure Word 2 and earlier binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23q Ensure Word 2 and earlier binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word2files -> !2; +# +# +#23r Ensure Word 6.0 binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23r Ensure Word 6.0 binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word60files -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !word60files; +# +# +#23s Ensure Word 95 binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23s Ensure Word 95 binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word95files -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !word95files; +# +# +#23t Ensure Word 97 binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23t Ensure Word 97 binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word97files -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !word97files; +# +# +#25a Ensure Make hidden markup visible is set to 'Enabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 25a Ensure Make hidden markup visible is set to 'Enabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\options -> markupopensave -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\options -> !markupopensave; +# +# +#25b Ensure Make hidden markup visible is set to 'Enabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 25b Ensure Make hidden markup visible is set to 'Enabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\options -> showmarkupopensave -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\options -> !showmarkupopensave; +# +# +#27a Ensure Turn off error reporting for files that fail file validation is set to 'Enabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 27a Ensure Turn off error reporting for files that fail file validation is set to 'Enabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\security\filevalidation -> disablereporting -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\security\filevalidation -> !disablereporting; +# +# +#27b Ensure Turn off file validation ins set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 27b Ensure Turn off file validation ins set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> enableonload -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> !enableonload; +# +# +#27c Ensure Turn off file validation ins set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 27c Ensure Turn off file validation ins set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> enableonload -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> !enableonload; +# +# +#27d Ensure Turn off file validation ins set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 27d Ensure Turn off file validation ins set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> enableonload -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> !enableonload; +# +# +#29a Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29a Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> disableinternetfilesinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> !disableinternetfilesinpv; +# +# +#29b Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29b Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> disableunsafelocationsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> !disableunsafelocationsinpv; +# +# +#29c Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29c Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> !openinprotectedview; +# +# +#29d Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29d Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> disableattachmentsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> !disableattachmentsinpv; +# +# +#29e Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29e Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> disableinternetfilesinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> !disableinternetfilesinpv; +# +# +#29f Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29f Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> disableunsafelocationsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> !disableunsafelocationsinpv; +# +# +#29g Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29g Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> !openinprotectedview; +# +# +#29h Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29h Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> disableattachmentsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> !disableattachmentsinpv; +# +# +#29i Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 29i Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableinternetfilesinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableinternetfilesinpv; +# +# +#29j Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 29j Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableunsafelocationsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> !disableunsafelocationsinpv; +# +# +#29k Ensure Set document behaviour if file validation fails is set to 'Enable' (Block files) in Microsoft Word +[ACSC - Microsoft Office 2016 - 29k Ensure Set document behaviour if file validation fails is set to 'Enable' (Block files) in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> !openinprotectedview; +# +# +#29l Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 29l Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableattachmentsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> !disableattachmentsinpv; +# +# +#31a Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 31a Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> disabletrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> !disabletrusteddocuments; +# +# +#31b Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 31b Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> disablenetworktrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> !disablenetworktrusteddocuments; +# +# +#31c Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Powerpoint +[ACSC - Microsoft Office 2016 - 31c Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Powerpoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> disabletrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> !disabletrusteddocuments; +# +# +#31d Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Powerpoint +[ACSC - Microsoft Office 2016 - 31d Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Powerpoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> disablenetworktrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> !disablenetworktrusteddocuments; +# +# +#31e Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 31e Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> disabletrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> !disabletrusteddocuments; +# +# +#31f Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 31f Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> disablenetworktrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> !disablenetworktrusteddocuments; +# +# +#34a Ensure Allow including screenshot with Office Feedback is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34a Ensure Allow including screenshot with Office Feedback is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> includescreenshot -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> !includescreenshot; +# +# +#34b Ensure Automatically receive small updates to improve reliability is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34b Ensure Automatically receive small updates to improve reliability is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> updatereliabilitydata -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> !updatereliabilitydata; +# +# +#34c Ensure Disable Opt-in Wizard on first run is set to 'Enabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34c Ensure Disable Opt-in Wizard on first run is set to 'Enabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\general -> shownfirstrunoptin -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\general -> !shownfirstrunoptin; +# +# +#34d Ensure Enable Customer Experience Improvement Program is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34d Ensure Enable Customer Experience Improvement Program is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> qmenable -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> !qmenable; +# +# +#34e Ensure Page Send Office Feedback is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34e Ensure Page Send Office Feedback is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> enabled -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> !enabled; +# +# +#34f Ensure Send personal information is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34f Ensure Send personal information is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> sendcustomerdata -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> !sendcustomerdata; +# +# +# diff --git a/openarmor-rules/shared/cis_apache2224_rcl.txt b/openarmor-rules/shared/cis_apache2224_rcl.txt new file mode 100644 index 000000000..aa3c92126 --- /dev/null +++ b/openarmor-rules/shared/cis_apache2224_rcl.txt @@ -0,0 +1,505 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Apache Https Server +# Based on Center for Internet Security Benchmark for Apache HttpSserver 2.4 v1.3.1 and Apache HttpsServer 2.2 v3.4.1 (https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308) +# +# +$main-conf=/etc/apache2/apache2.conf,/etc/httpd/conf/httpd.conf; +$conf-dirs=/etc/apache2/conf-enabled,/etc/apache2/mods-enabled,/etc/apache2/sites-enabled,/etc/httpd/conf.d,/etc/httpd/modsecurity.d; +$ssl-confs=/etc/apache2/mods-enabled/ssl.conf,/etc/httpd/conf.d/ssl.conf; +$mods-en=/etc/apache2/mods-enabled; +$request-confs=/etc/httpd/conf/httpd.conf,/etc/apache2/mods-enabled/reqtimeout.conf; +$traceen=/etc/apache2/apache2.conf,/etc/httpd/conf/httpd.conf,/etc/apache2/conf-enabled/security.conf; +# +# +#2.3 Disable WebDAV Modules +[CIS - Apache Configuration - 2.3: WebDAV Modules are enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sdav; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sdav; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sdav; +d:$mods-en -> dav.load; +# +# +#2.4 Disable Status Module +[CIS - Apache Configuration - 2.4: Status Module is enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sstatus; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sstatus; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sstatus; +d:$mods-en -> status.load; +# +# +#2.5 Disable Autoindex Module +[CIS - Apache Configuration - 2.5: Autoindex Module is enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sautoindex; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sautoindex; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sautoindex; +d:$mods-en -> autoindex.load; +# +# +#2.6 Disable Proxy Modules +[CIS - Apache Configuration - 2.6: Proxy Modules are enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sproxy; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sproxy; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sproxy; +d:$mods-en -> proxy.load; +# +# +#2.7 Disable User Directories Modules +[CIS - Apache Configuration - 2.7: User Directories Modules are enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\suserdir; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\suserdir; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\suserdir; +d:$mods-en -> userdir.load; +# +# +#2.8 Disable Info Module +[CIS - Apache Configuration - 2.8: Info Module is enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sinfo; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sinfo; +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sinfo; +d:$mods-en -> info.load; +# +# +#3.2 Give the Apache User Account an Invalid Shell +[CIS - Apache Configuration - 3.2: Apache User Account has got a valid shell] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/passwd -> r:/var/www && !r:\.*/bin/false$|/sbin/nologin$; +# +# +#3.3 Lock the Apache User Account +[CIS - Apache Configuration - 3.3: Lock the Apache User Account] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/shadow -> r:^daemon|^wwwrun|^www-data|^apache && !r:\p!\.*$; +# +# +#4.4 Restrict Override for All Directories +[CIS - Apache Configuration - 4.4: Restrict Override for All Directories] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && !r:\w+ && r:allowoverride && !r:none$; +d:$conf-dirs -> conf -> !r:^# && !r:\w+ && r:allowoverridelist; +f:$main-conf -> !r:^# && !r:\w+ && r:allowoverride && !r:none$; +f:$main-conf -> !r:^# && !r:\w+ && r:allowoverridelist; +# +# +#5.3 Minimize Options for Other Directories +[CIS - Apache Configuration - 5.3: Minimize Options for other directories] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:options\sincludes; +f:$main-conf -> !r:^# && r:options\sincludes; +# +# +#5.4.1 Remove default index.html sites +[CIS - Apache Configuration - 5.4.1: Remove default index.html sites] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/var/www -> index.html; +d:/var/www/html -> index.html; +# +# +#5.4.2 Remove the Apache user manual +[CIS - Apache Configuration - 5.4.2: Remove the Apache user manual] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/etc/httpd/conf.d -> manual.conf; +d:/etc/apache2/conf-enabled -> apache2-doc.conf; +# +# +#5.4.5 Verify that no Handler is enabled +[CIS - Apache Configuration - 5.4.5: A Handler is configured] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:/wsethandler; +f:$main-conf -> !r:^# && r:/wsethandler; +# +# +#5.5 Remove default CGI content printenv +[CIS - Apache Configuration - 5.5: Remove default CGI content printenv] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/var/www/cgi-bin -> printenv; +d:/usr/lib/cgi-bin -> printenv; +# +# +#5.6 Remove default CGI content test-cgi +[CIS - Apache Configuration - 5.6: Remove default CGI content test-cgi] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/var/www/cgi-bin -> test-cgi; +d:/usr/lib/cgi-bin -> test-cgi; +# +# +#5.7 Limit HTTP Request Method +[CIS - Apache Configuration - 5.7: Disable HTTP Request Method] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:; +# +# +#5.8 Disable HTTP Trace Method +[CIS - Apache Configuration - 5.8: Disable HTTP Trace Method] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$traceen -> !r:^# && r:traceenable\s+on\s*$; +# +# +#5.9 Restrict HTTP Protocol Versions +[CIS - Apache Configuration - 5.9: Restrict HTTP Protocol Versions] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:loadmodule\srewrite; +d:$mods-en -> !f:rewrite.load; +f:$main-conf -> !r:rewriteengine\son; +f:$main-conf -> !r:rewritecond && !r:%{THE_REQUEST} && !r:!HTTP/1\\.1\$; +f:$main-conf -> !r:rewriterule && !r:.* - [F]; +# +# +#5.12 Deny IP Address Based Requests +[CIS - Apache Configuration - 5.12: Deny IP Address Based Requests] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:loadmodule\srewrite; +d:$mods-en -> !f:rewrite.load; +f:$main-conf -> !r:rewriteengine\son; +f:$main-conf -> !r:rewritecond && !r:%{HTTP_HOST} && !r:www\\.\w+\\.\w+ [NC]$; +f:$main-conf -> !r:rewritecond && !r:%{REQUEST_URI} && !r:/error [NC]$; +f:$main-conf -> !r:rewriterule && !r:.\(.*\) - [L,F]$; +# +# +#5.13 Restrict Listen Directive +[CIS - Apache Configuration - 5.13: Restrict Listen Directive] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:listen\s80$; +d:$conf-dirs -> conf -> !r:^# && r:listen\s0.0.0.0\p80; +d:$conf-dirs -> conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p80; +f:$main-conf -> !r:^# && r:listen\s80$; +f:$main-conf -> !r:^# && r:listen\s0.0.0.0\p\d*; +f:$main-conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p\d*; +f:/etc/apache2/sites-enabled/000-default.conf -> !r:^# && r:listen\s80$; +f:/etc/apache2/sites-enabled/000-default.conf -> !r:^# && r:listen\s0.0.0.0\p\d*; +f:/etc/apache2/sites-enabled/000-default.conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p\d*; +f:/etc/apache2/ports.conf -> !r:^# && r:listen\s80$; +f:/etc/apache2/ports.conf -> !r:^# && r:listen\s0.0.0.0\p\d*; +f:/etc/apache2/ports.conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p\d*; +# +# +#5.14 Restrict Browser Frame Options +[CIS - Apache Configuration - 5.14: Restrict Browser Frame Options] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:header\salways\sappend\sx-frame-options && !r:sameorigin|deny; +# +# +#6.1 Configure the Error Log to notice at least +[CIS - Apache Configuration - 6.1: Configure the Error Log to notice at least] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^# && r:loglevel\snotice\score\p && r:warn|emerg|alert|crit|error|notice; +f:$main-conf -> !r:loglevel\snotice\score\p && !r:info|debug; +# +# +#6.2 Configure a Syslog facility for Error Log +[CIS - Apache Configuration - 6.2: Configure a Syslog facility for Error Log] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:errorlog\s+\p*syslog\p\.*\p*; +# +# +#7.6 Disable SSL Insecure Renegotiation +[CIS - Apache Configuration - 7.6: Disable SSL Insecure Renegotiation] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$ssl-confs -> !r:^\t*\s*# && r:sslinsecurerenegotiation\s+on\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslinsecurerenegotiation\s*$; +# +# +#7.7 Ensure SSL Compression is not enabled +[CIS - Apache Configuration - 7.7: Ensure SSL Compression is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$ssl-confs -> !r:^\t*\s*# && r:sslcompression\s+on\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslcompression\s*$; +# +# +#7.8 Disable SSL TLS v1.0 Protocol +[CIS - Apache Configuration - 7.8: Disable insecure TLS Protocol] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$ssl-confs -> !r:^\t*\s*sslprotocol; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+all; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+\.*tlsv1\P\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+\.*sslv2\P\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+\.*sslv3\P\s*; +# +# +#7.9 Enable OCSP Stapling +[CIS - Apache Configuration - 7.9: Enable OCSP Stapling] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:^loadmodule\s+ssl; +d:$mods-en -> !f:ssl.load; +f:$ssl-confs -> !r:\t*\s*# && r:sslusestapling\s+off; +f:$ssl-confs -> !r:\t*\s*sslusestapling\s+on; +f:$ssl-confs -> !r:\t*\s*sslstaplingcache\s+\.+; +# +# +#7.10 Enable HTTP Strict Transport Security +[CIS - Apache Configuration - 7.10: Enable HTTP Strict Transport Security] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/apache2/apache2.conf -> !r:Header\salways\sset\sStrict-Transport-Security\s"max-age=\d\d\d\d*"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=1\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=2\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=3\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=4\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=5\d\d"; +# +# +#8.1 Set ServerToken to Prod or ProductOnly +[CIS - Apache Configuration - 8.1: Set ServerToken to Prod or ProductOnly] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+major; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+minor; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+min; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+minimal; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+os; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+full; +# +# +#8.2: Set ServerSignature to Off +[CIS - Apache Configuration - 8.2: Set ServerSignature to Off] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:serversignature\s+email; +d:$conf-dirs -> conf -> !r:^# && r:serversignature\s+on; +# +# +#8.3: Prevent Information Leakage via Default Apache Content +[CIS - Apache Configuration - 8.3: Prevent Information Leakage via Default Apache Content] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^\t*\s*# && r:include\s*\w*httpd-autoindex.conf; +d:$conf-dirs -> conf -> !r:^\t*\s*# && r:alias\s*/icons/\s*\.*; +# +# +#9.1:Set TimeOut to 10 or less +[CIS - Apache Configuration - 9.1: Set TimeOut to 10 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^# && r:timeout\s+9\d; +f:$main-conf -> !r:^# && r:timeout\s+8\d; +f:$main-conf -> !r:^# && r:timeout\s+7\d; +f:$main-conf -> !r:^# && r:timeout\s+6\d; +f:$main-conf -> !r:^# && r:timeout\s+5\d; +f:$main-conf -> !r:^# && r:timeout\s+4\d; +f:$main-conf -> !r:^# && r:timeout\s+3\d; +f:$main-conf -> !r:^# && r:timeout\s+2\d; +f:$main-conf -> !r:^# && r:timeout\s+11; +f:$main-conf -> !r:^# && r:timeout\s+12; +f:$main-conf -> !r:^# && r:timeout\s+13; +f:$main-conf -> !r:^# && r:timeout\s+14; +f:$main-conf -> !r:^# && r:timeout\s+15; +f:$main-conf -> !r:^# && r:timeout\s+16; +f:$main-conf -> !r:^# && r:timeout\s+17; +f:$main-conf -> !r:^# && r:timeout\s+18; +f:$main-conf -> !r:^# && r:timeout\s+19; +f:$main-conf -> !r:^timeout\s+\d\d*; +f:$main-conf -> !r:^# && r:timeout\s+\d\d\d+; +# +# +#9.2:Set the KeepAlive directive to On +[CIS - Apache Configuration - 9.2: Set the KeepAlive directive to On] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^# && r:keepalive\s+off; +f:$main-conf -> !r:keepalive\s+on; +# +# +#9.3:Set MaxKeepAliveRequests to 100 or greater +[CIS - Apache Configuration - 9.3: Set MaxKeepAliveRequest to 100 or greater] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^maxkeepaliverequests\s+\d\d\d+; +# +# +#9.4: Set KeepAliveTimeout Low to Mitigate Denial of Service +[CIS - Apache Configuration - 9.4: Set KeepAliveTimeout Low] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:keepalivetimeout\s+\d\d*; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+16; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+17; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+18; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+19; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+2\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+3\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+4\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+5\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+6\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+7\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+8\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+9\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+\d\d\d+; +# +# +#9.5 Set Timeout Limits for Request Headers +[CIS - Apache Configuration - 9.5: Set Timeout Limits for Request Headers] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:^loadmodule\s+reqtimeout; +d:$mods-en -> !f:reqtimeout.load; +f:$request-confs -> !r:^\t*\s*requestreadtimeout\.+header\p\d\d*\D\d\d*; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D41; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D42; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D43; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D44; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D45; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D46; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D47; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D48; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D49; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D5\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D6\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D7\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D8\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D9\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D\d\d\d+; +# +# +#9.6 Set Timeout Limits for Request Body +[CIS - Apache Configuration - 9.6: Set Timeout Limits for Request Body] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:^loadmodule\s+reqtimeout; +d:$mods-en -> !f:reqtimeout.load; +f:$request-confs -> !r:\t*\s*requestreadtimeout\.+body\p\d\d*; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p21; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p22; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p23; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p24; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p25; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p26; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p27; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p28; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p29; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p3\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p4\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p5\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p6\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p7\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p8\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p9\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p\d\d\d+; +# +# +#10.1 Set the LimitRequestLine directive to 512 or less +[CIS - Apache Configuration - 10.1: Set LimitRequestLine to 512 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestline\s+\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\13; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\14; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\15; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\16; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\17; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\18; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\19; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\2\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\3\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\4\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\5\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\6\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\7\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\8\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\9\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+6\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+7\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+8\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+9\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+\d\d\d\d+; +# +# +#10.2 Set the LimitRequestFields directive to 100 or less +[CIS - Apache Configuration - 10.2: Set LimitRequestFields to 100 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestfields\s\d\d*; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d1; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d2; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d3; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d4; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d5; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d6; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d7; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d8; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d9; +f:$main-conf -> !r:^# && r:limitrequestfields\s+11\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+12\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+13\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+14\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+15\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+16\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+17\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+18\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+19\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+2\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+3\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+4\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+5\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+6\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+7\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+8\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+9\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+\d\d\d\d+; +# +# +#10.3 Set the LimitRequestFieldsize directive to 1024 or less +[CIS - Apache Configuration - 10.3: Set LimitRequestFieldsize to 1024 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestfieldsize\s+\d\d*; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d25; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d26; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d27; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d28; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d29; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d3\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d4\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d5\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d6\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d7\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d8\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d9\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+11\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+12\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+13\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+14\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+15\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+16\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+17\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+18\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+19\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+2\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+3\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+4\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+5\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+6\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+7\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+8\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+9\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+\d\d\d\d\d+; +# +# +#10.4 Set the LimitRequestBody directive to 102400 or less +[CIS - Apache Configuration - 10.4: Set LimitRequestBody to 102400 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestbody\s+\d\d*; +f:$main-conf -> !r:^# && r:limitrequestbody\s+0\s*$; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d1; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d2; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d3; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d4; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d5; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d6; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d7; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d8; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d9; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d241\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d242\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d243\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d244\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d245\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d246\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d247\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d248\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d249\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d25\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d26\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d27\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d28\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d29\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d3\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d4\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d5\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d6\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d7\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d8\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d9\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+11\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+12\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+13\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+14\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+15\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+16\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+17\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+18\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+19\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+2\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+3\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+4\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+5\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+6\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+7\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+8\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+9\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+\d\d\d\d\d\d\d+; diff --git a/openarmor-rules/shared/cis_debian_linux_rcl.txt b/openarmor-rules/shared/cis_debian_linux_rcl.txt new file mode 100644 index 000000000..949fd4fe1 --- /dev/null +++ b/openarmor-rules/shared/cis_debian_linux_rcl.txt @@ -0,0 +1,196 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Debian/Ubuntu +# Based on Center for Internet Security Benchmark for Debian Linux v1.0 + +# Main one. Only valid for Debian/Ubuntu. +[CIS - Testing against the CIS Debian Linux Benchmark v1.0] [all required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/debian_version; +f:/proc/sys/kernel/ostype -> Linux; + + +# Section 1.4 - Partition scheme. +[CIS - Debian Linux - 1.4 - Robust partition scheme - /tmp is not on its own partition {CIS: 1.4 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +[CIS - Debian Linux - 1.4 - Robust partition scheme - /opt is not on its own partition {CIS: 1.4 Debian Linux}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/opt; +f:/etc/fstab -> !r:/opt; + +[CIS - Debian Linux - 1.4 - Robust partition scheme - /var is not on its own partition {CIS: 1.4 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:/var; + + +# Section 2.3 - SSH configuration +[CIS - Debian Linux - 2.3 - SSH Configuration - Protocol version 1 enabled {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +[CIS - Debian Linux - 2.3 - SSH Configuration - IgnoreRHosts disabled {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +[CIS - Debian Linux - 2.3 - SSH Configuration - Empty passwords permitted {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +[CIS - Debian Linux - 2.3 - SSH Configuration - Host based authentication enabled {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +[CIS - Debian Linux - 2.3 - SSH Configuration - Root login allowed {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + + +# Section 2.4 Enable system accounting +#[CIS - Debian Linux - 2.4 - System Accounting - Sysstat not installed {CIS: 2.4 Debian Linux}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +#f:!/etc/default/sysstat; +#f:!/var/log/sysstat; + +#[CIS - Debian Linux - 2.4 - System Accounting - Sysstat not enabled {CIS: 2.4 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +#f:!/etc/default/sysstat; +#f:/etc/default/sysstat -> !r:^# && r:ENABLED="false"; + + +# Section 2.5 Install and run Bastille +#[CIS - Debian Linux - 2.5 - System harderning - Bastille is not installed {CIS: 2.5 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +#f:!/etc/Bastille; + + +# Section 2.6 Ensure sources.list Sanity +[CIS - Debian Linux - 2.6 - Sources list sanity - Security updates not enabled {CIS: 2.6 Debian Linux} {PCI_DSS: 6.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:!/etc/apt/sources.list; +f:!/etc/apt/sources.list -> !r:^# && r:http://security.debian|http://security.ubuntu; + + +# Section 3 - Minimize inetd services +[CIS - Debian Linux - 3.3 - Telnet enabled on inetd {CIS: 3.3 Debian Linux} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:telnet; + +[CIS - Debian Linux - 3.4 - FTP enabled on inetd {CIS: 3.4 Debian Linux} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:/ftp; + +[CIS - Debian Linux - 3.5 - rsh/rlogin/rcp enabled on inetd {CIS: 3.5 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:shell|login; + +[CIS - Debian Linux - 3.6 - tftpd enabled on inetd {CIS: 3.6 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:tftp; + +[CIS - Debian Linux - 3.7 - imap enabled on inetd {CIS: 3.7 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:imap; + +[CIS - Debian Linux - 3.8 - pop3 enabled on inetd {CIS: 3.8 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:pop; + +[CIS - Debian Linux - 3.9 - Ident enabled on inetd {CIS: 3.9 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:ident; + + +# Section 4 - Minimize boot services +[CIS - Debian Linux - 4.1 - Disable inetd - Inetd enabled but no services running {CIS: 4.1 Debian Linux} {PCI_DSS: 2.2.2}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +p:inetd; +f:!/etc/inetd.conf -> !r:^# && r:wait; + +[CIS - Debian Linux - 4.3 - GUI login enabled {CIS: 4.3 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +[CIS - Debian Linux - 4.6 - Disable standard boot services - Samba Enabled {CIS: 4.6 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/samba; + +[CIS - Debian Linux - 4.7 - Disable standard boot services - NFS Enabled {CIS: 4.7 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/nfs-common; +f:/etc/init.d/nfs-user-server; +f:/etc/init.d/nfs-kernel-server; + +[CIS - Debian Linux - 4.9 - Disable standard boot services - NIS Enabled {CIS: 4.9 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/nis; + +[CIS - Debian Linux - 4.13 - Disable standard boot services - Web server Enabled {CIS: 4.13 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/apache; +f:/etc/init.d/apache2; + +[CIS - Debian Linux - 4.15 - Disable standard boot services - DNS server Enabled {CIS: 4.15 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/bind; + +[CIS - Debian Linux - 4.16 - Disable standard boot services - MySQL server Enabled {CIS: 4.16 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/mysql; + +[CIS - Debian Linux - 4.16 - Disable standard boot services - PostgreSQL server Enabled {CIS: 4.16 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/postgresql; + +[CIS - Debian Linux - 4.17 - Disable standard boot services - Webmin Enabled {CIS: 4.17 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/webmin; + +[CIS - Debian Linux - 4.18 - Disable standard boot services - Squid Enabled {CIS: 4.18 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/squid; + + +# Section 5 - Kernel tuning +[CIS - Debian Linux - 5.1 - Network parameters - Source routing accepted {CIS: 5.1 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +[CIS - Debian Linux - 5.1 - Network parameters - ICMP broadcasts accepted {CIS: 5.1 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +[CIS - Debian Linux - 5.2 - Network parameters - IP Forwarding enabled {CIS: 5.2 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + + +# Section 7 - Permissions +[CIS - Debian Linux - 7.1 - Partition /var without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/var && !r:nodev; + +[CIS - Debian Linux - 7.1 - Partition /tmp without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/tmp && !r:nodev; + +[CIS - Debian Linux - 7.1 - Partition /opt without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/opt && !r:nodev; + +[CIS - Debian Linux - 7.1 - Partition /home without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/home && !r:nodev ; + +[CIS - Debian Linux - 7.2 - Removable partition /media without 'nodev' set {CIS: 7.2 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +[CIS - Debian Linux - 7.2 - Removable partition /media without 'nosuid' set {CIS: 7.2 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +[CIS - Debian Linux - 7.3 - User-mounted removable partition /media {CIS: 7.3 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && r:user; + + +# Section 8 - Access and authentication +[CIS - Debian Linux - 8.8 - LILO Password not set {CIS: 8.8 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/lilo.conf -> !r:^# && !r:restricted; +f:/etc/lilo.conf -> !r:^# && !r:password=; + +[CIS - Debian Linux - 8.8 - GRUB Password not set {CIS: 8.8 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +[CIS - Debian Linux - 9.2 - Account with empty password present {CIS: 9.2 Debian Linux} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - Debian Linux - 13.11 - Non-root account with uid 0 {CIS: 13.11 Debian Linux} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + diff --git a/openarmor-rules/shared/cis_debianlinux7-8_L1_rcl.txt b/openarmor-rules/shared/cis_debianlinux7-8_L1_rcl.txt new file mode 100644 index 000000000..ed885dbce --- /dev/null +++ b/openarmor-rules/shared/cis_debianlinux7-8_L1_rcl.txt @@ -0,0 +1,686 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# Level 1 CIS Checks for Debian Linux 7 and Debian Linux 8 +# Based on Center for Internet Security Benchmark v1.0.0 for Debian Linux 7 (https://workbench.cisecurity.org/benchmarks/80) and Benchmark v1.0.0 for Debian Linux 8 (https://workbench.cisecurity.org/benchmarks/81) +# +$rc_dirs=/etc/rc0.d,/etc/rc1.d,/etc/rc2.d,/etc/rc3.d,/etc/rc4.d,/etc/rc5.d,/etc/rc6.d,/etc/rc7.d,/etc/rc8.d,/etc/rc9.d,/etc/rca.d,/etc/rcb.d,/etc/rcc.d,/etc/rcs.d,/etc/rcS.d; +$rsyslog_files=/etc/rsyslog.conf,/etc/rsyslog.d/*; +$profiledfiles=/etc/profile.d/*; +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +# +# +#2.1 Create Separate Partition for /tmp +[CIS - Debian Linux 7/8 - 2.1 Create Separate Partition for /tmp] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp; +# +# +#2.2 Set nodev option for /tmp Partition +[CIS - Debian Linux 7/8 - 2.2 Set nodev option for /tmp Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+\w+\s+\.*nodev; +# +# +#2.3 Set nosuid option for /tmp Partition +[CIS - Debian Linux 7/8 - 2.3 Set nosuid option for /tmp Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+\w+\s+\.*nosuid; +# +# +#2.4 Set noexec option for /tmp Partition +[CIS - Debian Linux 7/8 - 2.4 Set noexec option for /tmp Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+\w+\s+\.*noexec; +# +# +#2.5 Create Separate Partition for /var +[CIS - Debian Linux 7/8 - 2.5 Create Separate Partition for /var] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/var; +# +# +#2.6 Bind Mount the /var/tmp directory to /tmp +[CIS - Debian Linux 7/8 - 2.6 Bind Mount the /var/tmp directory to /tmp] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+/var/tmp\s+none\s+\.*bind\.*0\s+0; +# +# +#2.7 Create Separate Partition for /var/log +[CIS - Debian Linux 7/8 - 2.7 Create Separate Partition for /var/log] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/var/log; +# +# +#2.8 Create Separate Partition for /var/log/audit +[CIS - Debian Linux 7/8 - 2.8 Create Separate Partition for /var/log/audit] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/var/log/audit; +# +# +#2.9 Create Separate Partition for /home +[CIS - Debian Linux 7/8 - 2.9 Create Separate Partition for /home] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/home; +# +# +#2.10 Add nodev Option to /home +[CIS - Debian Linux 7/8 - 2.10 Add nodev Option to /home] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/home\s+\w+\s+\.*nodev; +# +# +#2.11 Add nodev Option to Removable Media Partitions +[CIS - Debian Linux 7/8 - 2.11 Add nodev Option to Removable Media Partitions] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/media\.*\s+\w+\s+\.*nodev; +# +# +#2.12 Add noexec Option to Removable Media Partitions +[CIS - Debian Linux 7/8 - 2.12 Add noexec Option to Removable Media Partitions] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/media\.*\s+\w+\s+\.*noexec; +# +# +#2.13 Add nosuid Option to Removable Media Partitions +[CIS - Debian Linux 7/8 - 2.13 Add nosuid Option to Removable Media Partitions] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/media\.*\s+\w+\s+\.*nosuid; +# +# +#2.14 Add nodev Option to /run/shm Partition +[CIS - Debian Linux 7/8 - 2.14 Add nodev Option to /run/shm Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/run/shm\s+\w+\s+\.*nodev; +# +# +#2.15 Add nosuid Option to /run/shm Partition +[CIS - Debian Linux 7/8 - 2.15 Add nosuid Option to /run/shm Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/run/shm\s+\w+\s+\.*nosuid; +# +# +#2.16 Add noexec Option to /run/shm Partition +[CIS - Debian Linux 7/8 - 2.16 Add noexec Option to /run/shm Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/run/shm\s+\w+\s+\.*noexec; +# +# +#2.25 Disable Automounting +[CIS - Debian Linux 7/8 - 2.25 Disable Automounting] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:autofsc; +# +# +#3.3 Set Boot Loader Password +[CIS - Debian Linux 7/8 - 3.3 Set Boot Loader Password] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/boot/grub/grub.cfg -> !r:^set superusers; +f:/boot/grub/grub.cfg -> !r:^password; +f:/etc/grub.d -> !r:^set superusers; +f:/etc/grub.d -> !r:^password; +# +# +#3.4 Require Authentication for Single-User Mode +[CIS - Debian Linux 7/8 - 3.4 Require Authentication for Single-User Mode] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/shadow -> r:^root:!:; +f:/etc/shadow -> r:^root:*:; +f:/etc/shadow -> r:^root:*!:; +f:/etc/shadow -> r:^root:!*:; +# +# +#4.1 Restrict Core Dumps +[CIS - Debian Linux 7/8 - 4.1 Restrict Core Dumps] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/security/limits.conf -> !r:^* hard core 0; +f:/etc/sysctl.conf -> !r:^fs.suid_dumpable = 0; +# +# +#4.3 Enable Randomized Virtual Memory Region Placement +[CIS - Debian Linux 7/8 - 4.3 Enable Randomized Virtual Memory Region Placement] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^kernel.randomize_va_space = 2; +# +# +#5.1.1 Ensure NIS is not installed +[CIS - Debian Linux 7/8 - 5.1.1 Ensure NIS is not installed] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/init.d/nis; +# +# +#5.1.2 Ensure rsh server is not enabled +[CIS - Debian Linux 7/8 - 5.1.2 Ensure rsh server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:shell|login|exec; +# +# +#5.1.4 Ensure talk server is not enabled +[CIS - Debian Linux 7/8 - 5.1.4 Ensure talk server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:talk|ntalk; +# +# +#5.1.6 Ensure telnet server is not enabled +[CIS - Debian Linux 7/8 - 5.1.6 Ensure telnet server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:telnet; +# +# +#5.1.7 Ensure tftp-server is not enabled +[CIS - Debian Linux 7/8 - 5.1.7 Ensure tftp-server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:tftp; +# +# +#5.1.8 Ensure xinetd is not enabled +[CIS - Debian Linux 7/8 - 5.1.8 Ensure xinetd is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:xinetd; +# +# +#5.2 Ensure chargen is not enabled +[CIS - Debian Linux 7/8 - 5.2 Ensure chargen is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:chargen; +# +# +#5.3 Ensure daytime is not enabled +[CIS - Debian Linux 7/8 - 5.3 Ensure daytime is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:daytime; +# +# +#5.4 Ensure echo is not enabled +[CIS - Debian Linux 7/8 - 5.4 Ensure echo is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:echo; +# +# +#5.5 Ensure discard is not enabled +[CIS - Debian Linux 7/8 - 5.5 Ensure discard is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:discard; +# +# +#5.6 Ensure time is not enabled +[CIS - Debian Linux 7/8 - 5.6 Ensure time is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:time; +# +# +#6.2 Ensure Avahi Server is not enabled +[CIS - Debian Linux 7/8 - 6.2 Ensure Avahi Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:avahi-daemon; +# +# +#6.3 Ensure print server is not enabled +[CIS - Debian Linux 7/8 - 6.3 Ensure print server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:cups; +d:$rc_dirs -> S -> r:cups-browsed; +# +# +#6.4 Ensure DHCP Server is not enabled +[CIS - Debian Linux 7/8 - 6.4 Ensure DHCP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:disc-dhcp-server; +# +# +#6.5 Configure Network Time Protocol (NTP) +[CIS - Debian Linux 7/8 - 6.5 Configure Network Time Protocol (NTP)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ntp.conf -> !r:^restrict -4 default kod nomodify notrap nopeer noquery; +f:/etc/ntp.conf -> !r:^restrict -6 default kod nomodify notrap nopeer noquery; +f:/etc/ntp.conf -> !r:^server\s\.+; +# +# +#6.6 Ensure LDAP is not ennabled +[CIS - Debian Linux 7/8 - 6.6 Ensure LDAP is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:/etc/init.d -> r:ldap; +# +# +#6.7 Ensure NFS and RPC are not enabled +[CIS - Debian Linux 7/8 - 6.7 Ensure NFS and RPC are not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:rpcbind; +d:$rc_dirs -> S -> r:nfs-kernel-server; +# +# +#6.8 Ensure DNS Server is not enabled +[CIS - Debian Linux 7/8 - 6.8 Ensure DNS Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:bind9; +# +# +#6.9 Ensure FTP Server is not enabled +[CIS - Debian Linux 7/8 - 6.9 Ensure FTP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:vsftpd; +# +# +#6.10 Ensure HTTP Server is not enabled +[CIS - Debian Linux 7/8 - 6.10 Ensure HTTP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:apache2; +# +# +#6.11 Ensure IMAP and POP server is not enabled +[CIS - Debian Linux 7/8 - 6.11 Ensure IMAP and POP server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:dovecot; +# +# +#6.12 Ensure Samba is not enabled +[CIS - Debian Linux 7/8 - 6.12 Ensure Samba is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:samba; +# +# +#6.13 Ensure HTTP Proxy Server is not enabled +[CIS - Debian Linux 7/8 - 6.13 Ensure HTTP Proxy Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:squid3; +# +# +#6.14 Ensure SNMP Server is not enabled +[CIS - Debian Linux 7/8 - 6.14 Ensure SNMP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:snmpd; +# +# +#6.15 Configure Mail Transfer Agent for Local-Only Mode +[CIS - Debian Linux 7/8 - 6.15 Configure Mail Transfer Agent for Local Only Mode] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/exim4/update-exim4.conf.conf -> r:^dc_local_interfaces= && !r:'127.0.0.1\s*\p\s*::1'$|'::1\s*\p\s*127.0.0.1'$|'127.0.0.1'$|'::1'$; +# +# +#6.16 Ensure rsync service is not enabled +[CIS - Debian Linux 7/8 - 6.16 Ensure rsync service is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/rsync -> !r:^# && r:RSYNC_ENABLE=true|inetd; +f:/etc/default/rsync -> !r:^RSYNC_ENABLE=false; +# +# +#7.1.1 Disable IP Forwarding +[CIS - Debian Linux 7/8 - 7.1.1 Disable IP Forwarding] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.ip_forward=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.ip_forward=0; +# +# +#7.1.2 Disable Send Packet Redirects +[CIS - Debian Linux 7/8 - 7.1.2 Disable Send Packet Redirects] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.send_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.send_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.send_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.send_redirects=0; +# +# +#7.2.1 Disable Source Routed Packet Acceptance +[CIS - Debian Linux 7/8 - 7.2.1 Disable Source Routed Packet Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.accept_source_route=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.accept_source_route=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.accept_source_route=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.accept_source_route=0; +# +# +#7.2.2 Disable ICMP Redirect Acceptance +[CIS - Debian Linux 7/8 - 7.2.2 Disable ICMP Redirect Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.accept_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.accept_redirects=0; +# +# +#7.2.3 Disable Secure ICMP Redirect Acceptance +[CIS - Debian Linux 7/8 - 7.2.3 Disable Secure ICMP Redirect Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.secure_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.secure_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.secure_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.secure_redirects=0; +# +# +#7.2.4 Log Suspicious Packets +[CIS - Debian Linux 7/8 - 7.2.4 Log Suspicious Packets] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.log_martians=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.log_martians=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.log_martians=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.log_martians=1; +# +# +#7.2.5 Enable Ignore Broadcast Requests +[CIS - Debian Linux 7/8 - 7.2.5 Enable Ignore Broadcast Requests] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.icmp_echo_ignore_broadcasts=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.icmp_echo_ignore_broadcasts=1; +# +# +#7.2.6 Enable Bad Error Message Protection +[CIS - Debian Linux 7/8 - 7.2.6 Enable Bad Error Message Protection] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.icmp_ignore_bogus_error_responses=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.icmp_ignore_bogus_error_responses=1; +# +# +#7.2.7 Enable RFC-recommended Source Route Validation +[CIS - Debian Linux 7/8 - 7.2.7 Enable RFC-recommended Source Route Validation] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.rp_filter=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.rp_filter=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.rp_filter=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.rp_filter=1; +# +# +#7.2.8 Enable TCP SYN Cookies +[CIS - Debian Linux 7/8 - 7.2.8 Enable TCP SYN Cookies] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.tcp_syncookies=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.tcp_syncookies=1; +# +# +#7.3.1 Disable IPv6 Router Advertisements +[CIS - Debian Linux 7/8 - 7.3.1 Disable IPv6 Router Advertisements] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.all.accept_ra=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.all.accept_ra=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.default.accept_ra=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.default.accept_ra=0; +# +# +#7.3.2 Disable IPv6 Redirect Acceptance +[CIS - Debian Linux 7/8 - 7.3.2 Disable IPv6 Redirect Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.all.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.all.accept_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.default.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.default.accept_redirects=0; +# +# +#7.3.3 Disable IPv6 +[CIS - Debian Linux 7/8 - 7.3.3 Disable IPv6] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.all.disable_ipv6=0; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.all.disable_ipv6=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.default.disable_ipv6=0; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.default.disable_ipv6=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.lo.disable_ipv6=0; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.lo.disable_ipv6=1; +# +# +#7.4.2 Create /etc/hosts.allow +[CIS - Debian Linux 7/8 - 7.4.2 Create /etc/hosts.allow] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/hosts.allow; +f:/etc/hosts.allow -> !r:^ALL:\.*; +# +# +#7.4.4 Create /etc/hosts.deny +[CIS - Debian Linux 7/8 - 7.4.4 Create /etc/hosts.deny] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/hosts.deny; +f:/etc/hosts.deny -> !r:^ALL:\s*ALL; +# +# +#7.5.1 Disable DCCP +[CIS - Debian Linux 7/8 - 7.5.1 Disable DCCP] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install dccp /bin/true; +# +# +#7.5.2 Disable SCTP +[CIS - Debian Linux 7/8 - 7.5.2 Disable SCTP] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install sctp /bin/true; +# +# +#7.5.3 Disable RDS +[CIS - Debian Linux 7/8 - 7.5.3 Disable RDS] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install rds /bin/true; +# +# +#7.5.4 Disable TIPC +[CIS - Debian Linux 7/8 - 7.5.4 Disable TIPC] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install tipc /bin/true; +# +# +#7.7 Ensure Firewall is active (RunLevel 2, 3, 4, 5; Priority 01) +[CIS - Debian Linux 7/8 - 7.7 Ensure Firewall is active (RunLevel 2, 3, 4, 5; Priority 01)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/rc2.d/S01iptables-persistent; +f:!/etc/rc3.d/S01iptables-persistent; +f:!/etc/rc4.d/S01iptables-persistent; +f:!/etc/rc5.d/S01iptables-persistent; +# +# +#8.2.2 Ensure the rsyslog Service is activated (RunLevel 2, 3, 4, 5; Priority 01) +[CIS - Debian Linux 7/8 - 8.2.2 Ensure the rsyslog Service is activated (RunLevel 2, 3, 4, 5; Priority 01)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/rc2.d/S01rsyslog; +f:!/etc/rc3.d/S01rsyslog; +f:!/etc/rc4.d/S01rsyslog; +f:!/etc/rc5.d/S01rsyslog; +# +# +#8.2.3 Configure /etc/rsyslog.conf +[CIS - Debian Linux 7/8 - 8.2.3 Configure /etc/rsyslog.conf] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:$rsyslog_files -> !r:^*.emerg\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.info\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.warning\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.err\s*\t*\s*\S; +f:$rsyslog_files -> !r:^news.crit\s*\t*\s*\S; +f:$rsyslog_files -> !r:^news.err\s*\t*\s*\S; +f:$rsyslog_files -> !r:^news.notice\s*\t*\s*\S; +f:$rsyslog_files -> !r:^*.=warning;*.=err\s*\t*\s*\S; +f:$rsyslog_files -> !r:^*.crit\s*\t*\s*\S; +f:$rsyslog_files -> !r:^*.*;mail.none;news.none\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local0,local1.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local2,local3.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local4,local5.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local6,local7.*\s*\t*\s*\S; +# +# +#8.2.5 Configure rsyslog to Send Logs to a Remote Log Host +[CIS - Debian Linux 7/8 - 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/rsyslog.conf -> !r:^*.* @@\w+.\w+.\w+; +# +# +#8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts +[CIS - Debian Linux 7/8 - 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:$rsyslog_files -> !r:^\$ModLoad imtcp.so; +f:$rsyslog_files -> !r:^\$InputTCPServerRun 514; +# +# +#8.4 Configure logrotate +[CIS - Debian Linux 7/8 - 8.4 Configure logrotate] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/logrotate.d/rsyslog; +f:/etc/logrotate.d/rsyslog -> !r:\S+; +# +# +#9.1.1 Enable cron Daemon (RunLevel 2, 3, 4, 5; Priority 15) +[CIS - Debian Linux 7/8 - 9.1.1 Enable cron Daemon (RunLevel 2, 3, 4, 5; Priority 15)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/rc2.d/S15anacron; +f:!/etc/rc2.d/S15cron; +f:!/etc/rc3.d/S15anacron; +f:!/etc/rc3.d/S15cron; +f:!/etc/rc4.d/S15anacron; +f:!/etc/rc4.d/S15cron; +f:!/etc/rc5.d/S15anacron; +f:!/etc/rc5.d/S15cron; +# +# +#9.1.8 Restrict at/cron to Authorized Users +[CIS - Debian Linux 7/8 - 9.1.8 Restrict at/cron to Authorized Users] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/cron.allow; +f:!/etc/at.allow; +# +# +#9.2.1 Set Password Creation Requirement Parameters Using pam_cracklib +[CIS - Debian Linux 7/8 - 9.2.1 Set Password Creation Requirement Parameters Using pam_cracklib] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/common-password -> !r:password required pam_cracklib.so retry=\d minlen=\d\d+ dcredit=-\d+ ucredit=-\d+ ocredit=-\d+ lcredit=-\d+; +# +# +#9.2.2 Set Lockout for Failed Password Attempts +[CIS - Debian Linux 7/8 - 9.2.2 Set Lockout for Failed Password Attempts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/login -> !r:auth required pam_tally2.so onerr=fail audit silent deny=\d unlock_time=\d\d\d+; +# +# +#9.2.3 Limit Password Reuse +[CIS - Debian Linux 7/8 - 9.2.3 Limit Password Reuse] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/common-password -> !r:password [success=1 default=ignore] pam_unix.so obscure sha512 remember=\d; +# +# +#9.3.1 Set SSH Protocol to 2 +[CIS - Debian Linux 7/8 - 9.3.1 Set SSH Protocol to 2] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:protocol 1; +f:/etc/ssh/sshd_config -> !r:^protocol 2$; +# +# +#9.3.2 Set LogLevel to INFO +[CIS - Debian Linux 7/8 - 9.3.2 Set LogLevel to INFO] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^LogLevel\s+INFO; +# +# +#9.3.4 Disable SSH X11 Forwarding +[CIS - Debian Linux 7/8 - 9.3.4 Disable SSH X11 Forwarding] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^X11Forwarding\s+no; +# +# +#9.3.5 Set SSH MaxAuthTries to 4 or Less +[CIS - Debian Linux 7/8 - 9.3.5 Set SSH MaxAuthTries to 4 or Less] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^MaxAuthTries\s+\d; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+\d\d+; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+5; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+6; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+7; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+8; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+9; +# +# +#9.3.6 Set SSH IgnoreRhosts to Yes +[CIS - Debian Linux 7/8 - 9.3.6 Set SSH IgnoreRhosts to Yes] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^IgnoreRhosts\s+yes; +# +# +#9.3.7 Set SSH HostbasedAuthentication to No +[CIS - Debian Linux 7/8 - 9.3.7 Set SSH HostbasedAuthentication to No] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^HostbasedAuthentication\s+no; +# +# +#9.3.8 Disable SSH Root Login +[CIS - Debian Linux 7/8 - 9.3.8 Disable SSH Root Login] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\s+yes; +f:/etc/ssh/sshd_config -> !r:^PermitRootLogin\s+no; +# +# +#9.3.9 Set SSH PermitEmptyPasswords to No +[CIS - Debian Linux 7/8 - 9.3.9 Set SSH PermitEmptyPasswords to No] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitEmptyPasswords\s+yes; +f:/etc/ssh/sshd_config -> !r:^PermitEmptyPasswords\s+no; +# +# +#9.3.10 Do Not Allow Users to Set Environment Options +[CIS - Debian Linux 7/8 - 9.3.10 Do Not Allow Users to Set Environment Options] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitUserEnvironment\s+yes; +f:/etc/ssh/sshd_config -> !r:^PermitUserEnvironment\s+no; +# +# +#9.3.12 Set Idle Timeout Interval for User Login +[CIS - Debian Linux 7/8 - 9.3.12 Set Idle Timeout Interval for User Login] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^ClientAliveInterval\s+\d+; +f:/etc/ssh/sshd_config -> !r:^ClientAliveCountMax\s+\d; +# +# +#9.3.13 Limit Access via SSH +[CIS - Debian Linux 7/8 - 9.3.13 Limit Access via SSH] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^AllowUsers\s+\w+|^AllowGroups\s+\w+|^DenyUsers\s+\w+|^DenyGroups\s+\w+; +# +# +#9.3.14 Set SSH Banner +[CIS - Debian Linux 7/8 - 9.3.14 Set SSH Banner] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^Banner\s+\S+; +# +# +#9.5 Restrict Access to the su Command +[CIS - Debian Linux 7/8 - 9.5 Restrict Access to the su Command] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/su -> !r:auth required pam_wheel.so use_uid; +# +# +#10.1.1 Set Password Expiration Days +[CIS - Debian Linux 7/8 - 10.1.1 Set Password Expiration Days] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/login.defs -> !r:^PASS_MAX_DAYS\s+\d+; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+\d\d\d+; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+91; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+92; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+93; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+94; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+95; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+96; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+97; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+98; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+99; +# +# +#10.1.2 Set Password Change Minimum Number of Days +[CIS - Debian Linux 7/8 - 10.1.2 Set Password Change Minimum Number of Days] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/login.defs -> !r:^PASS_MIN_DAYS\s+\d+; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+1; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+2; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+3; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+4; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+5; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+6; +# +# +#10.1.3 Set Password Expiring Warning Days +[CIS - Debian Linux 7/8 - 10.1.3 Set Password Expiring Warning Days] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/login.defs -> !r:^PASS_WARN_DAYS\s+\d+; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+1; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+2; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+3; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+4; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+5; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+6; +# +# +#10.3 Set Default Group for root Account +[CIS - Debian Linux 7/8 - 10.3 Set Default Group for root Account] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/passwd -> !r:^root:\w+:\w+:0:; +# +# +#10.4 Set Default umask for Users +[CIS - Debian Linux 7/8 - 10.4 Set Default umask for Users] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:$profiledfiles -> !r:^umask 077; +f:/etc/bash.bashrc -> !r:^umask 077; +# +# +#10.5 Lock Inactive User Accounts +[CIS - Debian Linux 7/8 - 10.5 Lock Inactive User Accounts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/useradd -> !r:^INACTIVE=\d\d*; +# +# +#11.1 Set Warning Banner for Standard Login Services +[CIS - Debian Linux 7/8 - 11.1 Set Warning Banner for Standard Login Services] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/motd; +f:!/etc/issue; +f:!/etc/issue.net; +# +# +#11.2 Remove OS Information from Login Warning Banners +[CIS - Debian Linux 7/8 - 11.2 Remove OS Information from Login Warning Banners] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/motd -> r:debian|gnu|linux; +# +# +#13.1 Ensure Password Fields are Not Empty +[CIS - Debian Linux 7/8 - 13.1 Ensure Password Fields are Not Empty] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/shadow -> r:^\w+::; +# +# +#13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File +[CIS - Debian Linux 7/8 - 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/passwd -> !r:^# && r:^+:; +# +# +#13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File +[CIS - Debian Linux 7/8 - 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/shadow -> !r:^# && r:^+:; +# +# +#13.4 Verify No Legacy "+" Entries Exist in /etc/group File +[CIS - Debian Linux 7/8 - 13.4 Verify No Legacy "+" Entries Exist in /etc/group File] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/group -> !r:^# && r:^+:; +# +# +#13.5 Verify No UID 0 Accounts Exist Other Than root +[CIS - Debian Linux 7/8 - 13.5 Verify No UID 0 Accounts Exist Other Than root] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; +# +# +#13.10 Check for Presence of User .rhosts Files +[CIS - Debian Linux 7/8 - 13.10 Check for Presence of User .rhosts Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$home_dirs -> r:^.rhosts$; +# +# +#13.18 Check for Presence of User .netrc Files +[CIS - Debian Linux 7/8 - 13.18 Check for Presence of User .netrc Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$home_dirs -> r:^.netrc$; +# +# +#13.19 Check for Presence of User .forward Files +[CIS - Debian Linux 7/8 - 13.19 Check for Presence of User .forward Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$home_dirs -> r:^.forward$; +# +# +#13.20 Ensure shadow group is empty +[CIS - Debian Linux 7/8 - 13.20 Ensure shadow group is empty] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/group -> !r:^# && r:shadow:\w*:\w*:\S+; diff --git a/openarmor-rules/shared/cis_debianlinux7-8_L2_rcl.txt b/openarmor-rules/shared/cis_debianlinux7-8_L2_rcl.txt new file mode 100644 index 000000000..b8eef0341 --- /dev/null +++ b/openarmor-rules/shared/cis_debianlinux7-8_L2_rcl.txt @@ -0,0 +1,245 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# Level 2 CIS Checks for Debian Linux 7 and Debian Linux 8 +# Based on Center for Internet Security Benchmark v1.0.0 for Debian Linux 7 (https://workbench.cisecurity.org/benchmarks/80) and Benchmark v1.0.0 for Debian Linux 8 (https://workbench.cisecurity.org/benchmarks/81) +# +# +$rc_dirfiles=/etc/rc0.d/*,/etc/rc1.d/*,/etc/rc2.d/*,/etc/rc3.d/*,/etc/rc4.d/*,/etc/rc5.d/*,/etc/rc6.d/*,/etc/rc7.d/*,/etc/rc8.d/*,/etc/rc9.d/*,/etc/rca.d/*,/etc/rcb.d/*,/etc/rcc.d/*,/etc/rcs.d/*,/etc/rcS.d/*; +# +# +#2.18 Disable Mounting of cramfs Filesystems +[CIS - Debian Linux 7/8 - 2.18 Disable Mounting of cramfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install cramfs /bin/true; +# +# +#2.19 Disable Mounting of freevxfs Filesystems +[CIS - Debian Linux 7/8 - 2.19 Disable Mounting of freevxfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install freevxfs /bin/true; +# +# +#2.20 Disable Mounting of jffs2 Filesystems +[CIS - Debian Linux 7/8 - 2.20 Disable Mounting of jffs2 Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install jffs2 /bin/true; +# +# +#2.21 Disable Mounting of hfs Filesystems +[CIS - Debian Linux 7/8 - 2.21 Disable Mounting of hfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install hfs /bin/true; +# +# +#2.22 Disable Mounting of hfsplus Filesystems +[CIS - Debian Linux 7/8 - 2.22 Disable Mounting of hfsplus Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install hfsplus /bin/true; +# +# +#2.23 Disable Mounting of squashfs Filesystems +[CIS - Debian Linux 7/8 - 2.23 Disable Mounting of squashfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install squashfs /bin/true; +# +# +#2.24 Disable Mounting of udf Filesystems +[CIS - Debian Linux 7/8 - 2.24 Disable Mounting of udf Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install udf /bin/true; +# +# +#4.5 Activate AppArmor +[CIS - Debian Linux 7/8 - 4.5 Activate AppArmor] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/grub -> !r:apparmor=1 && !r:security=apparmor; +# +# +#8.1.1.1 Configure Audit Log Storage Size +[CIS - Debian Linux 7/8 - 8.1.1.1 Configure Audit Log Storage Size] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/auditd.conf; +f:/etc/audit/auditd.conf -> !r:max_log_file\s*=\s*\d+; +# +# +#8.1.1.2 Disable System on Audit Log Full +[CIS - Debian Linux 7/8 - 8.1.1.2 Disable System on Audit Log Full] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/auditd.conf; +f:/etc/audit/auditd.conf -> !r:^space_left_action\s*=\s*email; +f:/etc/audit/auditd.conf -> !r:^# && r:space_left_action\s*=\s*ignore|syslog|suspend|single|halt; +f:/etc/audit/auditd.conf -> !r:^action_mail_acct\s*=\s*root; +f:/etc/audit/auditd.conf -> !r:^admin_space_left_action\s*=\s*halt; +f:/etc/audit/auditd.conf -> !r:^# && r:admin_space_left_action\s*=\s*ignore|syslog|email|suspend|single; +# +# +#8.1.1.3 Keep All Auditing Information +[CIS - Debian Linux 7/8 - 8.1.1.3 Keep All Auditing Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/auditd.conf; +f:/etc/audit/auditd.conf -> !r:^max_log_file_action\s*=\s*keep_logs; +f:/etc/audit/auditd.conf -> !r:^# && r:max_log_file_action\s*=\s*ignore|syslog|suspend|rotate; +# +# +#8.1.3 Enable Auditing for Processes That Start Prior to auditd +[CIS - Debian Linux 7/8 - 8.1.3 Enable Auditing for Processes That Start Prior to auditd] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/grub -> !r:^GRUB_CMDLINE_LINUX\s*=\s*\.*audit\s*=\s*1\.*; +# +# +#8.1.4 Record Events That Modify Date and Time Information +[CIS - Debian Linux 7 - 8.1.4 Record Events That Modify Date and Time Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S clock_settime -k time-change; +f:/etc/audit/audit.rules -> !r:^-w /etc/localtime -p wa -k time-change; +# +# +#8.1.5 Record Events That Modify User/Group Information +[CIS - Debian Linux 7/8 - 8.1.5 Record Events That Modify User/Group Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /etc/group -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/passwd -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/gshadow -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/shadow -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/security/opasswd -p wa -k identity; +# +# +#8.1.6 Record Events That Modify the System's Network Environment +[CIS - Debian Linux 7/8 - 8.1.6 Record Events That Modify the System's Network Environment] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/issue -p wa -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/issue.net -p wa -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/hosts -p wa -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/network -p wa -k system-locale; +# +# +#8.1.7 Record Events That Modify the System's Mandatory Access Controls +[CIS - Debian Linux 7/8 - 8.1.7 Record Events That Modify the System's Mandatory Access Controls] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /etc/selinux/ -p wa -k MAC-policy; +# +# +#8.1.8 Collect Login and Logout Events +[CIS - Debian Linux 7/8 - 8.1.8 Collect Login and Logout Events] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /var/log/faillog -p wa -k logins; +f:/etc/audit/audit.rules -> !r:^-w /var/log/lastlog -p wa -k logins; +f:/etc/audit/audit.rules -> !r:^-w /var/log/tallylog -p wa -k logins; +# +# +#8.1.9 Collect Session Initiation Information +[CIS - Debian Linux 7/8 - 8.1.9 Collect Session Initiation Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /var/run/utmp -p wa -k session; +f:/etc/audit/audit.rules -> !r:^-w /var/log/wtmp -p wa -k session; +f:/etc/audit/audit.rules -> !r:^-w /var/log/btmp -p wa -k session; +# +# +#8.1.10 Collect Discretionary Access Control Permission Modification Events +[CIS - Debian Linux 7/8 - 8.1.10 Collect Discretionary Access Control Permission Modification Events] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 \\; +f:/etc/audit/audit.rules -> !r:^-F auid!=4294967295 -k perm_mod; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 \\; +f:/etc/audit/audit.rules -> !r:^-F auid!=4294967295 -k perm_mod; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S \\; +f:/etc/audit/audit.rules -> !r:^lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod; +# +# +#8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files +[CIS - Debian Linux 7/8 - 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate \\; +f:/etc/audit/audit.rules -> !r:^-F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate \\; +f:/etc/audit/audit.rules -> !r:^-F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access; +# +# +#8.1.13 Collect Successful File System Mounts +[CIS - Debian Linux 7/8 - 8.1.13 Collect Successful File System Mounts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts; +# +# +#8.1.14 Collect File Deletion Events by User +[CIS - Debian Linux 7/8 - 8.1.14 Collect File Deletion Events by User] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 \\; +f:/etc/audit/audit.rules -> !r:^-F auid!=4294967295 -k delete; +# +# +#8.1.15 Collect Changes to System Administration Scope (sudoers) +[CIS - Debian Linux 7/8 - 8.1.15 Collect Changes to System Administration Scope (sudoers)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /etc/sudoers -p wa -k scope; +# +# +#8.1.16 Collect System Administrator Actions (sudolog) +[CIS - Debian Linux 7/8 - 8.1.16 Collect System Administrator Actions (sudolog)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /var/log/sudo.log -p wa -k actions; +# +# +#8.1.17 Collect Kernel Module Loading and Unloading +[CIS - Debian Linux 7/8 - 8.1.17 Collect Kernel Module Loading and Unloading] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /sbin/insmod -p x -k modules; +f:/etc/audit/audit.rules -> !r:^-w /sbin/rmmod -p x -k modules; +f:/etc/audit/audit.rules -> !r:^-w /sbin/modprobe -p x -k modules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S init_module -S delete_module -k modules|-a always,exit -F arch=b64 -S init_module -S delete_module -k modules; +# +# +#8.1.18 Make the Audit Configuration Immutable +[CIS - Debian Linux 7/8 - 8.1.18 Make the Audit Configuration Immutable] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-e 2$; +# +# +#8.3.1 Install AIDE +[CIS - Debian Linux 7/8 - 8.3.1 Install AIDE] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/usr/sbin/aideinit; +# +# +#8.3.2 Implement Periodic Execution of File Integrity +[CIS - Debian Linux 7/8 - 8.3.2 Implement Periodic Execution of File Integrity] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/crontab -> !r:/usr/sbin/aide --check; +# diff --git a/openarmor-rules/shared/cis_mysql5-6_community_rcl.txt b/openarmor-rules/shared/cis_mysql5-6_community_rcl.txt new file mode 100644 index 000000000..22c91af0d --- /dev/null +++ b/openarmor-rules/shared/cis_mysql5-6_community_rcl.txt @@ -0,0 +1,158 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for MYSQL +# Based on Center for Internet Security Benchmark for MYSQL v1.1.0 +# +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +$enviroment_files=/*/home/*/\.bashrc,/*/home/*/\.profile,/*/home/*/\.bash_profile,/home/*/\.bashrc,/home/*/\.profile,/home/*/\.bash_profile; +$mysql-cnfs=/etc/mysql/my.cnf,/etc/mysql/mariadb.cnf,/etc/mysql/conf.d/*.cnf,/etc/mysql/mariadb.conf.d/*.cnf,~/.my.cnf; +# +# +#1.3 Disable MySQL Command History +[CIS - MySQL Configuration - 1.3: Disable MySQL Command History] [any] [https://workbench.cisecurity.org/files/1310/download] +d:$home_dirs -> ^.mysql_history$; +# +# +#1.5 Disable Interactive Login +[CIS - MySQL Configuration - 1.5: Disable Interactive Login] [any] [https://workbench.cisecurity.org/files/1310/download] +f:/etc/passwd -> r:^mysql && !r:\.*/bin/false$|/sbin/nologin$; +# +# +#1.6 Verify That 'MYSQL_PWD' Is Not In Use +[CIS - MySQL Configuration - 1.6: 'MYSQL_PWD' Is in Use] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$enviroment_files -> r:\.*MYSQL_PWD\.*; +# +# +#4.3 Ensure 'allow-suspicious-udfs' Is Set to 'FALSE' +[CIS - MySQL Configuration - 4.3: 'allow-suspicious-udfs' Is Set in my.cnf'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:allow-suspicious-udfs\.+true; +f:$mysql-cnfs -> r:allow-suspicious-udfs\s*$; +# +# +#4.4 Ensure 'local_infile' Is Disabled +[CIS - MySQL Configuration - 4.4: local_infile is not forbidden in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:local-infile\s*=\s*1; +f:$mysql-cnfs -> r:local-infile\s*$; +# +# +#4.5 Ensure 'mysqld' Is Not Started with '--skip-grant-tables' +[CIS - MySQL Configuration - 4.5: skip-grant-tables is set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip-grant-tables\s*=\s*true; +f:$mysql-cnfs -> !r:skip-grant-tables\s*=\s*false; +f:$mysql-cnfs -> r:skip-grant-tables\s*$; +# +# +#4.6 Ensure '--skip-symbolic-links' Is Enabled +[CIS - MySQL Configuration - 4.6: skip_symbolic_links is not enabled in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip_symbolic_links\s*=\s*no; +f:$mysql-cnfs -> !r:skip_symbolic_links\s*=\s*yes; +f:$mysql-cnfs -> r:skip_symbolic_links\s*$; +# +# +#4.8 Ensure 'secure_file_priv' is not empty +[CIS - MySQL Configuration - 4.8: Ensure 'secure_file_priv' is not empty] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> !r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> r:secure_file_priv\s*$; +# +# +#4.9 Ensure 'sql_mode' Contains 'STRICT_ALL_TABLES' +[CIS - MySQL Configuration - 4.9: strict_all_tables is not set at sql_mode section of my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:strict_all_tables\s*$; +# +# +#6.1 Ensure 'log_error' is not empty +[CIS - MySQL Configuration - 6.1: log-error is not set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> !r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> r:log_error\s*$; +# +# +#6.2 Ensure Log Files are not Stored on a non-system partition +[CIS - MySQL Configuration - 6.2: log files are maybe stored on systempartition] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/var/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/usr/\S*\s*; +f:$mysql-cnfs -> r:log_bin\s*$; +# +# +#6.3 Ensure 'log_warning' is set to 2 at least +[CIS - MySQL Configuration - 6.3: log warnings is set low] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*0; +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*1; +f:$mysql-cnfs -> !r:log_warnings\s*=\s*\d+; +f:$mysql-cnfs -> r:log_warnings\s*$; +# +# +#6.5 Ensure 'log_raw' is set to 'off' +[CIS - MySQL Configuration - 6.5: log_raw is not set to off] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log-raw\s*=\s*on; +f:$mysql-cnfs -> r:log-raw\s*$; +# +# +#7.1 Ensure 'old_password' is not set to '1' or 'On' +[CIS - MySQL Configuration - 7.1:Ensure 'old_passwords' is not set to '1' or 'on'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*1; +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*on; +f:$mysql-cnfs -> !r:old_passwords\s*=\s*2; +f:$mysql-cnfs -> r:old_passwords\s*$; +# +# +#7.2 Ensure 'secure_auth' is set to 'ON' +[CIS - MySQL Configuration - 7.2: Ensure 'secure_auth' is set to 'ON'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:secure_auth\s*=\s*off; +f:$mysql-cnfs -> !r:secure_auth\s*=\s*on; +f:$mysql-cnfs -> r:secure_auth\s*$; +# +# +#7.3 Ensure Passwords Are Not Stored in the Global Configuration +[CIS - MySQL Configuration - 7.3: Passwords are stored in global configuration] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:^\s*password\.*; +# +# +#7.4 Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER' +[CIS - MySQL Configuration - 7.4: Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:no_auto_create_user\s*$; +f:$mysql-cnfs -> r:^# && r:\s*no_auto_create_user\s*$; +# +# +#7.6 Ensure Password Policy is in Place +[CIS - MySQL Configuration - 7.6: Ensure Password Policy is in Place ] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:plugin-load\s*=\s*validate_password.so\s*$; +f:$mysql-cnfs -> !r:validate-password\s*=\s*force_plus_permanent\s*$; +f:$mysql-cnfs -> !r:validate_password_length\s*=\s*14\s$; +f:$mysql-cnfs -> !r:validate_password_mixed_case_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_number_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_special_char_count\s*=\s*1; +f:$mysql-cnfs -> !r:validate_password_policy\s*=\s*medium\s*; +# +# +#9.2 Ensure 'master_info_repository' is set to 'Table' +[CIS - MySQL Configuration - 9.2: Ensure 'master_info_repositrory' is set to 'Table'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:master_info_repository\s*=\s*file; +f:$mysql-cnfs -> !r:master_info_repository\s*=\s*table; +f:$mysql-cnfs -> r:master_info_repository\s*$; diff --git a/openarmor-rules/shared/cis_mysql5-6_enterprise_rcl.txt b/openarmor-rules/shared/cis_mysql5-6_enterprise_rcl.txt new file mode 100644 index 000000000..e627e78cf --- /dev/null +++ b/openarmor-rules/shared/cis_mysql5-6_enterprise_rcl.txt @@ -0,0 +1,208 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for MYSQL +# Based on Center for Internet Security Benchmark for MYSQL v1.1.0 +# +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +$enviroment_files=/*/home/*/\.bashrc,/*/home/*/\.profile,/*/home/*/\.bash_profile,/home/*/\.bashrc,/home/*/\.profile,/home/*/\.bash_profile; +$mysql-cnfs=/etc/mysql/my.cnf,/etc/mysql/mariadb.cnf,/etc/mysql/conf.d/*.cnf,/etc/mysql/mariadb.conf.d/*.cnf,~/.my.cnf; +# +# +#1.3 Disable MySQL Command History +[CIS - MySQL Configuration - 1.3: Disable MySQL Command History] [any] [https://workbench.cisecurity.org/files/1310/download] +d:$home_dirs -> ^.mysql_history$; +# +# +#1.5 Disable Interactive Login +[CIS - MySQL Configuration - 1.5: Disable Interactive Login] [any] [https://workbench.cisecurity.org/files/1310/download] +f:/etc/passwd -> r:^mysql && !r:\.*/bin/false$|/sbin/nologin$; +# +# +#1.6 Verify That 'MYSQL_PWD' Is Not In Use +[CIS - MySQL Configuration - 1.6: 'MYSQL_PWD' Is in Use] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$enviroment_files -> r:\.*MYSQL_PWD\.*; +# +# +#4.3 Ensure 'allow-suspicious-udfs' Is Set to 'FALSE' +[CIS - MySQL Configuration - 4.3: 'allow-suspicious-udfs' Is Set in my.cnf'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:allow-suspicious-udfs\.+true; +f:$mysql-cnfs -> r:allow-suspicious-udfs\s*$; +# +# +#4.4 Ensure 'local_infile' Is Disabled +[CIS - MySQL Configuration - 4.4: local_infile is not forbidden in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:local-infile\s*=\s*1; +f:$mysql-cnfs -> r:local-infile\s*$; +# +# +#4.5 Ensure 'mysqld' Is Not Started with '--skip-grant-tables' +[CIS - MySQL Configuration - 4.5: skip-grant-tables is set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip-grant-tables\s*=\s*true; +f:$mysql-cnfs -> !r:skip-grant-tables\s*=\s*false; +f:$mysql-cnfs -> r:skip-grant-tables\s*$; +# +# +#4.6 Ensure '--skip-symbolic-links' Is Enabled +[CIS - MySQL Configuration - 4.6: skip_symbolic_links is not enabled in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip_symbolic_links\s*=\s*no; +f:$mysql-cnfs -> !r:skip_symbolic_links\s*=\s*yes; +f:$mysql-cnfs -> r:skip_symbolic_links\s*$; +# +# +#4.8 Ensure 'secure_file_priv' is not empty +[CIS - MySQL Configuration - 4.8: Ensure 'secure_file_priv' is not empty] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> !r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> r:secure_file_priv\s*$; +# +# +#4.9 Ensure 'sql_mode' Contains 'STRICT_ALL_TABLES' +[CIS - MySQL Configuration - 4.9: strict_all_tables is not set at sql_mode section of my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:strict_all_tables\s*$; +# +# +#6.1 Ensure 'log_error' is not empty +[CIS - MySQL Configuration - 6.1: log-error is not set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> !r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> r:log_error\s*$; +# +# +#6.2 Ensure Log Files are not Stored on a non-system partition +[CIS - MySQL Configuration - 6.2: log files are maybe stored on systempartition] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/var/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/usr/\S*\s*; +f:$mysql-cnfs -> r:log_bin\s*$; +# +# +#6.3 Ensure 'log_warning' is set to 2 at least +[CIS - MySQL Configuration - 6.3: log warnings is set low] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*0; +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*1; +f:$mysql-cnfs -> !r:log_warnings\s*=\s*\d+; +f:$mysql-cnfs -> r:log_warnings\s*$; +# +# +#6.4 Ensure 'log_raw' is set to 'off' +[CIS - MySQL Configuration - 6.4: log_raw is not set to off] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log-raw\s*=\s*on; +f:$mysql-cnfs -> r:log-raw\s*$; +# +# +#6.5 Ensure audit_log_connection_policy is not set to 'none' +[CIS - MySQL Configuration - 6.5: audit_log_connection_policy is set to 'none' change it to all or erros] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r^# && r::audit_log_connection_policy\s*=\s*none; +f:$mysql-cnfs -> r:audit_log_connection_policy\s*$; +# +# +#6.6 Ensure audit_log_exclude_account is set to Null +[CIS - MySQL Configuration - 6.6:audit_log_exclude_accounts is not set to Null] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_exclude_accounts\s*=\s* && !r:null\s*$; +f:$mysql-cnfs -> r:audit_log_exclude_accounts\s*$; +# +# +#6.7 Ensure audit_log_include_accounts is set to Null +[CIS - MySQL Configuration - 6.7:audit_log_include_accounts is not set to Null] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_include_accounts\s*=\s* && !r:null\s*$; +f:$mysql-cnfs -> r:audit_log_include_accounts\s*$; +# +# +#6.9 Ensure audit_log_policy is not set to all +[CIS - MySQL Configuration - 6.9: audit_log_policy is not set to all] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_policy\s*=\s*queries; +f:$mysql-cnfs -> !r:^# && r:audit_log_policy\s*=\s*none; +f:$mysql-cnfs -> !r:^# && r:audit_log_policy\s*=\s*logins; +f:$mysql-cnfs -> r:audit_log_policy\s*$; +# +# +#6.10 Ensure audit_log_statement_policy is set to all +[CIS - MySQL Configuration - 6.10: Ensure audit_log_statement_policy is set to all] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_statement_policy\.+errors; +f:$mysql-cnfs -> !r:^# && r:audit_log_statement_policy\.+none; +f:$mysql-cnfs -> r:audit_log_statement_policy\s*$; +# +# +#6.11 Ensure audit_log_strategy is set to synchronous or semisynchronous +[CIS - MySQL Configuration - 6.11: Ensure audit_log_strategy is set to all] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_strategy\.+asynchronous; +f:$mysql-cnfs -> !r:^# && r:audit_log_strategy\.+performance; +f:$mysql-cnfs -> !r:audit_log_strategy\s*=\s* && r:semisynchronous|synchronous; +f:$mysql-cnfs -> r:audit_log_strategy\s*$; +# +# +#6.12 Make sure the audit plugin can't be unloaded +[CIS - MySQL Configuration - 6.12: Audit plugin can be unloaded] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:^audit_log\s*=\s*on\s*; +f:$mysql-cnfs -> !r:^# && r:^audit_log\s*=\s*off\s*; +f:$mysql-cnfs -> !r:^# && r:^audit_log\s*=\s*force\s*; +f:$mysql-cnfs -> !r:^audit_log\s*=\s*force_plus_permanent\s*; +f:$mysql-cnfs -> r:^audit_log\s$; +# +# +#7.1 Ensure 'old_password' is not set to '1' or 'On' +[CIS - MySQL Configuration - 7.1:Ensure 'old_passwords' is not set to '1' or 'on'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*1; +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*on; +f:$mysql-cnfs -> !r:old_passwords\s*=\s*2; +f:$mysql-cnfs -> r:old_passwords\s*$; +# +# +#7.2 Ensure 'secure_auth' is set to 'ON' +[CIS - MySQL Configuration - 7.2: Ensure 'secure_auth' is set to 'ON'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:secure_auth\s*=\s*off; +f:$mysql-cnfs -> !r:secure_auth\s*=\s*on; +f:$mysql-cnfs -> r:secure_auth\s*$; +# +# +#7.3 Ensure Passwords Are Not Stored in the Global Configuration +[CIS - MySQL Configuration - 7.3: Passwords are stored in global configuration] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:^\s*password\.*; +# +# +#7.4 Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER' +[CIS - MySQL Configuration - 7.4: Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:no_auto_create_user\s*$; +f:$mysql-cnfs -> r:^# && r:\s*no_auto_create_user\s*$; +# +# +#7.6 Ensure Password Policy is in Place +[CIS - MySQL Configuration - 7.6: Ensure Password Policy is in Place ] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:plugin-load\s*=\s*validate_password.so\s*$; +f:$mysql-cnfs -> !r:validate-password\s*=\s*force_plus_permanent\s*$; +f:$mysql-cnfs -> !r:validate_password_length\s*=\s*14\s$; +f:$mysql-cnfs -> !r:validate_password_mixed_case_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_number_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_special_char_count\s*=\s*1; +f:$mysql-cnfs -> !r:validate_password_policy\s*=\s*medium\s*; +# +# +#9.2 Ensure 'master_info_repository' is set to 'Table' +[CIS - MySQL Configuration - 9.2: Ensure 'master_info_repositrory' is set to 'Table'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:master_info_repository\s*=\s*file; +f:$mysql-cnfs -> !r:master_info_repository\s*=\s*table; +f:$mysql-cnfs -> r:master_info_repository\s*$; diff --git a/openarmor-rules/shared/cis_rhel5_linux_rcl.txt b/openarmor-rules/shared/cis_rhel5_linux_rcl.txt new file mode 100644 index 000000000..8ebf43b4d --- /dev/null +++ b/openarmor-rules/shared/cis_rhel5_linux_rcl.txt @@ -0,0 +1,845 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat / CentOS 5 +# Based on CIS Benchmark for Red Hat Enterprise Linux 5 v2.1.0 + +# TODO: URL is invalid currently + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS Red Hat Enterprise Linux 5 Benchmark v2.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 5; +f:/etc/redhat-release -> r:^CentOS && r:release 5; +f:/etc/redhat-release -> r:^Cloud && r:release 5; +f:/etc/redhat-release -> r:^Oracle && r:release 5; +f:/etc/redhat-release -> r:^Better && r:release 5; + + +# 1.1.1 /tmp: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /tmp is not on its own partition {CIS: 1.1.1 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 1.1.2 /tmp: nodev +[CIS - RHEL5 - 1.1.2 - Partition /tmp without 'nodev' set {CIS: 1.1.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.3 /tmp: nosuid +[CIS - RHEL5 - 1.1.3 - Partition /tmp without 'nosuid' set {CIS: 1.1.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 1.1.4 /tmp: noexec +[CIS - RHEL5 - 1.1.4 - Partition /tmp without 'noexec' set {CIS: 1.1.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.5 Build considerations - Partition scheme. +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 1.1.5 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 1.1.6 bind mount /var/tmp to /tmp +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 1.1.6 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 1.1.7 /var/log: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 1.1.7 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 1.1.8 /var/log/audit: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 1.1.8 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 1.1.9 /home: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 1.1.9 Debian RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 1.1.10 /home: nodev +[CIS - RHEL5 - 1.1.10 - Partition /home without 'nodev' set {CIS: 1.1.10 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 1.1.11 nodev on removable media partitions (not scored) +[CIS - RHEL5 - 1.1.11 - Removable partition /media without 'nodev' set {CIS: 1.1.11 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 1.1.12 noexec on removable media partitions (not scored) +[CIS - RHEL5 - 1.1.12 - Removable partition /media without 'noexec' set {CIS: 1.1.12 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 1.1.13 nosuid on removable media partitions (not scored) +[CIS - RHEL5 - 1.1.13 - Removable partition /media without 'nosuid' set {CIS: 1.1.13 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 1.1.14 /dev/shm: nodev +[CIS - RHEL5 - 1.1.11 - /dev/shm without 'nodev' set {CIS: 1.1.14 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 1.1.15 /dev/shm: nosuid +[CIS - RHEL5 - 1.1.11 - /dev/shm without 'nosuid' set {CIS: 1.1.15 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 1.1.16 /dev/shm: noexec +[CIS - RHEL5 - 1.1.11 - /dev/shm without 'noexec' set {CIS: 1.1.16 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 1.1.17 sticky bit on world writable directories (Scored) +# TODO + +# 1.1.18 disable cramfs (not scored) + +# 1.1.19 disable freevxfs (not scored) + +# 1.1.20 disable jffs2 (not scored) + +# 1.1.21 disable hfs (not scored) + +# 1.1.22 disable hfsplus (not scored) + +# 1.1.23 disable squashfs (not scored) + +# 1.1.24 disable udf (not scored) + + +########################################## +# 1.2 Software Updates +########################################## + +# 1.2.1 Configure rhn updates (not scored) + +# 1.2.2 verify RPM gpg keys (Scored) +# TODO + +# 1.2.3 verify gpgcheck enabled (Scored) +# TODO + +# 1.2.4 Disable rhnsd (not scored) + +# 1.2.5 Disable yum-updatesd (Scored) +[CIS - RHEL5 - 1.2.5 - yum-updatesd not Disabled {CIS: 1.2.5 RHEL5} {PCI_DSS: 6.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; +p:yum-updatesd; + +# 1.2.6 Obtain updates with yum (not scored) + +# 1.2.7 Verify package integrity (not scored) + + +############################################### +# 1.3 Advanced Intrusion Detection Environment +############################################### +# +# Skipped, this control is obsoleted by openarmor +# + + +############################################### +# 1.4 Configure SELinux +############################################### + +# 1.4.1 enable selinux in /etc/grub.conf +[CIS - RHEL5 - 1.4.1 - SELinux Disabled in /etc/grub.conf {CIS: 1.4.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/grub.conf -> !r:selinux=0; + +# 1.4.2 Set selinux state +[CIS - RHEL5 - 1.4.2 - SELinux not set to enforcing {CIS: 1.4.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/selinux/config -> r:SELINUX=enforcing; + +# 1.4.3 Set seliux policy +[CIS - RHEL5 - 1.4.3 - SELinux policy not set to targeted {CIS: 1.4.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/selinux/config -> r:SELINUXTYPE=targeted; + +# 1.4.4 Remove SETroubleshoot +[CIS - RHEL5 - 1.4.4 - SELinux setroubleshoot enabled {CIS: 1.4.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsetroubleshoot$; + +# 1.4.5 Disable MCS Translation service mcstrans +[CIS - RHEL5 - 1.4.5 - SELinux mctrans enabled {CIS: 1.4.5 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dmctrans$; + +# 1.4.6 Check for unconfined daemons +# TODO + + +############################################### +# 1.5 Secure Boot Settings +############################################### + +# 1.5.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) + +# 1.5.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) + +# 1.5.3 Set Boot Loader Password (Scored) +[CIS - RHEL5 - 1.5.3 - GRUB Password not set {CIS: 1.5.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +# 1.5.4 Require Authentication for Single-User Mode (Scored) +[CIS - RHEL5 - 1.5.4 - Authentication for single user mode not enabled {CIS: 1.5.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/inittab -> !r:^# && r:S:wait; + +# 1.5.5 Disable Interactive Boot (Scored) +[CIS - RHEL5 - 1.5.5 - Interactive Boot not disabled {CIS: 1.5.5 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/sysconfig/init -> !r:^# && r:PROMPT=no; + + + +############################################### +# 1.6 Additional Process Hardening +############################################### + +# 1.6.1 Restrict Core Dumps (Scored) +[CIS - RHEL5 - 1.6.1 - Interactive Boot not disabled {CIS: 1.6.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 1.6.2 Configure ExecShield (Scored) +[CIS - RHEL5 - 1.6.2 - ExecShield not enabled {CIS: 1.6.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/kernel/exec-shield -> 0; + +# 1.6.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - RHEL5 - 1.6.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 1.6.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 0; + +# 1.6.4 Enable XD/NX Support on 32-bit x86 Systems (Scored) +# TODO + +# 1.6.5 Disable Prelink (Scored) +[CIS - RHEL5 - 1.6.5 - Prelink not disabled {CIS: 1.6.5 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/sysconfig/prelink -> !r:PRELINKING=no; + + +############################################### +# 1.7 Use the Latest OS Release +############################################### + + +############################################### +# 2 OS Services +############################################### + +############################################### +# 2.1 Remove Legacy Services +############################################### + +# 2.1.1 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - RHEL5 - 2.1.1 - Telnet enabled on xinetd {CIS: 2.1.1 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; + + +# 2.1.2 Remove telnet Clients (Scored) +# TODO + +# 2.1.3 Remove rsh-server (Scored) +[CIS - RHEL5 - 2.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.1.3 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; + +# 2.1.4 Remove rsh (Scored) +# TODO + +# 2.1.5 Remove NIS Client (Scored) +[CIS - RHEL5 - 2.1.5 - Disable standard boot services - NIS (client) Enabled {CIS: 2.1.5 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; + +# 2.1.6 Remove NIS Server (Scored) +[CIS - RHEL5 - 2.1.5 - Disable standard boot services - NIS (server) Enabled {CIS: 2.1.6 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; + +# 2.1.7 Remove tftp (Scored) +# TODO + +# 2.1.8 Remove tftp-server (Scored) +[CIS - RHEL5 - 2.1.8 - tftpd enabled on xinetd {CIS: 2.1.8 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; + +# 2.1.9 Remove talk (Scored) +# TODO + +# 2.1.10 Remove talk-server (Scored) +[CIS - RHEL5 - 2.1.10 - talk enabled on xinetd {CIS: 2.1.10 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; + +# 2.1.11 Remove xinetd (Scored) +# TODO + +# 2.1.12 Disable chargen-dgram (Scored) +# TODO + +# 2.1.13 Disable chargen-stream (Scored) +# TODO + +# 2.1.14 Disable daytime-dgram (Scored) +# TODO + +# 2.1.15 Disable daytime-stream (Scored) +# TODO + +# 2.1.16 Disable echo-dgram (Scored) +# TODO + +# 2.1.17 Disable echo-stream (Scored) +# TODO + +# 2.1.18 Disable tcpmux-server (Scored) +# TODO + + +############################################### +# 3 Special Purpose Services +############################################### + +############################################### +# 3.1 Disable Avahi Server +############################################### + +# 3.1.1 Disable Avahi Server (Scored) +[CIS - RHEL5 - 3.1.1 - Avahi daemon not disabled {CIS: 3.1.1 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +p:avahi-daemon; + +# 3.1.2 Service Only via Required Protocol (Not Scored) +# TODO + +# 3.1.3 Check Responses TTL Field (Scored) +# TODO + +# 3.1.4 Prevent Other Programs from Using Avahi’s Port (Not Scored) +# TODO + +# 3.1.5 Disable Publishing (Not Scored) + +# 3.1.6 Restrict Published Information (if publishing is required) (Not scored) + +# 3.2 Set Daemon umask (Scored) +[CIS - RHEL5 - 3.2 - Set daemon umask - Default umask is higher than 027 {CIS: 3.2 RHEL5}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/init.d/functions -> !r:^# && r:^umask && <:umask 027; + +# 3.3 Remove X Windows (Scored) +[CIS - RHEL5 - 3.3 - X11 not disabled {CIS: 3.3 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +# 3.4 Disable Print Server - CUPS (Not Scored) + +# 3.5 Remove DHCP Server (Not Scored) +# TODO + +# 3.6 Configure Network Time Protocol (NTP) (Scored) +#[CIS - RHEL5 - 3.6 - NTPD not disabled {CIS: 3.6 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +# TODO. + +# 3.7 Remove LDAP (Not Scored) + +# 3.8 Disable NFS and RPC (Not Scored) +[CIS - RHEL5 - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 3.9 Remove DNS Server (Not Scored) +# TODO + +# 3.10 Remove FTP Server (Not Scored) +[CIS - RHEL5 - 3.10 - VSFTP enabled on xinetd {CIS: 3.10 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 3.11 Remove HTTP Server (Not Scored) +[CIS - RHEL5 - 3.11 - Disable standard boot services - Apache web server Enabled {CIS: 3.11 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dhttpd$; + +# 3.12 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - RHEL5 - 3.12 - imap enabled on xinetd {CIS: 3.12 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - RHEL5 - 3.12 - pop3 enabled on xinetd {CIS: 3.12 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 3.13 Remove Samba (Not Scored) +[CIS - RHEL5 - 3.13 - Disable standard boot services - Samba Enabled {CIS: 3.13 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 3.14 Remove HTTP Proxy Server (Not Scored) +[CIS - RHEL5 - 3.14 - Disable standard boot services - Squid Enabled {CIS: 3.14 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 3.15 Remove SNMP Server (Not Scored) +[CIS - RHEL5 - 3.15 - Disable standard boot services - SNMPD process Enabled {CIS: 3.15 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 3.16 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + + +############################################### +# 4 Network Configuration and Firewalls +############################################### + +############################################### +# 4.1 Modify Network Parameters (Host Only) +############################################### + +# 4.1.1 Disable IP Forwarding (Scored) +[CIS - RHEL5 - 4.1.1 - Network parameters - IP Forwarding enabled {CIS: 4.1.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 4.1.2 Disable Send Packet Redirects (Scored) +[CIS - RHEL5 - 4.1.2 - Network parameters - IP send redirects enabled {CIS: 4.1.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + + +############################################### +# 4.2 Modify Network Parameters (Host and Router) +############################################### + +# 4.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - RHEL5 - 4.2.1 - Network parameters - Source routing accepted {CIS: 4.2.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 4.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - RHEL5 - 4.2.2 - Network parameters - ICMP redirects accepted {CIS: 4.2.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 4.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - RHEL5 - 4.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 4.2.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 4.2.4 Log Suspicious Packets (Scored) +[CIS - RHEL5 - 4.2.4 - Network parameters - martians not logged {CIS: 4.2.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 4.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - RHEL5 - 4.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 4.2.5 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 4.2.6 Enable Bad Error Message Protection (Scored) +[CIS - RHEL5 - 4.2.6 - Network parameters - Bad error message protection not enabled {CIS: 4.2.6 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 4.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - RHEL5 - 4.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 4.2.7 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 4.2.8 Enable TCP SYN Cookies (Scored) +[CIS - RHEL5 - 4.2.8 - Network parameters - SYN Cookies not enabled {CIS: 4.2.8 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + + +############################################### +# 4.3 Wireless Networking +############################################### + +# 4.3.1 Deactivate Wireless Interfaces (Not Scored) + + +############################################### +# 4.4 Disable ipv6 +############################################### + +############################################### +# 4.4.1 Configure IPv6 +############################################### + +# 4.4.1.1 Disable IPv6 Router Advertisements (Not Scored) + +# 4.4.1.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 4.4.2 Disable IPv6 (Not Scored) + + +############################################### +# 4.5 Install TCP Wrappers +############################################### + +# 4.5.1 Install TCP Wrappers (Not Scored) + +# 4.5.2 Create /etc/hosts.allow (Not Scored) + +# 4.5.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 4.5.4 Create /etc/hosts.deny (Not Scored) + +# 4.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + + +############################################### +# 4.6 Uncommon Network Protocols +############################################### + +# 4.6.1 Disable DCCP (Not Scored) + +# 4.6.2 Disable SCTP (Not Scored) + +# 4.6.3 Disable RDS (Not Scored) + +# 4.6.4 Disable TIPC (Not Scored) + +# 4.7 Enable IPtables (Scored) +# TODO + +# 4.8 Enable IP6tables (Not Scored) + + +############################################### +# 5 Logging and Auditing +############################################### + +############################################### +# 5.1 Configure Syslog +############################################### + +# 5.1.1 Configure /etc/syslog.conf (Not Scored) + +# 5.1.2 Create and Set Permissions on syslog Log Files (Scored) + +# 5.1.3 Configure syslog to Send Logs to a Remote Log Host (Scored) + +# 5.1.4 Accept Remote syslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.2 Configure rsyslog +############################################### + +# 5.2.1 Install the rsyslog package (Not Scored) + +# 5.2.2 Activate the rsyslog Service (Not Scored) + +# 5.2.3 Configure /etc/rsyslog.conf (Not Scored) + +# 5.2.4 Create and Set Permissions on rsyslog Log Files (Not Scored) + +# 5.2.5 Configure rsyslog to Send Logs to a Remote Log Host (Not Scored) + +# 5.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.3 Configure System Accounting (auditd) +############################################### + +############################################### +# 5.3.1 Configure Data Retention +############################################### + +# 5.3.1.1 Configure Audit Log Storage Size (Not Scored) + +# 5.3.1.2 Disable System on Audit Log Full (Not Scored) + +# 5.3.1.3 Keep All Auditing Information (Scored) + +# 5.3.2 Enable auditd Service (Scored) + +# 5.3.3 Configure Audit Log Storage Size (Not Scored) + +# 5.3.4 Disable System on Audit Log Full (Not Scored) + +# 5.3.5 Keep All Auditing Information (Scored) + +# 5.3.6 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 5.3.7 Record Events That Modify Date and Time Information (Scored) + +# 5.3.8 Record Events That Modify User/Group Information (Scored) + +# 5.3.9 Record Events That Modify the System’s Network Environment (Scored) + +# 5.3.10 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 5.3.11 Collect Login and Logout Events (Scored) + +# 5.3.12 Collect Session Initiation Information (Scored) + +# 5.3.13 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 5.3.14 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 5.3.15 Collect Use of Privileged Commands (Scored) + +# 5.3.16 Collect Successful File System Mounts (Scored) + +# 5.3.17 Collect File Deletion Events by User (Scored) + +# 5.3.18 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 5.3.19 Collect System Administrator Actions (sudolog) (Scored) + +# 5.3.20 Collect Kernel Module Loading and Unloading (Scored) + +# 5.3.21 Make the Audit Configuration Immutable (Scored) + +# 5.4 Configure logrotate (Not Scored) + + +############################################### +# 6 System Access, Authentication and Authorization +############################################### + +############################################### +# 6.1 Configure cron and anacron +############################################### + +# 6.1.1 Enable anacron Daemon (Scored) + +# 6.1.2 Enable cron Daemon (Scored) + +# 6.1.3 Set User/Group Owner and Permission on /etc/anacrontab (Scored) + +# 6.1.4 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 6.1.5 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 6.1.6 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 6.1.7 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 6.1.8 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 6.1.9 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 6.1.10 Restrict at Daemon (Scored) + +# 6.1.11 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 6.1 Configure SSH +############################################### + +# 6.2.1 Set SSH Protocol to 2 (Scored) +[CIS - RHEL5 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 6.2.2 Set LogLevel to INFO (Scored) + +# 6.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) + +# 6.2.4 Disable SSH X11 Forwarding (Scored) + +# 6.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) + +# 6.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - RHEL5 - 6.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 6.2.6 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 6.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - RHEL5 - 6.2.7 - SSH Configuration - Host based authentication enabled {CIS: 6.2.7 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 6.2.8 Disable SSH Root Login (Scored) +[CIS - RHEL5 - 6.2.8 - SSH Configuration - Root login allowed {CIS: 6.2.8 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + +# 6.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - RHEL5 - 6.2.9 - SSH Configuration - Empty passwords permitted {CIS: 6.2.9 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +# 6.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 6.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 6.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 6.2.13 Limit Access via SSH (Scored) + +# 6.2.14 Set SSH Banner (Scored) + +# 6.2.15 Enable SSH UsePrivilegeSeparation (Scored) + + +############################################### +# 6.3 Configure PAM +############################################### + +# 6.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 6.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 6.3.3 Use pam_deny.so to Deny Services (Not Scored) + +# 6.3.4 Upgrade Password Hashing Algorithm to SHA-512 (Scored) + +# 6.3.5 Limit Password Reuse (Scored) + +# 6.3.6 Remove the pam_ccreds Package (Scored) + +# 6.4 Restrict root Login to System Console (Not Scored) + +# 6.5 Restrict Access to the su Command (Scored) + + +############################################### +# 7 User Accounts and Environment +############################################### + +############################################### +# 7.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 7.1.1 Set Password Expiration Days (Scored) + +# 7.1.2 Set Password Change Minimum Number of Days (Scored) + +# 7.1.3 Set Password Expiring Warning Days (Scored) + +# 7.2 Disable System Accounts (Scored) + +# 7.3 Set Default Group for root Account (Scored) + +# 7.4 Set Default umask for Users (Scored) + +# 7.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 8 Warning Banners +############################################### + +############################################### +# 8.1 Warning Banners for Standard Login Services +############################################### + +# 8.1.1 Set Warning Banner for Standard Login Services (Scored) + +# 8.1.2 Remove OS Information from Login Warning Banners (Scored) + +# 8.2 Set GNOME Warning Banner (Not Scored) + + +############################################### +# 9 System Maintenance +############################################### + +############################################### +# 9.1 Verify System File Permissions +############################################### + +# 9.1.1 Verify System File Permissions (Not Scored) + +# 9.1.2 Verify Permissions on /etc/passwd (Scored) + +# 9.1.3 Verify Permissions on /etc/shadow (Scored) + +# 9.1.4 Verify Permissions on /etc/gshadow (Scored) + +# 9.1.5 Verify Permissions on /etc/group (Scored) + +# 9.1.6 Verify User/Group Ownership on /etc/passwd (Scored) + +# 9.1.7 Verify User/Group Ownership on /etc/shadow (Scored) + +# 9.1.8 Verify User/Group Ownership on /etc/gshadow (Scored) + +# 9.1.9 Verify User/Group Ownership on /etc/group (Scored) + +# 9.1.10 Find World Writable Files (Not Scored) + +# 9.1.11 Find Un-owned Files and Directories (Scored) + +# 9.1.12 Find Un-grouped Files and Directories (Scored) + +# 9.1.13 Find SUID System Executables (Not Scored) + +# 9.1.14 Find SGID System Executables (Not Scored) + + +############################################### +# 9.2 Review User and Group Settings +############################################### + +# 9.2.1 Ensure Password Fields are Not Empty (Scored) + +# 9.2.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 9.2.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 9.2.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 9.2.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - RHEL5 - 9.2.5 - Non-root account with uid 0 {CIS: 9.2.5 RHEL5} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 9.2.6 Ensure root PATH Integrity (Scored) + +# 9.2.7 Check Permissions on User Home Directories (Scored) + +# 9.2.8 Check User Dot File Permissions (Scored) + +# 9.2.9 Check Permissions on User .netrc Files (Scored) + +# 9.2.10 Check for Presence of User .rhosts Files (Scored) + +# 9.2.11 Check Groups in /etc/passwd (Scored) + +# 9.2.12 Check That Users Are Assigned Home Directories (Scored) + +# 9.2.13 Check That Defined Home Directories Exist (Scored) + +# 9.2.14 Check User Home Directory Ownership (Scored) + +# 9.2.15 Check for Duplicate UIDs (Scored) + +# 9.2.16 Check for Duplicate GIDs (Scored) + +# 9.2.17 Check That Reserved UIDs Are Assigned to System Accounts + +# 9.2.18 Check for Duplicate User Names (Scored) + +# 9.2.19 Check for Duplicate Group Names (Scored) + +# 9.2.20 Check for Presence of User .netrc Files (Scored) + +# 9.2.21 Check for Presence of User .forward Files (Scored) + +# Other/Legacy Tests +[CIS - RHEL5 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - RHEL5 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/openarmor-rules/shared/cis_rhel6_linux_rcl.txt b/openarmor-rules/shared/cis_rhel6_linux_rcl.txt new file mode 100644 index 000000000..2bf56eda5 --- /dev/null +++ b/openarmor-rules/shared/cis_rhel6_linux_rcl.txt @@ -0,0 +1,787 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat / CentOS 6 +# Based on CIS Benchmark for Red Hat Enterprise Linux 6 v1.3.0 + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS Red Hat Enterprise Linux 5 Benchmark v2.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 6; +f:/etc/redhat-release -> r:^CentOS && r:release 6; +f:/etc/redhat-release -> r:^Cloud && r:release 6; +f:/etc/redhat-release -> r:^Oracle && r:release 6; +f:/etc/redhat-release -> r:^Better && r:release 6; + +# 1.1.1 /tmp: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /tmp is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 1.1.2 /tmp: nodev +[CIS - RHEL6 - 1.1.2 - Partition /tmp without 'nodev' set {CIS: 1.1.2 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.3 /tmp: nosuid +[CIS - RHEL6 - 1.1.3 - Partition /tmp without 'nosuid' set {CIS: 1.1.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 1.1.4 /tmp: noexec +[CIS - RHEL6 - 1.1.4 - Partition /tmp without 'noexec' set {CIS: 1.1.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.5 Build considerations - Partition scheme. +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 1.1.5 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 1.1.6 bind mount /var/tmp to /tmp +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 1.1.6 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 1.1.7 /var/log: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 1.1.7 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 1.1.8 /var/log/audit: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 1.1.8 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 1.1.9 /home: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 1.1.9 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 1.1.10 /home: nodev +[CIS - RHEL6 - 1.1.10 - Partition /home without 'nodev' set {CIS: 1.1.10 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 1.1.11 nodev on removable media partitions (not scored) +[CIS - RHEL6 - 1.1.11 - Removable partition /media without 'nodev' set {CIS: 1.1.11 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 1.1.12 noexec on removable media partitions (not scored) +[CIS - RHEL6 - 1.1.12 - Removable partition /media without 'noexec' set {CIS: 1.1.12 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 1.1.13 nosuid on removable media partitions (not scored) +[CIS - RHEL6 - 1.1.13 - Removable partition /media without 'nosuid' set {CIS: 1.1.13 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 1.1.14 /dev/shm: nodev +[CIS - RHEL6 - 1.1.14 - /dev/shm without 'nodev' set {CIS: 1.1.14 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 1.1.15 /dev/shm: nosuid +[CIS - RHEL6 - 1.1.15 - /dev/shm without 'nosuid' set {CIS: 1.1.15 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 1.1.16 /dev/shm: noexec +[CIS - RHEL6 - 1.1.16 - /dev/shm without 'noexec' set {CIS: 1.1.16 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 1.1.17 sticky bit on world writable directories (Scored) +# TODO + +# 1.1.18 disable cramfs (not scored) + +# 1.1.19 disable freevxfs (not scored) + +# 1.1.20 disable jffs2 (not scored) + +# 1.1.21 disable hfs (not scored) + +# 1.1.22 disable hfsplus (not scored) + +# 1.1.23 disable squashfs (not scored) + +# 1.1.24 disable udf (not scored) + + +########################################## +# 1.2 Software Updates +########################################## + +# 1.2.1 Configure rhn updates (not scored) + +# 1.2.2 verify RPM gpg keys (Scored) +# TODO + +# 1.2.3 verify gpgcheck enabled (Scored) +# TODO + +# 1.2.4 Disable rhnsd (not scored) + +# 1.2.5 Obtain Software Package Updates with yum (Not Scored) + +# 1.2.6 Obtain updates with yum (not scored) + + +############################################### +# 1.3 Advanced Intrusion Detection Environment +############################################### +# +# Skipped, this control is obsoleted by openarmor +# + +############################################### +# 1.4 Configure SELinux +############################################### + +# 1.4.1 enable selinux in /etc/grub.conf +[CIS - RHEL6 - 1.4.1 - SELinux Disabled in /etc/grub.conf {CIS: 1.4.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/grub.conf -> !r:selinux=0; + +# 1.4.2 Set selinux state +[CIS - RHEL6 - 1.4.2 - SELinux not set to enforcing {CIS: 1.4.2 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/selinux/config -> r:SELINUX=enforcing; + +# 1.4.3 Set seliux policy +[CIS - RHEL6 - 1.4.3 - SELinux policy not set to targeted {CIS: 1.4.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/selinux/config -> r:SELINUXTYPE=targeted; + +# 1.4.4 Remove SETroubleshoot +[CIS - RHEL6 - 1.4.4 - SELinux setroubleshoot enabled {CIS: 1.4.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsetroubleshoot$; + +# 1.4.5 Disable MCS Translation service mcstrans +[CIS - RHEL6 - 1.4.5 - SELinux mctrans enabled {CIS: 1.4.5 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dmctrans$; + +# 1.4.6 Check for unconfined daemons +# TODO + + +############################################### +# 1.5 Secure Boot Settings +############################################### + +# 1.5.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) + +# 1.5.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) + +# 1.5.3 Set Boot Loader Password (Scored) +[CIS - RHEL6 - 1.5.3 - GRUB Password not set {CIS: 1.5.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +# 1.5.4 Require Authentication for Single-User Mode (Scored) +[CIS - RHEL6 - 1.5.4 - Authentication for single user mode not enabled {CIS: 1.5.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/inittab -> !r:^# && r:S:wait; + +# 1.5.5 Disable Interactive Boot (Scored) +[CIS - RHEL6 - 1.5.5 - Interactive Boot not disabled {CIS: 1.5.5 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/sysconfig/init -> !r:^# && r:PROMPT=no; + + +############################################### +# 1.6 Additional Process Hardening +############################################### + +# 1.6.1 Restrict Core Dumps (Scored) +[CIS - RHEL6 - 1.6.1 - Interactive Boot not disabled {CIS: 1.6.1 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 1.6.2 Configure ExecShield (Scored) +[CIS - RHEL6 - 1.6.2 - ExecShield not enabled {CIS: 1.6.2 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/kernel/exec-shield -> 0; + +# 1.6.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - RHEL6 - 1.6.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 1.6.3 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 0; + + +############################################### +# 1.7 Use the Latest OS Release (Not Scored) +############################################### + + +############################################### +# 2 OS Services +############################################### + +############################################### +# 2.1 Remove Legacy Services +############################################### + +# 2.1.1 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - RHEL6 - 2.1.1 - Telnet enabled on xinetd {CIS: 2.1.1 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; + + +# 2.1.2 Remove telnet Clients (Scored) +# TODO + +# 2.1.3 Remove rsh-server (Scored) +[CIS - RHEL6 - 2.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.1.3 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; + +# 2.1.4 Remove rsh (Scored) +# TODO + +# 2.1.5 Remove NIS Client (Scored) +[CIS - RHEL6 - 2.1.5 - Disable standard boot services - NIS (client) Enabled {CIS: 2.1.5 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; + +# 2.1.6 Remove NIS Server (Scored) +[CIS - RHEL6 - 2.1.6 - Disable standard boot services - NIS (server) Enabled {CIS: 2.1.6 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; + +# 2.1.7 Remove tftp (Scored) +# TODO + +# 2.1.8 Remove tftp-server (Scored) +[CIS - RHEL6 - 2.1.8 - tftpd enabled on xinetd {CIS: 2.1.8 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; + +# 2.1.9 Remove talk (Scored) +# TODO + +# 2.1.10 Remove talk-server (Scored) +[CIS - RHEL6 - 2.1.10 - talk enabled on xinetd {CIS: 2.1.10 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; + +# 2.1.11 Remove xinetd (Scored) +# TODO + +# 2.1.12 Disable chargen-dgram (Scored) +# TODO + +# 2.1.13 Disable chargen-stream (Scored) +# TODO + +# 2.1.14 Disable daytime-dgram (Scored) +# TODO + +# 2.1.15 Disable daytime-stream (Scored) +# TODO + +# 2.1.16 Disable echo-dgram (Scored) +# TODO + +# 2.1.17 Disable echo-stream (Scored) +# TODO + +# 2.1.18 Disable tcpmux-server (Scored) +# TODO + + +############################################### +# 3 Special Purpose Services +############################################### + +# 3.1 Set Daemon umask (Scored) +[CIS - RHEL6 - 3.1 - Set daemon umask - Default umask is higher than 027 {CIS: 3.1 RHEL6} {PCI_DSS: 2.2.2}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/init.d/functions -> !r:^# && r:^umask && <:umask 027; + +# 3.2 Remove X Windows (Scored) +[CIS - RHEL6 - 3.2 - X11 not disabled {CIS: 3.2 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +# 3.3 Disable Avahi Server (Scored) +[CIS - RHEL6 - 3.2 - Avahi daemon not disabled {CIS: 3.3 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +p:avahi-daemon; + +# 3.4 Disable Print Server - CUPS (Not Scored) + +# 3.5 Remove DHCP Server (Not Scored) +# TODO + +# 3.6 Configure Network Time Protocol (NTP) (Scored) +#[CIS - RHEL6 - 3.6 - NTPD not disabled {CIS: 1.1.1 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +# TODO. + +# 3.7 Remove LDAP (Not Scored) + +# 3.8 Disable NFS and RPC (Not Scored) +[CIS - RHEL6 - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 3.9 Remove DNS Server (Not Scored) +# TODO + +# 3.10 Remove FTP Server (Not Scored) +[CIS - RHEL6 - 3.10 - VSFTP enabled on xinetd {CIS: 3.10 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 3.11 Remove HTTP Server (Not Scored) +[CIS - RHEL6 - 3.11 - Disable standard boot services - Apache web server Enabled {CIS: 3.11 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dhttpd$; + +# 3.12 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - RHEL6 - 3.12 - imap enabled on xinetd {CIS: 3.12 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - RHEL6 - 3.12 - pop3 enabled on xinetd {CIS: 3.12 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 3.13 Remove Samba (Not Scored) +[CIS - RHEL6 - 3.13 - Disable standard boot services - Samba Enabled {CIS: 3.13 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 3.14 Remove HTTP Proxy Server (Not Scored) +[CIS - RHEL6 - 3.14 - Disable standard boot services - Squid Enabled {CIS: 3.14 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 3.15 Remove SNMP Server (Not Scored) +[CIS - RHEL6 - 3.15 - Disable standard boot services - SNMPD process Enabled {CIS: 3.15 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 3.16 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + + +############################################### +# 4 Network Configuration and Firewalls +############################################### + +############################################### +# 4.1 Modify Network Parameters (Host Only) +############################################### + +# 4.1.1 Disable IP Forwarding (Scored) +[CIS - RHEL6 - 4.1.1 - Network parameters - IP Forwarding enabled {CIS: 4.1.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 4.1.2 Disable Send Packet Redirects (Scored) +[CIS - RHEL6 - 4.1.2 - Network parameters - IP send redirects enabled {CIS: 4.1.2 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + + +############################################### +# 4.2 Modify Network Parameters (Host and Router) +############################################### + +# 4.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - RHEL6 - 4.2.1 - Network parameters - Source routing accepted {CIS: 4.2.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 4.2.2 Disable ICMP Redirect Acceptance (Scored) +#[CIS - RHEL6 - 4.2.2 - Network parameters - ICMP redirects accepted {CIS: 1.1.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +#f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +#f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 4.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - RHEL6 - 4.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 4.2.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 4.2.4 Log Suspicious Packets (Scored) +[CIS - RHEL6 - 4.2.4 - Network parameters - martians not logged {CIS: 4.2.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 4.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - RHEL6 - 4.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 4.2.5 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 4.2.6 Enable Bad Error Message Protection (Scored) +[CIS - RHEL6 - 4.2.6 - Network parameters - Bad error message protection not enabled {CIS: 4.2.6 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 4.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - RHEL6 - 4.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 4.2.7 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 4.2.8 Enable TCP SYN Cookies (Scored) +[CIS - RHEL6 - 4.2.8 - Network parameters - SYN Cookies not enabled {CIS: 4.2.8 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + + +############################################### +# 4.3 Wireless Networking +############################################### + +# 4.3.1 Deactivate Wireless Interfaces (Not Scored) + + +############################################### +# 4.4 Disable ipv6 +############################################### + +############################################### +# 4.4.1 Configure IPv6 +############################################### + +# 4.4.1.1 Disable IPv6 Router Advertisements (Not Scored) + +# 4.4.1.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 4.4.2 Disable IPv6 (Not Scored) + + +############################################### +# 4.5 Install TCP Wrappers +############################################### + +# 4.5.1 Install TCP Wrappers (Not Scored) + +# 4.5.2 Create /etc/hosts.allow (Not Scored) + +# 4.5.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 4.5.4 Create /etc/hosts.deny (Not Scored) + +# 4.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + + +############################################### +# 4.6 Uncommon Network Protocols +############################################### + +# 4.6.1 Disable DCCP (Not Scored) + +# 4.6.2 Disable SCTP (Not Scored) + +# 4.6.3 Disable RDS (Not Scored) + +# 4.6.4 Disable TIPC (Not Scored) + +# 4.7 Enable IPtables (Scored) +# TODO + +# 4.8 Enable IP6tables (Not Scored) + + +############################################### +# 5 Logging and Auditing +############################################### + +############################################### +# 5.1 Configure Syslog +############################################### + +# 5.1.1 Install the rsyslog package (Scored) +# TODO + +# 5.1.2 Activate the rsyslog Service (Scored) +# TODO + +# 5.1.3 Configure /etc/rsyslog.conf (Not Scored) + +# 5.1.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 5.1.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 5.1.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.2 Configure System Accounting (auditd) +############################################### + +############################################### +# 5.2.1 Configure Data Retention +############################################### + +# 5.2.1.1 Configure Audit Log Storage Size (Not Scored) + +# 5.2.1.2 Disable System on Audit Log Full (Not Scored) + +# 5.2.1.3 Keep All Auditing Information (Scored) + +# 5.2.2 Enable auditd Service (Scored) + +# 5.2.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 5.2.4 Record Events That Modify Date and Time Information (Scored) + +# 5.2.5 Record Events That Modify User/Group Information (Scored) + +# 5.2.6 Record Events That Modify the System’s Network Environment (Scored) + +# 5.2.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 5.2.8 Collect Login and Logout Events (Scored) + +# 5.2.9 Collect Session Initiation Information (Scored) + +# 5.2.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 5.2.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 5.2.12 Collect Use of Privileged Commands (Scored) + +# 5.2.13 Collect Successful File System Mounts (Scored) + +# 5.2.14 Collect File Deletion Events by User (Scored) + +# 5.2.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 5.2.16 Collect System Administrator Actions (sudolog) (Scored) + +# 5.2.17 Collect Kernel Module Loading and Unloading (Scored) + +# 5.2.18 Make the Audit Configuration Immutable (Scored) + +# 5.3 Configure logrotate (Not Scored) + + +############################################### +# 6 System Access, Authentication and Authorization +############################################### + +############################################### +# 6.1 Configure cron and anacron +############################################### + +# 6.1.1 Enable anacron Daemon (Scored) + +# 6.1.2 Enable cron Daemon (Scored) + +# 6.1.3 Set User/Group Owner and Permission on /etc/anacrontab (Scored) + +# 6.1.4 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 6.1.5 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 6.1.6 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 6.1.7 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 6.1.8 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 6.1.9 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 6.1.10 Restrict at Daemon (Scored) + +# 6.1.11 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 6.1 Configure SSH +############################################### + +# 6.2.1 Set SSH Protocol to 2 (Scored) +[CIS - RHEL6 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 6.2.2 Set LogLevel to INFO (Scored) + +# 6.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) + +# 6.2.4 Disable SSH X11 Forwarding (Scored) + +# 6.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) + +# 6.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - RHEL6 - 6.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 6.2.6 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 6.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - RHEL6 - 6.2.7 - SSH Configuration - Host based authentication enabled {CIS: 6.2.7 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 6.2.8 Disable SSH Root Login (Scored) +[CIS - RHEL6 - 6.2.8 - SSH Configuration - Root login allowed {CIS: 6.2.8 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + +# 6.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - RHEL6 - 6.2.9 - SSH Configuration - Empty passwords permitted {CIS: 6.2.9 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +# 6.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 6.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 6.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 6.2.13 Limit Access via SSH (Scored) + +# 6.2.14 Set SSH Banner (Scored) + + +############################################### +# 6.3 Configure PAM +############################################### + +# 6.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 6.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 6.3.3 Use pam_deny.so to Deny Services (Not Scored) + +# 6.3.4 Upgrade Password Hashing Algorithm to SHA-512 (Scored) + +# 6.3.5 Limit Password Reuse (Scored) + +# 6.4 Restrict root Login to System Console (Not Scored) + +# 6.5 Restrict Access to the su Command (Scored) + + +############################################### +# 7 User Accounts and Environment +############################################### + +############################################### +# 7.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 7.1.1 Set Password Expiration Days (Scored) + +# 7.1.2 Set Password Change Minimum Number of Days (Scored) + +# 7.1.3 Set Password Expiring Warning Days (Scored) + +# 7.2 Disable System Accounts (Scored) + +# 7.3 Set Default Group for root Account (Scored) + +# 7.4 Set Default umask for Users (Scored) + +# 7.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 8 Warning Banners +############################################### + +############################################### +# 8.1 Warning Banners for Standard Login Services +############################################### + +# 8.1 Set Warning Banner for Standard Login Services (Scored) + +# 8.2 Remove OS Information from Login Warning Banners (Scored) + +# 8.3 Set GNOME Warning Banner (Not Scored) + + +############################################### +# 9 System Maintenance +############################################### + +############################################### +# 9.1 Verify System File Permissions +############################################### + +# 9.1.1 Verify System File Permissions (Not Scored) + +# 9.1.2 Verify Permissions on /etc/passwd (Scored) + +# 9.1.3 Verify Permissions on /etc/shadow (Scored) + +# 9.1.4 Verify Permissions on /etc/gshadow (Scored) + +# 9.1.5 Verify Permissions on /etc/group (Scored) + +# 9.1.6 Verify User/Group Ownership on /etc/passwd (Scored) + +# 9.1.7 Verify User/Group Ownership on /etc/shadow (Scored) + +# 9.1.8 Verify User/Group Ownership on /etc/gshadow (Scored) + +# 9.1.9 Verify User/Group Ownership on /etc/group (Scored) + +# 9.1.10 Find World Writable Files (Not Scored) + +# 9.1.11 Find Un-owned Files and Directories (Scored) + +# 9.1.12 Find Un-grouped Files and Directories (Scored) + +# 9.1.13 Find SUID System Executables (Not Scored) + +# 9.1.14 Find SGID System Executables (Not Scored) + + +############################################### +# 9.2 Review User and Group Settings +############################################### + +# 9.2.1 Ensure Password Fields are Not Empty (Scored) + +# 9.2.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 9.2.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 9.2.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 9.2.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - RHEL6 - 9.2.5 - Non-root account with uid 0 {CIS: 9.2.5 RHEL6} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 9.2.6 Ensure root PATH Integrity (Scored) + +# 9.2.7 Check Permissions on User Home Directories (Scored) + +# 9.2.8 Check User Dot File Permissions (Scored) + +# 9.2.9 Check Permissions on User .netrc Files (Scored) + +# 9.2.10 Check for Presence of User .rhosts Files (Scored) + +# 9.2.11 Check Groups in /etc/passwd (Scored) + +# 9.2.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 9.2.13 Check User Home Directory Ownership (Scored) + +# 9.2.14 Check for Duplicate UIDs (Scored) + +# 9.2.15 Check for Duplicate GIDs (Scored) + +# 9.2.16 Check for Duplicate User Names (Scored) + +# 9.2.17 Check for Duplicate Group Names (Scored) + +# 9.2.18 Check for Presence of User .netrc Files (Scored) + +# 9.2.19 Check for Presence of User .forward Files (Scored) + + +# Other/Legacy Tests +[CIS - RHEL6 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - RHEL6 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/openarmor-rules/shared/cis_rhel7_linux_rcl.txt b/openarmor-rules/shared/cis_rhel7_linux_rcl.txt new file mode 100644 index 000000000..cf8a297b2 --- /dev/null +++ b/openarmor-rules/shared/cis_rhel7_linux_rcl.txt @@ -0,0 +1,818 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat / CentOS 7 +# Based on CIS Benchmark for Red Hat Enterprise Linux 7 v1.1.0 + +# Vars +$sshd_file=/etc/ssh/sshd_config; + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS Red Hat Enterprise Linux 7 Benchmark v1.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 7; +f:/etc/redhat-release -> r:^CentOS && r:release 7; +f:/etc/redhat-release -> r:^Cloud && r:release 7; +f:/etc/redhat-release -> r:^Oracle && r:release 7; +f:/etc/redhat-release -> r:^Better && r:release 7; +f:/etc/redhat-release -> r:^OpenVZ && r:release 7; + +# 1.1.1 /tmp: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /tmp is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 1.1.2 /tmp: nodev +[CIS - RHEL7 - 1.1.2 - Partition /tmp without 'nodev' set {CIS: 1.1.2 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.3 /tmp: nosuid +[CIS - RHEL7 - 1.1.3 - Partition /tmp without 'nosuid' set {CIS: 1.1.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 1.1.4 /tmp: noexec +[CIS - RHEL7 - 1.1.4 - Partition /tmp without 'noexec' set {CIS: 1.1.4 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:noexec; + +# 1.1.5 Build considerations - Partition scheme. +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 1.1.5 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 1.1.6 bind mount /var/tmp to /tmp +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 1.1.6 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 1.1.7 /var/log: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 1.1.7 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 1.1.8 /var/log/audit: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 1.1.8 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 1.1.9 /home: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 1.1.9 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 1.1.10 /home: nodev +[CIS - RHEL7 - 1.1.10 - Partition /home without 'nodev' set {CIS: 1.1.10 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 1.1.11 nodev on removable media partitions (not scored) +[CIS - RHEL7 - 1.1.11 - Removable partition /media without 'nodev' set {CIS: 1.1.11 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 1.1.12 noexec on removable media partitions (not scored) +[CIS - RHEL7 - 1.1.12 - Removable partition /media without 'noexec' set {CIS: 1.1.12 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 1.1.13 nosuid on removable media partitions (not scored) +[CIS - RHEL7 - 1.1.13 - Removable partition /media without 'nosuid' set {CIS: 1.1.13 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 1.1.14 /dev/shm: nodev +[CIS - RHEL7 - 1.1.14 - /dev/shm without 'nodev' set {CIS: 1.1.14 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 1.1.15 /dev/shm: nosuid +[CIS - RHEL7 - 1.1.15 - /dev/shm without 'nosuid' set {CIS: 1.1.15 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 1.1.16 /dev/shm: noexec +[CIS - RHEL7 - 1.1.16 - /dev/shm without 'noexec' set {CIS: 1.1.16 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 1.1.17 sticky bit on world writable directories (Scored) +# TODO + +# 1.1.18 disable cramfs (not scored) + +# 1.1.19 disable freevxfs (not scored) + +# 1.1.20 disable jffs2 (not scored) + +# 1.1.21 disable hfs (not scored) + +# 1.1.22 disable hfsplus (not scored) + +# 1.1.23 disable squashfs (not scored) + +# 1.1.24 disable udf (not scored) + + +########################################## +# 1.2 Software Updates +########################################## + +# 1.2.1 Configure rhn updates (not scored) + +# 1.2.2 verify RPM gpg keys (Scored) +# TODO + +# 1.2.3 verify gpgcheck enabled (Scored) +# TODO + +# 1.2.4 Disable rhnsd (not scored) + +# 1.2.5 Obtain Software Package Updates with yum (Not Scored) + +# 1.2.6 Obtain updates with yum (not scored) + + +############################################### +# 1.3 Advanced Intrusion Detection Environment +############################################### +# +# Skipped, this control is obsoleted by openarmor +# + +############################################### +# 1.4 Configure SELinux +############################################### + +# 1.4.1 enable selinux in /etc/grub.conf +[CIS - RHEL7 - 1.4.1 - SELinux Disabled in /etc/grub.conf {CIS: 1.4.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/grub.conf -> r:selinux=0; +f:/etc/grub2.cfg -> r:selinux=0; + +# 1.4.2 Set selinux state +[CIS - RHEL7 - 1.4.2 - SELinux not set to enforcing {CIS: 1.4.2 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/selinux/config -> !r:SELINUX=enforcing; + +# 1.4.3 Set seliux policy +[CIS - RHEL7 - 1.4.3 - SELinux policy not set to targeted {CIS: 1.4.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/selinux/config -> !r:SELINUXTYPE=targeted; + +# 1.4.4 Remove SETroubleshoot +[CIS - RHEL7 - 1.4.4 - SELinux setroubleshoot enabled {CIS: 1.4.4 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsetroubleshoot$; +f:/usr/share/dbus-1/services/sealert.service -> r:Exec=/usr/bin/sealert; + +# 1.4.5 Disable MCS Translation service mcstrans +[CIS - RHEL7 - 1.4.5 - SELinux mctrans enabled {CIS: 1.4.5 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dmctrans$; +f:/usr/lib/systemd/system/mcstransd.service -> r:ExecStart=/usr/sbin/mcstransd; + +# 1.4.6 Check for unconfined daemons +# TODO + + +############################################### +# 1.5 Secure Boot Settings +############################################### + +# 1.5.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) +# stat -L -c "%u %g" /boot/grub2/grub.cfg | egrep "0 0" + +# 1.5.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) +# stat -L -c "%a" /boot/grub2/grub.cfg | egrep ".00" + +# 1.5.3 Set Boot Loader Password (Scored) +[CIS - RHEL7 - 1.5.3 - GRUB Password not set {CIS: 1.5.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/boot/grub2/grub.cfg -> !r:^# && !r:password; + + + +############################################### +# 1.6 Additional Process Hardening +############################################### + +# 1.6.1 Restrict Core Dumps (Scored) +[CIS - RHEL7 - 1.6.1 - Interactive Boot not disabled {CIS: 1.6.1 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 1.6.1 Enable Randomized Virtual Memory Region Placement (Scored) +# Note this is also labeled 1.6.1 in the CIS benchmark. +[CIS - RHEL7 - 1.6.1 - Randomized Virtual Memory Region Placement not enabled {CIS: 1.6.3 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> !r:^2$; + + +############################################### +# 1.7 Use the Latest OS Release (Not Scored) +############################################### + + +############################################### +# 2 OS Services +############################################### + +############################################### +# 2.1 Remove Legacy Services +############################################### + +# 2.1.1 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - RHEL7 - 2.1.1 - Telnet enabled on xinetd {CIS: 2.1.1 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/telnet@.service -> r:ExecStart=-/usr/sbin/in.telnetd; + + +# 2.1.2 Remove telnet Clients (Scored) +# TODO + +# 2.1.3 Remove rsh-server (Scored) +[CIS - RHEL7 - 2.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.1.3 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; +# TODO (finish this) +f:/usr/lib/systemd/system/rexec@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rlogin@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rsh@.service -> r:ExecStart; + +# 2.1.4 Remove rsh (Scored) +# TODO + +# 2.1.5 Remove NIS Client (Scored) +[CIS - RHEL7 - 2.1.5 - Disable standard boot services - NIS (client) Enabled {CIS: 2.1.5 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; +f:/usr/lib/systemd/system/ypbind.service -> r:Exec; + +# 2.1.6 Remove NIS Server (Scored) +[CIS - RHEL7 - 2.1.6 - Disable standard boot services - NIS (server) Enabled {CIS: 2.1.6 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; +f:/usr/lib/systemd/system/ypserv.service -> r:Exec; + +# 2.1.7 Remove tftp (Scored) +# TODO + +# 2.1.8 Remove tftp-server (Scored) +[CIS - RHEL7 - 2.1.8 - tftpd enabled on xinetd {CIS: 2.1.8 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/tftp.service -> r:Exec; + +# 2.1.9 Remove talk (Scored) +# TODO + +# 2.1.10 Remove talk-server (Scored) +[CIS - RHEL7 - 2.1.10 - talk enabled on xinetd {CIS: 2.1.10 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/ntalk.service -> r:Exec; + +# 2.1.11 Remove xinetd (Scored) +[CIS - RHEL7 - 2.1.11 - xinetd detected {CIS: 2.1.11 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/usr/lib/systemd/system/xinetd.service -> r:Exec; + +# 2.1.12 Disable chargen-dgram (Scored) +[CIS - RHEL7 - 2.1.12 - chargen-dgram enabled on xinetd {CIS: 2.1.12 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen-dgram -> !r:^# && r:disable && r:no; + +# 2.1.13 Disable chargen-stream (Scored) +[CIS - RHEL7 - 2.1.13 - chargen-stream enabled on xinetd {CIS: 2.1.13 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen-stream -> !r:^# && r:disable && r:no; + +# 2.1.14 Disable daytime-dgram (Scored) +[CIS - RHEL7 - 2.1.14 - daytime-dgram enabled on xinetd {CIS: 2.1.14 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime-dgram -> !r:^# && r:disable && r:no; + +# 2.1.15 Disable daytime-stream (Scored) +[CIS - RHEL7 - 2.1.15 - daytime-stream enabled on xinetd {CIS: 2.1.15 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime-stream -> !r:^# && r:disable && r:no; + + +# 2.1.16 Disable echo-dgram (Scored) +[CIS - RHEL7 - 2.1.16 - echo-dgram enabled on xinetd {CIS: 2.1.16 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo-dgram -> !r:^# && r:disable && r:no; + +# 2.1.17 Disable echo-stream (Scored) +[CIS - RHEL7 - 2.1.17 - echo-stream enabled on xinetd {CIS: 2.1.17 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo-stream -> !r:^# && r:disable && r:no; + +# 2.1.18 Disable tcpmux-server (Scored) +[CIS - RHEL7 - 2.1.18 - tcpmux-server enabled on xinetd {CIS: 2.1.18 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/tcpmux-server -> !r:^# && r:disable && r:no; + + +############################################### +# 3 Special Purpose Services +############################################### + +# 3.1 Set Daemon umask (Scored) +[CIS - RHEL7 - 3.1 - Set daemon umask - Default umask is higher than 027 {CIS: 3.1 RHEL7} {PCI_DSS: 2.2.2}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/sysconfig/init -> !r:^# && r:^umask && <:umask 027; + +# 3.2 Remove X Windows (Scored) +[CIS - RHEL7 - 3.2 - X11 not disabled {CIS: 3.2 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/usr/lib/systemd/system/default.target -> r:Graphical; +p:gdm-x-session; + +# 3.3 Disable Avahi Server (Scored) +[CIS - RHEL7 - 3.2 - Avahi daemon not disabled {CIS: 3.3 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +p:avahi-daemon; + +# 3.4 Disable Print Server - CUPS (Not Scored) + +# 3.5 Remove DHCP Server (Scored) +[CIS - RHEL7 - 3.5 - DHCPnot disabled {CIS: 3.5 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/usr/lib/systemd/system/dhcpd.service -> r:Exec; + +# 3.6 Configure Network Time Protocol (NTP) (Scored) +[CIS - RHEL7 - 3.6 - NTPD not Configured {CIS: 3.6 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ntp.conf -> r:restrict default kod nomodify notrap nopeer noquery && r:^server; +f:/etc/sysconfig/ntpd -> r:OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"; + +# 3.7 Remove LDAP (Not Scored) + +# 3.8 Disable NFS and RPC (Not Scored) +[CIS - RHEL7 - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 3.9 Remove DNS Server (Not Scored) +# TODO + +# 3.10 Remove FTP Server (Not Scored) +[CIS - RHEL7 - 3.10 - VSFTP enabled on xinetd {CIS: 3.10 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 3.11 Remove HTTP Server (Not Scored) +[CIS - RHEL7 - 3.11 - Disable standard boot services - Apache web server Enabled {CIS: 3.11 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dhttpd$; + +# 3.12 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - RHEL7 - 3.12 - imap enabled on xinetd {CIS: 3.12 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - RHEL7 - 3.12 - pop3 enabled on xinetd {CIS: 3.12 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 3.13 Remove Samba (Not Scored) +[CIS - RHEL7 - 3.13 - Disable standard boot services - Samba Enabled {CIS: 3.13 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 3.14 Remove HTTP Proxy Server (Not Scored) +[CIS - RHEL7 - 3.14 - Disable standard boot services - Squid Enabled {CIS: 3.14 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 3.15 Remove SNMP Server (Not Scored) +[CIS - RHEL7 - 3.15 - Disable standard boot services - SNMPD process Enabled {CIS: 3.15 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 3.16 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + + +############################################### +# 4 Network Configuration and Firewalls +############################################### + +############################################### +# 4.1 Modify Network Parameters (Host Only) +############################################### + +# 4.1.1 Disable IP Forwarding (Scored) +[CIS - RHEL7 - 4.1.1 - Network parameters - IP Forwarding enabled {CIS: 4.1.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 4.1.2 Disable Send Packet Redirects (Scored) +[CIS - RHEL7 - 4.1.2 - Network parameters - IP send redirects enabled {CIS: 4.1.2 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + + +############################################### +# 4.2 Modify Network Parameters (Host and Router) +############################################### + +# 4.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - RHEL7 - 4.2.1 - Network parameters - Source routing accepted {CIS: 4.2.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 4.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - RHEL7 - 4.2.2 - Network parameters - ICMP redirects accepted {CIS: 1.1.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 4.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - RHEL7 - 4.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 4.2.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 4.2.4 Log Suspicious Packets (Scored) +[CIS - RHEL7 - 4.2.4 - Network parameters - martians not logged {CIS: 4.2.4 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 4.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - RHEL7 - 4.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 4.2.5 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 4.2.6 Enable Bad Error Message Protection (Scored) +[CIS - RHEL7 - 4.2.6 - Network parameters - Bad error message protection not enabled {CIS: 4.2.6 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 4.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - RHEL7 - 4.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 4.2.7 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 4.2.8 Enable TCP SYN Cookies (Scored) +[CIS - RHEL7 - 4.2.8 - Network parameters - SYN Cookies not enabled {CIS: 4.2.8 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + + +############################################### +# 4.3 Wireless Networking +############################################### + +# 4.3.1 Deactivate Wireless Interfaces (Not Scored) + + +############################################### +# 4.4 Disable ipv6 +############################################### + +############################################### +# 4.4.1 Configure IPv6 +############################################### + +# 4.4.1.1 Disable IPv6 Router Advertisements (Not Scored) + +# 4.4.1.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 4.4.2 Disable IPv6 (Not Scored) + + +############################################### +# 4.5 Install TCP Wrappers +############################################### + +# 4.5.1 Install TCP Wrappers (Not Scored) + +# 4.5.2 Create /etc/hosts.allow (Not Scored) + +# 4.5.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 4.5.4 Create /etc/hosts.deny (Not Scored) + +# 4.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + + +############################################### +# 4.6 Uncommon Network Protocols +############################################### + +# 4.6.1 Disable DCCP (Not Scored) + +# 4.6.2 Disable SCTP (Not Scored) + +# 4.6.3 Disable RDS (Not Scored) + +# 4.6.4 Disable TIPC (Not Scored) + +# 4.7 Enable IPtables (Scored) +#[CIS - RHEL7 - 4.7 - Uncommon Network Protocols - Firewalld not enabled {CIS: 4.7 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +#f:/usr/lib/systemd/system/firewalld.service -> TODO; + + +############################################### +# 5 Logging and Auditing +############################################### + +############################################### +# 5.1 Configure Syslog +############################################### + +# 5.1.1 Install the rsyslog package (Scored) +# TODO + +# 5.1.2 Activate the rsyslog Service (Scored) +# TODO + +# 5.1.3 Configure /etc/rsyslog.conf (Not Scored) + +# 5.1.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 5.1.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 5.1.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.2 Configure System Accounting (auditd) +############################################### + +############################################### +# 5.2.1 Configure Data Retention +############################################### + +# 5.2.1.1 Configure Audit Log Storage Size (Not Scored) + +# 5.2.1.2 Disable System on Audit Log Full (Not Scored) + +# 5.2.1.3 Keep All Auditing Information (Scored) + +# 5.2.2 Enable auditd Service (Scored) + +# 5.2.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 5.2.4 Record Events That Modify Date and Time Information (Scored) + +# 5.2.5 Record Events That Modify User/Group Information (Scored) + +# 5.2.6 Record Events That Modify the System’s Network Environment (Scored) + +# 5.2.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 5.2.8 Collect Login and Logout Events (Scored) + +# 5.2.9 Collect Session Initiation Information (Scored) + +# 5.2.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 5.2.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 5.2.12 Collect Use of Privileged Commands (Scored) + +# 5.2.13 Collect Successful File System Mounts (Scored) + +# 5.2.14 Collect File Deletion Events by User (Scored) + +# 5.2.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 5.2.16 Collect System Administrator Actions (sudolog) (Scored) + +# 5.2.17 Collect Kernel Module Loading and Unloading (Scored) + +# 5.2.18 Make the Audit Configuration Immutable (Scored) + +# 5.3 Configure logrotate (Not Scored) + + +############################################### +# 6 System Access, Authentication and Authorization +############################################### + +############################################### +# 6.1 Configure cron and anacron +############################################### + +# 6.1.1 Enable anacron Daemon (Scored) + +# 6.1.2 Enable cron Daemon (Scored) + +# 6.1.3 Set User/Group Owner and Permission on /etc/anacrontab (Scored) + +# 6.1.4 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 6.1.5 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 6.1.6 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 6.1.7 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 6.1.8 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 6.1.9 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 6.1.10 Restrict at Daemon (Scored) + +# 6.1.11 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 6.1 Configure SSH +############################################### + +# 6.2.1 Set SSH Protocol to 2 (Scored) +[CIS - RHEL7 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 6.2.2 Set LogLevel to INFO (Scored) +[CIS - RHEL7 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && !r:LogLevel\.+INFO; + +# 6.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) +# TODO + +# 6.2.4 Disable SSH X11 Forwarding (Scored) +# TODO + +# 6.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) +[ CIS - RHEL7 - 6.2.5 - SSH Configuration - Set SSH MaxAuthTries to 4 or Less {CIS - RHEL7 - 6.2.5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:$sshd_file -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:$sshd_file -> r:^#\s*MaxAuthTries; +f:$sshd_file -> !r:MaxAuthTries; + +# 6.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - RHEL7 - 6.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 6.2.6 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 6.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - RHEL7 - 6.2.7 - SSH Configuration - Host based authentication enabled {CIS: 6.2.7 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 6.2.8 Disable SSH Root Login (Scored) +[CIS - RHEL7 - 6.2.8 - SSH Configuration - Root login allowed {CIS: 6.2.8 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitRootLogin; + +# 6.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - RHEL7 - 6.2.9 - SSH Configuration - Empty passwords permitted {CIS: 6.2.9 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitEmptyPasswords; + +# 6.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 6.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 6.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 6.2.13 Limit Access via SSH (Scored) + +# 6.2.14 Set SSH Banner (Scored) + + +############################################### +# 6.3 Configure PAM +############################################### + +# 6.3.1 Upgrade Password Hashing Algorithm to SHA-512 (Scored) +# authconfig --test | grep hashing | grep sha512 + +# 6.3.2 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 6.3.3 Set Lockout for Failed Password Attempts (Not Scored) + +# 6.3.4 Limit Password Reuse (Scored) + + +# 6.4 Restrict root Login to System Console (Not Scored) + +# 6.5 Restrict Access to the su Command (Scored) + + +############################################### +# 7 User Accounts and Environment +############################################### + +############################################### +# 7.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 7.1.1 Set Password Expiration Days (Scored) + +# 7.1.2 Set Password Change Minimum Number of Days (Scored) + +# 7.1.3 Set Password Expiring Warning Days (Scored) + +# 7.2 Disable System Accounts (Scored) + +# 7.3 Set Default Group for root Account (Scored) + +# 7.4 Set Default umask for Users (Scored) + +# 7.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 8 Warning Banners +############################################### + +############################################### +# 8.1 Warning Banners for Standard Login Services +############################################### + +# 8.1 Set Warning Banner for Standard Login Services (Scored) + +# 8.2 Remove OS Information from Login Warning Banners (Scored) + +# 8.3 Set GNOME Warning Banner (Not Scored) + + +############################################### +# 9 System Maintenance +############################################### + +############################################### +# 9.1 Verify System File Permissions +############################################### + +# 9.1.1 Verify System File Permissions (Not Scored) + +# 9.1.2 Verify Permissions on /etc/passwd (Scored) + +# 9.1.3 Verify Permissions on /etc/shadow (Scored) + +# 9.1.4 Verify Permissions on /etc/gshadow (Scored) + +# 9.1.5 Verify Permissions on /etc/group (Scored) + +# 9.1.6 Verify User/Group Ownership on /etc/passwd (Scored) + +# 9.1.7 Verify User/Group Ownership on /etc/shadow (Scored) + +# 9.1.8 Verify User/Group Ownership on /etc/gshadow (Scored) + +# 9.1.9 Verify User/Group Ownership on /etc/group (Scored) + +# 9.1.10 Find World Writable Files (Not Scored) + +# 9.1.11 Find Un-owned Files and Directories (Scored) + +# 9.1.12 Find Un-grouped Files and Directories (Scored) + +# 9.1.13 Find SUID System Executables (Not Scored) + +# 9.1.14 Find SGID System Executables (Not Scored) + + +############################################### +# 9.2 Review User and Group Settings +############################################### + +# 9.2.1 Ensure Password Fields are Not Empty (Scored) + +# 9.2.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 9.2.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 9.2.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 9.2.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - RHEL7 - 9.2.5 - Non-root account with uid 0 {CIS: 9.2.5 RHEL7} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 9.2.6 Ensure root PATH Integrity (Scored) + +# 9.2.7 Check Permissions on User Home Directories (Scored) + +# 9.2.8 Check User Dot File Permissions (Scored) + +# 9.2.9 Check Permissions on User .netrc Files (Scored) + +# 9.2.10 Check for Presence of User .rhosts Files (Scored) + +# 9.2.11 Check Groups in /etc/passwd (Scored) + +# 9.2.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 9.2.13 Check User Home Directory Ownership (Scored) + +# 9.2.14 Check for Duplicate UIDs (Scored) + +# 9.2.15 Check for Duplicate GIDs (Scored) + +# 9.2.16 Check That Reserved UIDs Are Assigned to System Accounts (Scored) + +# 9.2.17 Check for Duplicate User Names (Scored) + +# 9.2.18 Check for Duplicate Group Names (Scored) + +# 9.2.19 Check for Presence of User .netrc Files (Scored) + +# 9.2.20 Check for Presence of User .forward Files (Scored) + + +# Other/Legacy Tests +[CIS - RHEL7 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - RHEL7 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/openarmor-rules/shared/cis_rhel_linux_rcl.txt b/openarmor-rules/shared/cis_rhel_linux_rcl.txt new file mode 100644 index 000000000..3c686f6aa --- /dev/null +++ b/openarmor-rules/shared/cis_rhel_linux_rcl.txt @@ -0,0 +1,281 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat (RHEL 2.1, 3.0, 4.0 and Fedora Core 1,2,3,4 and 5). +# Based on CIS Benchmark for Red Hat Enterprise Linux v1.0.5 + + + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + + +# Main one. Only valid for Red Hat/Fedora. +[CIS - Testing against the CIS Red Hat Enterprise Linux Benchmark v1.0.5] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 4; +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 3; +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 2.1; +f:/etc/fedora-release -> r:^Fedora && r:release 1; +f:/etc/fedora-release -> r:^Fedora && r:release 2; +f:/etc/fedora-release -> r:^Fedora && r:release 3; +f:/etc/fedora-release -> r:^Fedora && r:release 4; +f:/etc/fedora-release -> r:^Fedora && r:release 5; + + +# Build considerations - Partition scheme. +[CIS - Red Hat Linux - - Build considerations - Robust partition scheme - /var is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:/var; + +[CIS - Red Hat Linux - - Build considerations - Robust partition scheme - /home is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:/home; + + +# Section 1.3 - SSH configuration +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Protocol version 1 enabled {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - IgnoreRHosts disabled {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Empty passwords permitted {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Host based authentication enabled {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Root login allowed {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + + +# Section 1.4 Enable system accounting +#[CIS - Red Hat Linux - 1.4 - System Accounting - Sysstat not installed] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +#f:!/var/log/sa; + + +# Section 2.5 Install and run Bastille +#[CIS - Red Hat Linux - 1.5 - System harderning - Bastille is not installed] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +#f:!/etc/Bastille; + + +# Section 2 - Minimize xinetd services +[CIS - Red Hat Linux - 2.3 - Telnet enabled on xinetd {CIS: 2.3 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/telnet -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.4 - VSFTP enabled on xinetd {CIS: 2.4 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/vsftpd -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.4 - WU-FTP enabled on xinetd {CIS: 2.4 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/wu-ftpd -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.5 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.5 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/shell -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.6 - tftpd enabled on xinetd {CIS: 2.6 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/tftpd -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.7 - imap enabled on xinetd {CIS: 2.7 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/imap -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/imaps -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.8 - pop3 enabled on xinetd {CIS: 2.8 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/ipop3 -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/pop3s -> !r:^# && r:disable && r:no; + + +# Section 3 - Minimize boot services +[CIS - Red Hat Linux - 3.1 - Set daemon umask - Default umask is higher than 027 {CIS: 3.1 Red Hat Linux}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/init.d/functions -> !r:^# && r:^umask && >:umask 027; + +[CIS - Red Hat Linux - 3.4 - GUI login enabled {CIS: 3.4 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +[CIS - Red Hat Linux - 3.7 - Disable standard boot services - Samba Enabled {CIS: 3.7 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +[CIS - Red Hat Linux - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +[CIS - Red Hat Linux - 3.10 - Disable standard boot services - NIS Enabled {CIS: 3.10 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dypbind$; +d:$rc_dirs -> ^S\d\dypserv$; + +[CIS - Red Hat Linux - 3.13 - Disable standard boot services - NetFS Enabled {CIS: 3.13 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; + +[CIS - Red Hat Linux - 3.15 - Disable standard boot services - Apache web server Enabled {CIS: 3.15 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dapache$; +d:$rc_dirs -> ^S\d\dhttpd$; + +[CIS - Red Hat Linux - 3.15 - Disable standard boot services - TUX web server Enabled {CIS: 3.15 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dtux$; + +[CIS - Red Hat Linux - 3.16 - Disable standard boot services - SNMPD process Enabled {CIS: 3.16 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +[CIS - Red Hat Linux - 3.17 - Disable standard boot services - DNS server Enabled {CIS: 3.17 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - Red Hat Linux - 3.18 - Disable standard boot services - MySQL server Enabled {CIS: 3.18 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - Red Hat Linux - 3.18 - Disable standard boot services - PostgreSQL server Enabled {CIS: 3.18 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - Red Hat Linux - 3.19 - Disable standard boot services - Webmin Enabled {CIS: 3.19 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dwebmin$; + +[CIS - Red Hat Linux - 3.20 - Disable standard boot services - Squid Enabled {CIS: 3.20 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +[CIS - Red Hat Linux - 3.21 - Disable standard boot services - Kudzu hardware detection Enabled {CIS: 3.21 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + + +# Section 4 - Kernel tuning +[CIS - Red Hat Linux - 4.1 - Network parameters - Source routing accepted {CIS: 4.1 Red Hat Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +[CIS - Red Hat Linux - 4.1 - Network parameters - ICMP broadcasts accepted {CIS: 4.1 Red Hat Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +[CIS - Red Hat Linux - 4.2 - Network parameters - IP Forwarding enabled {CIS: 4.2 Red Hat Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + + +# Section 6 - Permissions +[CIS - Red Hat Linux - 6.1 - Partition /var without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/var && !r:nodev; + +[CIS - Red Hat Linux - 6.1 - Partition /tmp without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/tmp && !r:nodev; + +[CIS - Red Hat Linux - 6.1 - Partition /opt without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/opt && !r:nodev; + +[CIS - Red Hat Linux - 6.1 - Partition /home without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/home && !r:nodev ; + +[CIS - Red Hat Linux - 6.2 - Removable partition /media without 'nodev' set {CIS: 6.2 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +[CIS - Red Hat Linux - 6.2 - Removable partition /media without 'nosuid' set {CIS: 6.2 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +[CIS - Red Hat Linux - 6.3 - User-mounted removable partition allowed on the console {CIS: 6.3 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + + +# Section 7 - Access and authentication +[CIS - Red Hat Linux - 7.8 - LILO Password not set {CIS: 7.8 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/lilo.conf -> !r:^# && !r:restricted; +f:/etc/lilo.conf -> !r:^# && !r:password=; + +[CIS - Red Hat Linux - 7.8 - GRUB Password not set {CIS: 7.8 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +[CIS - Red Hat Linux - 8.2 - Account with empty password present {CIS: 8.2 Red Hat Linux} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - Red Hat Linux - SN.11 - Non-root account with uid 0 {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + + +# Tests specific for VMware ESX - Runs on Red Hat Linux - +# Will not be tested anywhere else. +[VMware ESX - Testing against the Security Harderning benchmark VI3 for ESX 3.5] [any required] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +f:/etc/vmware-release -> r:^VMware ESX; + + +# Virtual Machine Files and Settings - 1 +# 1.1 +[VMware ESX - VM settings - Copy operation between guest and console enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.copy.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.copy.disable && r:false; + +# 1.2 +[VMware ESX - VM settings - Paste operation between guest and console enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.paste.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.paste.disable && r:false; + +# 1.3 +[VMware ESX - VM settings - GUI Options enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.setGUIOptions.enable && r:true; + +# 1.4 +[VMware ESX - VM settings - Data Flow from the Virtual Machine to the Datastore not limited - Rotate size not 100KB] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^log.rotateSize; +d:/vmfs/volumes -> .vmx$ -> r:^log.rotateSize && !r:"100000"; + +# 1.5 +[VMware ESX - VM settings - Data Flow from the Virtual Machine to the Datastore not limited - Maximum number of logs not 10] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^log.keepOld; +d:/vmfs/volumes -> .vmx$ -> r:^log.keepOld && r:"10"; + +# 1.6 +[VMware ESX - VM settings - Data Flow from the Virtual Machine to the Datastore not limited - Guests allowed to write SetInfo data to config] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.setinfo.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.setinfo.disable && r:false; + +# 1.7 +[VMware ESX - VM settings - Nonpersistent Disks being used] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^scsi\d:\d.mode && r:!independent-nonpersistent; + +# 1.8 +[VMware ESX - VM settings - Floppy drive present] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^floppy\d+.present && r:!false; + +[VMware ESX - VM settings - Serial port present] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^serial\d+.present && r:!false; + +[VMware ESX - VM settings - Parallel port present] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^parallel\d+.present && r:!false; + +# 1.9 +[VMware ESX - VM settings - Unauthorized Removal or Connection of Devices allowed] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^Isolation.tools.connectable.disable; +d:/vmfs/volumes -> .vmx$ -> r:^Isolation.tools.connectable.disable && r:false; + +# 1.10 +[VMware ESX - VM settings - Avoid Denial of Service Caused by Virtual Disk Modification Operations - diskWiper enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.diskWiper.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.diskWiper.disable && r:false; + +[VMware ESX - VM settings - Avoid Denial of Service Caused by Virtual Disk Modification Operations - diskShrink enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.diskShrink.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.diskShrink.disable && r:false; + + +# Configuring the Service Console in ESX 3.5 - 2 +# 2.1 diff --git a/openarmor-rules/shared/cis_sles11_linux_rcl.txt b/openarmor-rules/shared/cis_sles11_linux_rcl.txt new file mode 100644 index 000000000..1eb8270cd --- /dev/null +++ b/openarmor-rules/shared/cis_sles11_linux_rcl.txt @@ -0,0 +1,728 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for SUSE SLES 11 +# Based on CIS Benchmark for SUSE Linux Enterprise Server 11 v1.1.0 + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS SUSE Linux Enterprise Server 11 Benchmark v1.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP1"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP2"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP3"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP4"; + +# 2.1 /tmp: partition +[CIS - SLES11 - 2.1 - Build considerations - Robust partition scheme - /tmp is not on its own partition {CIS: 2.2 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 2.2 /tmp: nodev +[CIS - SLES11 - 2.2 - Partition /tmp without 'nodev' set {CIS: 2.2 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.3 /tmp: nosuid +[CIS - SLES11 - 2.3 - Partition /tmp without 'nosuid' set {CIS: 2.3 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 2.4 /tmp: noexec +[CIS - SLES11 - 2.4 - Partition /tmp without 'noexec' set {CIS: 2.4 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.5 Build considerations - Partition scheme. +[CIS - SLES11 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 2.5 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 2.6 bind mount /var/tmp to /tmp +[CIS - SLES11 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 2.6 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 2.7 /var/log: partition +[CIS - SLES11 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 2.7 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 2.8 /var/log/audit: partition +[CIS - SLES11 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 2.8 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 2.9 /home: partition +[CIS - SLES11 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 2.9 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 2.10 /home: nodev +[CIS - SLES11 - 2.10 - Partition /home without 'nodev' set {CIS: 2.10 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 2.11 nodev on removable media partitions (not scored) +[CIS - SLES11 - 2.11 - Removable partition /media without 'nodev' set {CIS: 2.11 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 2.12 noexec on removable media partitions (not scored) +[CIS - SLES11 - 2.12 - Removable partition /media without 'noexec' set {CIS: 2.12 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 2.13 nosuid on removable media partitions (not scored) +[CIS - SLES11 - 2.13 - Removable partition /media without 'nosuid' set {CIS: 2.13 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 2.14 /dev/shm: nodev +[CIS - SLES11 - 2.14 - /dev/shm without 'nodev' set {CIS: 2.14 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 2.15 /dev/shm: nosuid +[CIS - SLES11 - 2.15 - /dev/shm without 'nosuid' set {CIS: 2.15 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 2.16 /dev/shm: noexec +[CIS - SLES11 - 2.16 - /dev/shm without 'noexec' set {CIS: 2.16 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 2.17 sticky bit on world writable directories (Scored) +# TODO + +# 2.18 disable cramfs (not scored) + +# 2.19 disable freevxfs (not scored) + +# 2.20 disable jffs2 (not scored) + +# 2.21 disable hfs (not scored) + +# 2.22 disable hfsplus (not scored) + +# 2.23 disable squashfs (not scored) + +# 2.24 disable udf (not scored) + +# 2.25 disable automounting (Scored) +# TODO + +############################################### +# 3 Secure Boot Settings +############################################### + +# 3.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) +# stat -L -c "%u %g" /boot/grub2/grub.cfg | egrep "0 0" + +# 3.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) +# stat -L -c "%a" /boot/grub2/grub.cfg | egrep ".00" + +# 3.3 Set Boot Loader Password (Scored) +[CIS - SLES11 - 3.3 - GRUB Password not set {CIS: 3.3 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/boot/grub2/grub.cfg -> !r:^# && !r:password; + +# 3.4 Require Authentication for Single-User Mode (Scored) + +# 3.5 Disable Interactive Boot (Scored) + +############################################### +# 4 Additional Process Hardening +############################################### + +# 4.1 Restrict Core Dumps (Scored) +[CIS - SLES11 - 4.1 - Interactive Boot not disabled {CIS: 4.1 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 4.2 Enable XD/NX Support on 32-bit x86 Systems (Not Scored) +# TODO + +# 4.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - SLES11 - 4.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 4.3 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 2; + +# 4.4 Disable Prelink (Scored) +# TODO + +# 4.5 Activate AppArmor (Scored) +# TODO + +############################################### +# 5 OS Services +############################################### + +############################################### +# 5.1 Remove Legacy Services +############################################### + +# 5.1.1 Remove NIS Server (Scored) +[CIS - SLES11 - 5.1.1 - Disable standard boot services - NIS (server) Enabled {CIS: 5.1.1 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; + +# 5.1.2 Remove NIS Client (Scored) +[CIS - SLES11 - 5.1.2 - Disable standard boot services - NIS (client) Enabled {CIS: 51.2 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; + +# 5.1.3 Remove rsh-server (Scored) +[CIS - SLES11 - 5.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 5.1.3 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; + +# 5.1.4 Remove rsh client (Scored) +# TODO + +# 5.1.5 Remove talk-server (Scored) +[CIS - SLES11 - 5.1.5 - talk enabled on xinetd {CIS: 5.1.5 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; + +# 5.1.6 Remove talk client (Scored) +# TODO + +# 5.1.7 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - SLES11 - 5.1.7 - Telnet enabled on xinetd {CIS: 5.1.7 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; + +# 5.1.8 Remove tftp-server (Scored) +[CIS - SLES11 - 5.1.8 - tftpd enabled on xinetd {CIS: 5.1.8 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; + +# 5.1.9 Remove xinetd (Scored) +[CIS - SLES11 - 5.1.9 - xinetd detected {CIS: 5.1.9 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] + +# 5.2 Disable chargen-udp (Scored) +[CIS - SLES11 - 5.2 - chargen-udp enabled on xinetd {CIS: 5.2 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen-udp -> !r:^# && r:disable && r:no; + +# 5.3 Disable chargen (Scored) +[CIS - SLES11 - 5.3 - chargen enabled on xinetd {CIS: 5.3 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen -> !r:^# && r:disable && r:no; + +# 5.4 Disable daytime-udp (Scored) +[CIS - SLES11 - 5.4 - daytime-udp enabled on xinetd {CIS: 5.4 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime-udp -> !r:^# && r:disable && r:no; + +# 5.5 Disable daytime (Scored) +[CIS - SLES11 - 5.5 - daytime enabled on xinetd {CIS: 5.5 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime -> !r:^# && r:disable && r:no; + + +# 5.6 Disable echo-udp (Scored) +[CIS - SLES11 - 5.6 - echo-udp enabled on xinetd {CIS: 5.6 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo-udp -> !r:^# && r:disable && r:no; + +# 5.7 Disable echo (Scored) +[CIS - SLES11 - 5.7 - echo enabled on xinetd {CIS: 5.7 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo -> !r:^# && r:disable && r:no; + +# 5.8 Disable discard-udp (Scored) +[CIS - SLES11 - 5.8 - discard-udp enabled on xinetd {CIS: 5.8 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/discard-udp -> !r:^# && r:disable && r:no; + +# 5.9 Disable discard (Scored) +[CIS - SLES11 - 5.9 - discard enabled on xinetd {CIS: 5.9 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/discard -> !r:^# && r:disable && r:no; + +# 5.10 Disable time-udp (Scored) +[CIS - SLES11 - 5.10 - time-udp enabled on xinetd {CIS: 5.10 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/time-udp -> !r:^# && r:disable && r:no; + +# 5.11 Disable time (Scored) +[CIS - SLES11 - 5.11 - time enabled on xinetd {CIS: 5.11 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/time -> !r:^# && r:disable && r:no; + +############################################### +# 6 Special Purpose Services +############################################### + +# 6.1 Remove X Windows (Scored) +[CIS - SLES11 - 6.1 - X11 not disabled {CIS: 6.1 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +# 6.2 Disable Avahi Server (Scored) +[CIS - SLES11 - 6.2 - Avahi daemon not disabled {CIS: 6.2 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +p:avahi-daemon; + +# 6.3 Disable Print Server - CUPS (Not Scored) +#TODO + +# 6.4 Remove DHCP Server (Scored) +#[CIS - SLES11 - 6.4 - DHCPnot disabled {CIS: 6.4 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dhcpd$; +d:$rc_dirs -> ^S\d\dhcpd6$; + +# 6.5 Configure Network Time Protocol (NTP) (Scored) +#TODO Chrony +[CIS - SLES11 - 6.5 - NTPD not Configured {CIS: 6.5 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ntp.conf -> r:restrict default kod nomodify notrap nopeer noquery && r:^server; +f:/etc/sysconfig/ntpd -> r:OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"; + +# 6.6 Remove LDAP (Not Scored) +#TODO + +# 6.7 Disable NFS and RPC (Not Scored) +[CIS - SLES11 - 6.7 - Disable standard boot services - NFS Enabled {CIS: 6.7 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 6.8 Remove DNS Server (Not Scored) +# TODO + +# 6.9 Remove FTP Server (Not Scored) +[CIS - SLES11 - 6.9 - VSFTP enabled on xinetd {CIS: 6.9 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 6.10 Remove HTTP Server (Not Scored) +[CIS - SLES11 - 6.10 - Disable standard boot services - Apache web server Enabled {CIS: 6.10 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dapache2$; + +# 6.11 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - SLES11 - 6.11 - imap enabled on xinetd {CIS: 6.11 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - SLES11 - 6.11 - pop3 enabled on xinetd {CIS: 6.11 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 6.12 Remove Samba (Not Scored) +[CIS - SLES11 - 6.12 - Disable standard boot services - Samba Enabled {CIS: 6.12 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 6.13 Remove HTTP Proxy Server (Not Scored) +[CIS - SLES11 - 6.13 - Disable standard boot services - Squid Enabled {CIS: 6.13 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 6.14 Remove SNMP Server (Not Scored) +[CIS - SLES11 - 6.14 - Disable standard boot services - SNMPD process Enabled {CIS: 6.14 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 6.15 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + +# 6.16 Ensure rsync service is not enabled (Scored) +[CIS - SLES11 - 6.16 - Disable standard boot services - rsyncd process Enabled {CIS: 6.16 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\drsyncd$; + +# 6.17 Ensure Biosdevname is not enabled (Scored) +# TODO + +############################################### +# 7 Network Configuration and Firewalls +############################################### + +############################################### +# 7.1 Modify Network Parameters (Host Only) +############################################### + +# 7.1.1 Disable IP Forwarding (Scored) +[CIS - SLES11 - 7.1.1 - Network parameters - IP Forwarding enabled {CIS: 7.1.1 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 7.1.2 Disable Send Packet Redirects (Scored) +[CIS - SLES11 - 7.1.2 - Network parameters - IP send redirects enabled {CIS: 7.1.2 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + +############################################### +# 7.2 Modify Network Parameters (Host and Router) +############################################### + +# 7.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - SLES11 - 7.2.1 - Network parameters - Source routing accepted {CIS: 7.2.1 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 7.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - SLES11 - 7.2.2 - Network parameters - ICMP redirects accepted {CIS: 7.2.2 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 7.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - SLES11 - 7.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 7.2.3 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 7.2.4 Log Suspicious Packets (Scored) +[CIS - SLES11 - 7.2.4 - Network parameters - martians not logged {CIS: 7.2.4 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 7.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - SLES11 - 7.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 7.2.5 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 7.2.6 Enable Bad Error Message Protection (Scored) +[CIS - SLES11 - 7.2.6 - Network parameters - Bad error message protection not enabled {CIS: 7.2.6 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 7.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - SLES11 - 7.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 7.2.7 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 7.2.8 Enable TCP SYN Cookies (Scored) +[CIS - SLES11 - 7.2.8 - Network parameters - SYN Cookies not enabled {CIS: 7.2.8 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + +############################################### +# 7.3 Configure IPv6 +############################################### + +# 7.3.1 Disable IPv6 Router Advertisements (Not Scored) + +# 7.3.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 7.3.3 Disable IPv6 (Not Scored) + +############################################### +# 7.4 Install TCP Wrappers +############################################### + +# 7.4.1 Install TCP Wrappers (Not Scored) + +# 7.4.2 Create /etc/hosts.allow (Not Scored) + +# 7.4.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 7.4.4 Create /etc/hosts.deny (Not Scored) + +# 7.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + +############################################### +# 7.5 Uncommon Network Protocols +############################################### + +# 7.5.1 Disable DCCP (Not Scored) + +# 7.5.2 Disable SCTP (Not Scored) + +# 7.5.3 Disable RDS (Not Scored) + +# 7.5.4 Disable TIPC (Not Scored) + +# 7.6 Deactivate Wireless Interfaces (Not Scored) + +# 7.7 Enable SuSEfirewall2 (Scored) + +# 7.8 Limit access to trusted networks (Not Scored) + +############################################### +# 8 Logging and Auditing +############################################### + +############################################### +# 8.1 Configure System Accounting (auditd) +############################################### + +############################################### +# 8.1.1 Configure Data Retention +############################################### + +# 8.1.1.1 Configure Audit Log Storage Size (Not Scored) + +# 8.1.1.2 Disable System on Audit Log Full (Not Scored) + +# 8.1.1.3 Keep All Auditing Information (Scored) + +# 8.1.2 Enable auditd Service (Scored) + +# 8.1.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 8.1.4 Record Events That Modify Date and Time Information (Scored) + +# 8.1.5 Record Events That Modify User/Group Information (Scored) + +# 8.1.6 Record Events That Modify the System’s Network Environment (Scored) + +# 8.1.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 8.1.8 Collect Login and Logout Events (Scored) + +# 8.1.9 Collect Session Initiation Information (Scored) + +# 8.1.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 8.1.12 Collect Use of Privileged Commands (Scored) + +# 8.1.13 Collect Successful File System Mounts (Scored) + +# 8.1.14 Collect File Deletion Events by User (Scored) + +# 8.1.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 8.1.16 Collect System Administrator Actions (sudolog) (Scored) + +# 8.1.17 Collect Kernel Module Loading and Unloading (Scored) + +# 8.1.18 Make the Audit Configuration Immutable (Scored) + +############################################### +# 8.2 Configure rsyslog +############################################### + +# 8.2.1 Install the rsyslog package (Scored) +# TODO + +# 8.2.2 Activate the rsyslog Service (Scored) +# TODO + +# 8.2.3 Configure /etc/rsyslog.conf (Not Scored) + +# 8.2.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + +############################################### +# 8.3 Advanced Intrusion Detection Environment (AIDE) +############################################### + +# 8.3.1 Install AIDE (Scored) + +# 8.3.2 Implement Periodic Execution of File Integrity (Scored) + +# 8.4 Configure logrotate (Not Scored) + +############################################### +# 9 System Access, Authentication and Authorization +############################################### + +############################################### +# 9.1 Configure cron and anacron +############################################### + +# 9.1.1 Enable cron Daemon (Scored) + +# 9.1.2 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 9.1.3 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 9.1.4 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 9.1.5 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 9.1.6 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 9.1.7 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 9.1.8 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 9.2 Configure SSH +############################################### + +# 9.2.1 Set SSH Protocol to 2 (Scored) +[CIS - SLES11 - 9.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 9.2.1 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 9.2.2 Set LogLevel to INFO (Scored) +[CIS - SLES11 - 9.2.1 - SSH Configuration - Loglevel not INFO {CIS: 9.2.1 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && !r:LogLevel\.+INFO; + +# 9.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) +# TODO + +# 9.2.4 Disable SSH X11 Forwarding (Scored) +# TODO + +# 9.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) +[ CIS - SLES11 - 9.2.5 - SSH Configuration - Set SSH MaxAuthTries to 4 or Less {CIS - SLES11 - 9.2.5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:/etc/ssh/sshd_config -> r:^#\s*MaxAuthTries; +f:/etc/ssh/sshd_config -> !r:MaxAuthTries; + +# 9.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - SLES11 - 9.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 9.2.6 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 9.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - SLES11 - 9.2.7 - SSH Configuration - Host based authentication enabled {CIS: 9.2.7 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 9.2.8 Disable SSH Root Login (Scored) +[CIS - SLES11 - 9.2.8 - SSH Configuration - Root login allowed {CIS: 9.2.8 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitRootLogin; + +# 9.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - SLES11 - 9.2.9 - SSH Configuration - Empty passwords permitted {CIS: 9.2.9 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitEmptyPasswords; + +# 9.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 9.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 9.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 9.2.13 Limit Access via SSH (Scored) + +# 9.2.14 Set SSH Banner (Scored) + +############################################### +# 9.3 Configure PAM +############################################### + +# 9.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 9.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 9.3.3 Limit Password Reuse (Scored) + +# 9.4 Restrict root Login to System Console (Not Scored) + +# 9.5 Restrict Access to the su Command (Scored) + +############################################### +# 10 User Accounts and Environment +############################################### + +############################################### +# 10.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 10.1.1 Set Password Expiration Days (Scored) + +# 10.1.2 Set Password Change Minimum Number of Days (Scored) + +# 10.1.3 Set Password Expiring Warning Days (Scored) + +# 10.2 Disable System Accounts (Scored) + +# 10.3 Set Default Group for root Account (Scored) + +# 10.4 Set Default umask for Users (Scored) + +# 10.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 11 Warning Banners +############################################### + +# 11.1 Set Warning Banner for Standard Login Services (Scored) + +# 11.2 Remove OS Information from Login Warning Banners (Scored) + +# 11.3 Set Graphical Warning Banner (Not Scored) + +############################################### +# 12 Verify System File Permissions +############################################### + +# 12.1 Verify System File Permissions (Not Scored) + +# 12.2 Verify Permissions on /etc/passwd (Scored) + +# 12.3 Verify Permissions on /etc/shadow (Scored) + +# 12.4 Verify Permissions on /etc/group (Scored) + +# 12.5 Verify User/Group Ownership on /etc/passwd (Scored) + +# 12.6 Verify User/Group Ownership on /etc/shadow (Scored) + +# 12.7 Verify User/Group Ownership on /etc/group (Scored) + +# 12.8 Find World Writable Files (Not Scored) + +# 12.9 Find Un-owned Files and Directories (Scored) + +# 12.10 Find Un-grouped Files and Directories (Scored) + +# 12.11 Find SUID System Executables (Not Scored) + +# 12.12 Find SGID System Executables (Not Scored) + +############################################### +# 13 Review User and Group Settings +############################################### + +# 13.1 Ensure Password Fields are Not Empty (Scored) + +# 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 13.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 13.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - SLES11 - 13.5 - Non-root account with uid 0 {CIS: 13.5 SLES11} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 13.6 Ensure root PATH Integrity (Scored) + +# 13.7 Check Permissions on User Home Directories (Scored) + +# 13.8 Check User Dot File Permissions (Scored) + +# 13.9 Check Permissions on User .netrc Files (Scored) + +# 13.10 Check for Presence of User .rhosts Files (Scored) + +# 13.11 Check Groups in /etc/passwd (Scored) + +# 13.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 13.13 Check User Home Directory Ownership (Scored) + +# 13.14 Check for Duplicate UIDs (Scored) + +# 13.15 Check for Duplicate GIDs (Scored) + +# 13.16 Check for Duplicate User Names (Scored) + +# 13.17 Check for Duplicate Group Names (Scored) + +# 13.18 Check for Presence of User .netrc Files (Scored) + +# 13.19 Check for Presence of User .forward Files (Scored) + +# 13.20 Ensure shadow group is empty (Scored) + + +# Other/Legacy Tests +[CIS - SLES11 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - SLES11 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - SLES11 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/openarmor-rules/shared/cis_sles12_linux_rcl.txt b/openarmor-rules/shared/cis_sles12_linux_rcl.txt new file mode 100644 index 000000000..1241ab6c6 --- /dev/null +++ b/openarmor-rules/shared/cis_sles12_linux_rcl.txt @@ -0,0 +1,734 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for SUSE SLES 12 +# Based on CIS Benchmark for SUSE Linux Enterprise Server 12 v1.0.0 + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS SUSE Linux Enterprise Server 12 Benchmark v1.0.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP1"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP2"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP4"; + +# 2.1 /tmp: partition +[CIS - SLES12 - 2.1 - Build considerations - Robust partition scheme - /tmp is not on its own partition {CIS: 2.2 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 2.2 /tmp: nodev +[CIS - SLES12 - 2.2 - Partition /tmp without 'nodev' set {CIS: 2.2 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.3 /tmp: nosuid +[CIS - SLES12 - 2.3 - Partition /tmp without 'nosuid' set {CIS: 2.3 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 2.4 /tmp: noexec +[CIS - SLES12 - 2.4 - Partition /tmp without 'noexec' set {CIS: 2.4 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.5 Build considerations - Partition scheme. +[CIS - SLES12 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 2.5 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 2.6 bind mount /var/tmp to /tmp +[CIS - SLES12 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 2.6 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 2.7 /var/log: partition +[CIS - SLES12 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 2.7 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 2.8 /var/log/audit: partition +[CIS - SLES12 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 2.8 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 2.9 /home: partition +[CIS - SLES12 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 2.9 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 2.10 /home: nodev +[CIS - SLES12 - 2.10 - Partition /home without 'nodev' set {CIS: 2.10 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 2.11 nodev on removable media partitions (not scored) +[CIS - SLES12 - 2.11 - Removable partition /media without 'nodev' set {CIS: 2.11 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 2.12 noexec on removable media partitions (not scored) +[CIS - SLES12 - 2.12 - Removable partition /media without 'noexec' set {CIS: 2.12 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 2.13 nosuid on removable media partitions (not scored) +[CIS - SLES12 - 2.13 - Removable partition /media without 'nosuid' set {CIS: 2.13 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 2.14 /dev/shm: nodev +[CIS - SLES12 - 2.14 - /dev/shm without 'nodev' set {CIS: 2.14 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 2.15 /dev/shm: nosuid +[CIS - SLES12 - 2.15 - /dev/shm without 'nosuid' set {CIS: 2.15 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 2.16 /dev/shm: noexec +[CIS - SLES12 - 2.16 - /dev/shm without 'noexec' set {CIS: 2.16 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 2.17 sticky bit on world writable directories (Scored) +# TODO + +# 2.18 disable cramfs (not scored) + +# 2.19 disable freevxfs (not scored) + +# 2.20 disable jffs2 (not scored) + +# 2.21 disable hfs (not scored) + +# 2.22 disable hfsplus (not scored) + +# 2.23 disable squashfs (not scored) + +# 2.24 disable udf (not scored) + +# 2.25 disable automounting (Scored) +# TODO + +############################################### +# 3 Secure Boot Settings +############################################### + +# 3.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) +# stat -L -c "%u %g" /boot/grub2/grub.cfg | egrep "0 0" + +# 3.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) +# stat -L -c "%a" /boot/grub2/grub.cfg | egrep ".00" + +# 3.3 Set Boot Loader Password (Scored) +[CIS - SLES12 - 3.3 - GRUB Password not set {CIS: 3.3 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/boot/grub2/grub.cfg -> !r:^# && !r:password; + +############################################### +# 4 Additional Process Hardening +############################################### + +# 4.1 Restrict Core Dumps (Scored) +[CIS - SLES12 - 4.1 - Interactive Boot not disabled {CIS: 4.1 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 4.2 Enable XD/NX Support on 32-bit x86 Systems (Not Scored) +# TODO + +# 4.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - SLES12 - 4.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 4.3 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 2; + +# 4.4 Disable Prelink (Scored) +# TODO + +# 4.5 Activate AppArmor (Scored) +# TODO + +############################################### +# 5 OS Services +############################################### + +############################################### +# 5.1 Remove Legacy Services +############################################### + +# 5.1.1 Remove NIS Server (Scored) +[CIS - SLES12 - 5.1.1 - Disable standard boot services - NIS (server) Enabled {CIS: 5.1.1 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; +f:/usr/lib/systemd/system/ypserv.service -> r:Exec; + +# 5.1.2 Remove NIS Client (Scored) +[CIS - SLES12 - 5.1.2 - Disable standard boot services - NIS (client) Enabled {CIS: 51.2 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; +f:/usr/lib/systemd/system/ypbind.service -> r:Exec; + +# 5.1.3 Remove rsh-server (Scored) +[CIS - SLES12 - 5.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 5.1.3 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; +# TODO (finish this) +f:/usr/lib/systemd/system/rexec@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rlogin@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rsh@.service -> r:ExecStart; + +# 5.1.4 Remove rsh client (Scored) +# TODO + +# 5.1.5 Remove talk-server (Scored) +[CIS - SLES12 - 5.1.5 - talk enabled on xinetd {CIS: 5.1.5 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/ntalk.service -> r:Exec; + +# 5.1.6 Remove talk client (Scored) +# TODO + +# 5.1.7 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - SLES12 - 5.1.7 - Telnet enabled on xinetd {CIS: 5.1.7 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/telnet@.service -> r:ExecStart=-/usr/sbin/in.telnetd; + +# 5.1.8 Remove tftp-server (Scored) +[CIS - SLES12 - 5.1.8 - tftpd enabled on xinetd {CIS: 5.1.8 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/tftp.service -> r:Exec; + +# 5.1.9 Remove xinetd (Scored) +[CIS - SLES12 - 5.1.9 - xinetd detected {CIS: 5.1.9 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/usr/lib/systemd/system/xinetd.service -> r:Exec; + +# 5.2 Disable chargen-udp (Scored) +[CIS - SLES12 - 5.2 - chargen-udp enabled on xinetd {CIS: 5.2 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/chargen-udp -> !r:^# && r:disable && r:no; + +# 5.3 Disable chargen (Scored) +[CIS - SLES12 - 5.3 - chargen enabled on xinetd {CIS: 5.3 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/chargen -> !r:^# && r:disable && r:no; + +# 5.4 Disable daytime-udp (Scored) +[CIS - SLES12 - 5.4 - daytime-udp enabled on xinetd {CIS: 5.4 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/daytime-udp -> !r:^# && r:disable && r:no; + +# 5.5 Disable daytime (Scored) +[CIS - SLES12 - 5.5 - daytime enabled on xinetd {CIS: 5.5 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/daytime -> !r:^# && r:disable && r:no; + + +# 5.6 Disable echo-udp (Scored) +[CIS - SLES12 - 5.6 - echo-udp enabled on xinetd {CIS: 5.6 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/echo-udp -> !r:^# && r:disable && r:no; + +# 5.7 Disable echo (Scored) +[CIS - SLES12 - 5.7 - echo enabled on xinetd {CIS: 5.7 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/echo -> !r:^# && r:disable && r:no; + +# 5.8 Disable discard-udp (Scored) +[CIS - SLES12 - 5.8 - discard-udp enabled on xinetd {CIS: 5.8 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/discard-udp -> !r:^# && r:disable && r:no; + +# 5.9 Disable discard (Scored) +[CIS - SLES12 - 5.9 - discard enabled on xinetd {CIS: 5.9 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/discard -> !r:^# && r:disable && r:no; + +# 5.10 Disable time-udp (Scored) +[CIS - SLES12 - 5.10 - time-udp enabled on xinetd {CIS: 5.10 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/time-udp -> !r:^# && r:disable && r:no; + +# 5.11 Disable time (Scored) +[CIS - SLES12 - 5.11 - time enabled on xinetd {CIS: 5.11 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/time -> !r:^# && r:disable && r:no; + +############################################### +# 6 Special Purpose Services +############################################### + +# 6.1 Remove X Windows (Scored) +[CIS - SLES12 - 6.1 - X11 not disabled {CIS: 6.1 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/usr/lib/systemd/system/default.target -> r:Graphical; +p:gdm-x-session; + +# 6.2 Disable Avahi Server (Scored) +[CIS - SLES12 - 6.2 - Avahi daemon not disabled {CIS: 6.2 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +p:avahi-daemon; + +# 6.3 Disable Print Server - CUPS (Not Scored) +#TODO + +# 6.4 Remove DHCP Server (Scored) +[CIS - SLES12 - 6.4 - DHCPnot disabled {CIS: 6.4 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/usr/lib/systemd/system/dhcpd.service -> r:Exec; + +# 6.5 Configure Network Time Protocol (NTP) (Scored) +#TODO Chrony +[CIS - SLES12 - 6.5 - NTPD not Configured {CIS: 6.5 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ntp.conf -> r:restrict default kod nomodify notrap nopeer noquery && r:^server; +f:/etc/sysconfig/ntpd -> r:OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"; + +# 6.6 Remove LDAP (Not Scored) +#TODO + +# 6.7 Disable NFS and RPC (Not Scored) +[CIS - SLES12 - 6.7 - Disable standard boot services - NFS Enabled {CIS: 6.7 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 6.8 Remove DNS Server (Not Scored) +# TODO + +# 6.9 Remove FTP Server (Not Scored) +[CIS - SLES12 - 6.9 - VSFTP enabled on xinetd {CIS: 6.9 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 6.10 Remove HTTP Server (Not Scored) +[CIS - SLES12 - 6.10 - Disable standard boot services - Apache web server Enabled {CIS: 6.10 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dapache2$; + +# 6.11 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - SLES12 - 6.11 - imap enabled on xinetd {CIS: 6.11 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - SLES12 - 6.11 - pop3 enabled on xinetd {CIS: 6.11 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 6.12 Remove Samba (Not Scored) +[CIS - SLES12 - 6.12 - Disable standard boot services - Samba Enabled {CIS: 6.12 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 6.13 Remove HTTP Proxy Server (Not Scored) +[CIS - SLES12 - 6.13 - Disable standard boot services - Squid Enabled {CIS: 6.13 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 6.14 Remove SNMP Server (Not Scored) +[CIS - SLES12 - 6.14 - Disable standard boot services - SNMPD process Enabled {CIS: 6.14 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 6.15 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + +# 6.16 Ensure rsync service is not enabled (Scored) +[CIS - SLES12 - 6.16 - Disable standard boot services - rsyncd process Enabled {CIS: 6.16 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\drsyncd$; + +# 6.17 Ensure Biosdevname is not enabled (Scored) +# TODO + +############################################### +# 7 Network Configuration and Firewalls +############################################### + +############################################### +# 7.1 Modify Network Parameters (Host Only) +############################################### + +# 7.1.1 Disable IP Forwarding (Scored) +[CIS - SLES12 - 7.1.1 - Network parameters - IP Forwarding enabled {CIS: 7.1.1 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 7.1.2 Disable Send Packet Redirects (Scored) +[CIS - SLES12 - 7.1.2 - Network parameters - IP send redirects enabled {CIS: 7.1.2 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + +############################################### +# 7.2 Modify Network Parameters (Host and Router) +############################################### + +# 7.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - SLES12 - 7.2.1 - Network parameters - Source routing accepted {CIS: 7.2.1 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 7.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - SLES12 - 7.2.2 - Network parameters - ICMP redirects accepted {CIS: 7.2.2 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 7.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - SLES12 - 7.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 7.2.3 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 7.2.4 Log Suspicious Packets (Scored) +[CIS - SLES12 - 7.2.4 - Network parameters - martians not logged {CIS: 7.2.4 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 7.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - SLES12 - 7.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 7.2.5 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 7.2.6 Enable Bad Error Message Protection (Scored) +[CIS - SLES12 - 7.2.6 - Network parameters - Bad error message protection not enabled {CIS: 7.2.6 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 7.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - SLES12 - 7.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 7.2.7 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 7.2.8 Enable TCP SYN Cookies (Scored) +[CIS - SLES12 - 7.2.8 - Network parameters - SYN Cookies not enabled {CIS: 7.2.8 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + +############################################### +# 7.3 Configure IPv6 +############################################### + +# 7.3.1 Disable IPv6 Router Advertisements (Not Scored) + +# 7.3.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 7.3.3 Disable IPv6 (Not Scored) + +############################################### +# 7.4 Install TCP Wrappers +############################################### + +# 7.4.1 Install TCP Wrappers (Not Scored) + +# 7.4.2 Create /etc/hosts.allow (Not Scored) + +# 7.4.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 7.4.4 Create /etc/hosts.deny (Not Scored) + +# 7.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + +############################################### +# 7.5 Uncommon Network Protocols +############################################### + +# 7.5.1 Disable DCCP (Not Scored) + +# 7.5.2 Disable SCTP (Not Scored) + +# 7.5.3 Disable RDS (Not Scored) + +# 7.5.4 Disable TIPC (Not Scored) + +# 7.6 Deactivate Wireless Interfaces (Not Scored) + +# 7.7 Enable SuSEfirewall2 (Scored) + +# 7.8 Limit access to trusted networks (Not Scored) + +############################################### +# 8 Logging and Auditing +############################################### + +############################################### +# 8.1 Configure System Accounting (auditd) +############################################### + +############################################### +# 8.1.1 Configure Data Retention +############################################### + +# 8.1.1.1 Configure Audit Log Storage Size (Not Scored) + +# 8.1.1.2 Disable System on Audit Log Full (Not Scored) + +# 8.1.1.3 Keep All Auditing Information (Scored) + +# 8.1.2 Enable auditd Service (Scored) + +# 8.1.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 8.1.4 Record Events That Modify Date and Time Information (Scored) + +# 8.1.5 Record Events That Modify User/Group Information (Scored) + +# 8.1.6 Record Events That Modify the System’s Network Environment (Scored) + +# 8.1.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 8.1.8 Collect Login and Logout Events (Scored) + +# 8.1.9 Collect Session Initiation Information (Scored) + +# 8.1.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 8.1.12 Collect Use of Privileged Commands (Scored) + +# 8.1.13 Collect Successful File System Mounts (Scored) + +# 8.1.14 Collect File Deletion Events by User (Scored) + +# 8.1.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 8.1.16 Collect System Administrator Actions (sudolog) (Scored) + +# 8.1.17 Collect Kernel Module Loading and Unloading (Scored) + +# 8.1.18 Make the Audit Configuration Immutable (Scored) + +############################################### +# 8.2 Configure rsyslog +############################################### + +# 8.2.1 Install the rsyslog package (Scored) +# TODO + +# 8.2.2 Activate the rsyslog Service (Scored) +# TODO + +# 8.2.3 Configure /etc/rsyslog.conf (Not Scored) + +# 8.2.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + +############################################### +# 8.3 Advanced Intrusion Detection Environment (AIDE) +############################################### + +# 8.3.1 Install AIDE (Scored) + +# 8.3.2 Implement Periodic Execution of File Integrity (Scored) + +# 8.4 Configure logrotate (Not Scored) + +############################################### +# 9 System Access, Authentication and Authorization +############################################### + +############################################### +# 9.1 Configure cron and anacron +############################################### + +# 9.1.1 Enable cron Daemon (Scored) + +# 9.1.2 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 9.1.3 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 9.1.4 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 9.1.5 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 9.1.6 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 9.1.7 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 9.1.8 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 9.2 Configure SSH +############################################### + +# 9.2.1 Set SSH Protocol to 2 (Scored) +[CIS - SLES12 - 9.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 9.2.1 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 9.2.2 Set LogLevel to INFO (Scored) +[CIS - SLES12 - 9.2.1 - SSH Configuration - Loglevel not INFO {CIS: 9.2.1 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && !r:LogLevel\.+INFO; + +# 9.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) +# TODO + +# 9.2.4 Disable SSH X11 Forwarding (Scored) +# TODO + +# 9.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) +[ CIS - SLES12 - 9.2.5 - SSH Configuration - Set SSH MaxAuthTries to 4 or Less {CIS - SLES12 - 9.2.5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:/etc/ssh/sshd_config -> r:^#\s*MaxAuthTries; +f:/etc/ssh/sshd_config -> !r:MaxAuthTries; + +# 9.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - SLES12 - 9.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 9.2.6 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 9.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - SLES12 - 9.2.7 - SSH Configuration - Host based authentication enabled {CIS: 9.2.7 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 9.2.8 Disable SSH Root Login (Scored) +[CIS - SLES12 - 9.2.8 - SSH Configuration - Root login allowed {CIS: 9.2.8 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitRootLogin; + +# 9.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - SLES12 - 9.2.9 - SSH Configuration - Empty passwords permitted {CIS: 9.2.9 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitEmptyPasswords; + +# 9.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 9.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 9.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 9.2.13 Limit Access via SSH (Scored) + +# 9.2.14 Set SSH Banner (Scored) + +############################################### +# 9.3 Configure PAM +############################################### + +# 9.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 9.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 9.3.3 Limit Password Reuse (Scored) + +# 9.4 Restrict root Login to System Console (Not Scored) + +# 9.5 Restrict Access to the su Command (Scored) + +############################################### +# 10 User Accounts and Environment +############################################### + +############################################### +# 10.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 10.1.1 Set Password Expiration Days (Scored) + +# 10.1.2 Set Password Change Minimum Number of Days (Scored) + +# 10.1.3 Set Password Expiring Warning Days (Scored) + +# 10.2 Disable System Accounts (Scored) + +# 10.3 Set Default Group for root Account (Scored) + +# 10.4 Set Default umask for Users (Scored) + +# 10.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 11 Warning Banners +############################################### + +# 11.1 Set Warning Banner for Standard Login Services (Scored) + +# 11.2 Remove OS Information from Login Warning Banners (Scored) + +# 11.3 Set Graphical Warning Banner (Not Scored) + +############################################### +# 12 Verify System File Permissions +############################################### + +# 12.1 Verify System File Permissions (Not Scored) + +# 12.2 Verify Permissions on /etc/passwd (Scored) + +# 12.3 Verify Permissions on /etc/shadow (Scored) + +# 12.4 Verify Permissions on /etc/group (Scored) + +# 12.5 Verify User/Group Ownership on /etc/passwd (Scored) + +# 12.6 Verify User/Group Ownership on /etc/shadow (Scored) + +# 12.7 Verify User/Group Ownership on /etc/group (Scored) + +# 12.8 Find World Writable Files (Not Scored) + +# 12.9 Find Un-owned Files and Directories (Scored) + +# 12.10 Find Un-grouped Files and Directories (Scored) + +# 12.11 Find SUID System Executables (Not Scored) + +# 12.12 Find SGID System Executables (Not Scored) + +############################################### +# 13 Review User and Group Settings +############################################### + +# 13.1 Ensure Password Fields are Not Empty (Scored) + +# 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 13.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 13.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - SLES12 - 13.5 - Non-root account with uid 0 {CIS: 13.5 SLES12} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 13.6 Ensure root PATH Integrity (Scored) + +# 13.7 Check Permissions on User Home Directories (Scored) + +# 13.8 Check User Dot File Permissions (Scored) + +# 13.9 Check Permissions on User .netrc Files (Scored) + +# 13.10 Check for Presence of User .rhosts Files (Scored) + +# 13.11 Check Groups in /etc/passwd (Scored) + +# 13.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 13.13 Check User Home Directory Ownership (Scored) + +# 13.14 Check for Duplicate UIDs (Scored) + +# 13.15 Check for Duplicate GIDs (Scored) + +# 13.16 Check for Duplicate User Names (Scored) + +# 13.17 Check for Duplicate Group Names (Scored) + +# 13.18 Check for Presence of User .netrc Files (Scored) + +# 13.19 Check for Presence of User .forward Files (Scored) + +# 13.20 Ensure shadow group is empty (Scored) + + +# Other/Legacy Tests +[CIS - SLES12 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - SLES12 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - SLES12 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/openarmor-rules/shared/cis_solaris11_rcl.txt b/openarmor-rules/shared/cis_solaris11_rcl.txt new file mode 100644 index 000000000..899eb1470 --- /dev/null +++ b/openarmor-rules/shared/cis_solaris11_rcl.txt @@ -0,0 +1,475 @@ +# openarmor Linux Audit - (C) 2017 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Solaris 11 +# Based on Center for Internet Security Benchmark for Solaris 11 Benchmark v1.1.0 https://workbench.cisecurity.org/benchmarks/410 +# +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +# +# +#2.1 Disable Local-only Graphical Login Environment +[CIS - Solaris 11 Configuration - 2.1 Disable Local-only Graphical Login Environment] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:gdm; +p:cde; +# +# +#2.2 Configure sendmail Service for Local-Only Mode +[CIS - Solaris 11 Configuration - 2.2 Configure sendmail Service for Local-Only Mode] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:!/etc/mail/local.cf; +# +# +#2.3 Disable RPC Encryption Key +[CIS - Solaris 11 Configuration - 2.3 Disable RPC Encryption Key] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:keyserv; +# +# +#2.4 Disable NIS Server Services +[CIS - Solaris 11 Configuration - 2.4 Disable NIS Server Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:ypserv; +p:ypbind; +p:ypxfr; +p:rpc.yppasswdd; +p:rpc.ypupdated; +f:/etc/init.d/nis; +# +# +#2.5 Disable NIS Client Services +[CIS - Solaris 11 Configuration - 2.5 Disable NIS Client Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:ypserv; +p:ypbind; +p:ypxfr; +p:rpc.yppasswdd; +p:rpc.ypupdated; +f:/etc/init.d/nis; +# +# +#2.6 Disable Kerberos TGT Expiration Warning +[CIS - Solaris 11 Configuration - 2.6 Disable Kerberos TGT Expiration Warning] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:ktkt_warnd; +# +# +#2.7 Disable Generic Security Services (GSS) +[CIS - Solaris 11 Configuration - 2.7 Disable Generic Security Services (GSS)] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:gssd; +# +# +#2.8 Disable Removable Volume Manager +[CIS - Solaris 11 Configuration - 2.8 Disable Removable Volume Manager] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:smserverd; +# +# +#2.9 Disable automount Service +[CIS - Solaris 11 Configuration - 2.9 Disable automount Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:automountd; +# +# +#2.10 Disable Apache Service +[CIS - Solaris 11 Configuration - 2.10 Disable Apache Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:apache; +p:httpd; +# +# +#2.11 Disable Local-only RPC Port Mapping Service +[CIS - Solaris 11 Configuration - 2.11 Disable Local-only RPC Port Mapping Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:rpcbind; +# +# +#2.12 Configure TCP Wrappers +[CIS - Solaris 11 Configuration - 2.12 Configure TCP Wrappers] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:!/etc/hosts.allow; +f:!/etc/hosts.deny; +# +# +#2.13 Disable Telnet Service +[CIS - Solaris 11 Configuration - 2.13 Disable Telnet Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:telnetd; +# +# +#3.1 Restrict Core Dumps to Protected Directory +[CIS - Solaris 11 Configuration - 3.1 Restrict Core Dumps to Protected Directory] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_PATTERN\p\.+; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_CONTENT\pdefault; +f:/etc/coreadm.conf -> !r:^COREADM_INIT_PATTERN\pcore; +f:/etc/coreadm.conf -> !r:^COREADM_INIT_CONTENT\pdefault; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_ENABLED\pyes|^COREADM_GLOB_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_PROC_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_SETID_ENABLED\pyes|^COREADM_GLOB_SETID_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_PROC_SETID_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_LOG_ENABLED\pyes; +# +# +#3.2 Enable Stack Protection +[CIS - Solaris 11 Configuration - 3.2 Enable Stack Protection] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:!/etc/system; +f:/etc/system -> !r:^\s*\t*noexec_user_stack\p1; +f:/etc/system -> !r:^# && r:\s*\t*noexec_user_stack\p0; +f:/etc/system -> !r:^\s*\t*noexec_user_stack_log\p1; +f:/etc/system -> !r:^# && r:\s*\t*noexec_user_stack_log\p0; +# +# +#3.3 Enable Strong TCP Sequence Number Generation +[CIS - Solaris 11 Configuration - 3.3 Enable Strong TCP Sequence Number Generation] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/inetinit -> !r:^TCP_STRONG_ISS\p2; +f:/etc/default/inetinit -> !r:^# && r:TCP_STRONG_ISS\p1; +# +# +#4.1 Create CIS Audit Class +[CIS - Solaris 11 Configuration - 4.1 Create CIS Audit Class] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_class -> !r:0x\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d:cis:\.+; +# +# +#4.2 Enable Auditing of Incoming Network Connections +[CIS - Solaris 11 Configuration - 4.2 Enable Auditing of Incoming Network Connections] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_event -> !r:^\d+:AUE_ACCEPT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_CONNECT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SOCKACCEPT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SOCKCONNECT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_inetd_connect:\.+cis\.*; +# +# +#4.3 Enable Auditing of File Metadata Modification Events +[CIS - Solaris 11 Configuration - 4.3 Enable Auditing of File Metadata Modification Events] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_event -> !r:^\d+:AUE_CHMOD:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_CHOWN:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FCHOWN:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FCHMOD:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_LCHOWN:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_ACLSET:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FACLSET:\.+cis\.*; +# +# +#4.4 Enable Auditing of Process and Privilege Events +[CIS - Solaris 11 Configuration - 4.4 Enable Auditing of Process and Privilege Events] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_event -> !r:^\d+:AUE_CHROOT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETREUID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETREGID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FCHROOT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_PFEXEC:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETUID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_NICE:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETGID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_PRIOCNTLSYS:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETEGID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETEUID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETPRIV:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETSID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETPGID:\.+cis\.*; +# +# +#4.5 Configure Solaris Auditing +[CIS - Solaris 11 Configuration - 4.5 Configure Solaris Auditing] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:/var/spool/cron/crontabs -> !r:/usr/sbin/audit -n; +# +# +#5.1 Default Service File Creation Mask +[CIS - Solaris 11 Configuration - 5.1 Default Service File Creation Mask] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/profile -> !r:^umask\s*\d\d\d; +# +# +#6.2 Disable "nobody" Access for RPC Encryption Key Storage Service +[CIS - Solaris 11 Configuration - 6.2 Disable "nobody" Access for RPC Encryption Key Storage Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f!:/etc/default/keyserv; +f:/etc/default/keyserv -> !r:^ENABLE\.NOBODY\.KEYS\pNO; +f:/etc/default/keyserv -> !r:^# && r:ENABLE\.NOBODY\.KEYS\pYES; +# +# +#6.3 Disable X11 Forwarding for SSH +[CIS - Solaris 11 Configuration - 6.3 Disable X11 Forwarding for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^X11Forwarding\s*no; +f:/etc/ssh/sshd_config -> !r:^# && r:X11Forwarding\s*yes; +# +# +#6.4 Limit Consecutive Login Attempts for SSH +[CIS - Solaris 11 Configuration - 6.4 Limit Consecutive Login Attempts for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^MaxAuthTries\s*3; +f:/etc/ssh/sshd_config -> !r:^# && r:MaxAuthTries\s*3\d+; +# +# +#6.5 Disable Rhost-based Authentication for SSH +[CIS - Solaris 11 Configuration - 6.5 Disable Rhost-based Authentication for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^IgnoreRhosts\s*yes; +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\s*no; +# +# +#6.6 Disable root login for SSH +[CIS - Solaris 11 Configuration - 6.6 Disable root login for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^PermitRootLogin\s*no; +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\s*yes; +# +# +#6.7 Blocking Authentication Using Empty/Null Passwords for SSH +[CIS - Solaris 11 Configuration - 6.7 Blocking Authentication Using Empty/Null Passwords for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^PermitEmptyPasswords\s*no; +f:/etc/ssh/sshd_config -> !r:^# && r:PermitEmptyPasswords\s*yes; +# +# +#6.8 Disable Host-based Authentication for Login-based Services +[CIS - Solaris 11 Configuration - 6.8 Disable Host-based Authentication for Login-based Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/pam.conf -> !r:^rlogin\s*\t*auth sufficient\s*\t*pam_rhosts_auth.so.1; +f:/etc/pam.conf -> !r:^rsh\s*\t*auth sufficient\s*\t*pam_rhosts_auth.so.1; +# +# +#6.9 Restrict FTP Use +[CIS - Solaris 11 Configuration - 6.9 Restrict FTP Use] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ftpd/ftpusers -> !r:^root; +f:/etc/ftpd/ftpusers -> !r:^daemon; +f:/etc/ftpd/ftpusers -> !r:^bin; +f:/etc/ftpd/ftpusers -> !r:^sys; +f:/etc/ftpd/ftpusers -> !r:^adm; +f:/etc/ftpd/ftpusers -> !r:^uucp; +f:/etc/ftpd/ftpusers -> !r:^nuucp; +f:/etc/ftpd/ftpusers -> !r:^smmsp; +f:/etc/ftpd/ftpusers -> !r:^listen; +f:/etc/ftpd/ftpusers -> !r:^gdm; +f:/etc/ftpd/ftpusers -> !r:^lp; +f:/etc/ftpd/ftpusers -> !r:^webservd; +f:/etc/ftpd/ftpusers -> !r:^postgres; +f:/etc/ftpd/ftpusers -> !r:^svctag; +f:/etc/ftpd/ftpusers -> !r:^openldap; +f:/etc/ftpd/ftpusers -> !r:^unknown; +f:/etc/ftpd/ftpusers -> !r:^aiuser; +f:/etc/ftpd/ftpusers -> !r:^nobody; +f:/etc/ftpd/ftpusers -> !r:^nobody4; +f:/etc/ftpd/ftpusers -> !r:^noaccess; +# +# +#6.10 Set Delay between Failed Login Attempts to 4 +[CIS - Solaris 11 Configuration - 6.10 Set Delay between Failed Login Attempts to 4] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^SLEEPTIME\p4; +f:/etc/default/login -> !r:^# && r:SLEEPTIME\p4\d; +# +# +#6.11 Remove Autologin Capabilities from the GNOME desktop +[CIS - Solaris 11 Configuration - 6.11 Remove Autologin Capabilities from the GNOME desktop] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/pam.conf -> !r:^# && r:gdm-autologin; +# +# +#6.12 Set Default Screen Lock for GNOME Users +[CIS - Solaris 11 Configuration - 6.12 Set Default Screen Lock for GNOME Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/usr/share/X11/app-defaults/XScreensaver -> !r:^*timeout:\s*\t*0:10:00; +f:/usr/share/X11/app-defaults/XScreensaver -> !r:^*locktimeout:\s*\t*0:00:00; +f:/usr/share/X11/app-defaults/XScreensaver -> !r:^*lock:\s*\t*true; +# +# +#6.13 Restrict at/cron to Authorized Users +[CIS - Solaris 11 Configuration - 6.13 Restrict at/cron to Authorized Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/cron.d/cron.deny; +f:/etc/cron.d/at.deny; +f:!/etc/cron.d/cron.allow; +f:/etc/cron.d/cron.allow -> !r:^root$; +f:!/etc/cron.d/at.allow; +f:/etc/cron.d/at.allow -> !r:^# && r:\w; +# +# +#6.14 Restrict root Login to System Console +[CIS - Solaris 11 Configuration - 6.14 Restrict root Login to System Console] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^CONSOLE\p/dev/console; +# +# +#6.15 Set Retry Limit for Account Lockout +[CIS - Solaris 11 Configuration - 6.14 Restrict root Login to System Console] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^RETRIES\p3; +f:/etc/default/login -> !r:^# && r:RETRIES\p3\d; +f:/etc/security/policy.conf -> !r:^LOCK_AFTER_RETRIES\pyes; +f:/etc/security/policy.conf -> !r:^# && r:LOCK_AFTER_RETRIES\pno; +# +# +#6.17 Secure the GRUB Menu (Intel) +[CIS - Solaris 11 Configuration - 6.17 Secure the GRUB Menu (Intel)] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/rpool/boot/grub/menu.lst -> !r:^password\s*--md5; +# +# +#7.1 Set Password Expiration Parameters on Active Accounts +[CIS - Solaris 11 Configuration - 7.1 Set Password Expiration Parameters on Active Accounts] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/passwd -> !r:^maxweeks\p13; +f:/etc/default/passwd -> !r:^# &&r:maxweeks\p13\d; +f:/etc/default/passwd -> !r:^minweeks\p1; +f:/etc/default/passwd -> !r:^# &&r:minweeks\p1\d; +f:/etc/default/passwd -> !r:^warnweeks\p4; +f:/etc/default/passwd -> !r:^# &&r:warnweeks\p4\d; +# +# +#7.2 Set Strong Password Creation Policies +[CIS - Solaris 11 Configuration - 7.2 Set Strong Password Creation Policies] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/passwd -> !r:^passlength\p8; +f:/etc/default/passwd -> !r:^# && r:passlength\p8\d; +f:/etc/default/passwd -> !r:^namecheck\pyes; +f:/etc/default/passwd -> !r:^# && r:namecheck\pno; +f:/etc/default/passwd -> !r:^history\p10; +f:/etc/default/passwd -> !r:^# && r:history\p10\d; +f:/etc/default/passwd -> !r:^mindiff\p3; +f:/etc/default/passwd -> !r:^# && r:mindiff\p3\d; +f:/etc/default/passwd -> !r:^minalpha\p2; +f:/etc/default/passwd -> !r:^# && r:minalpha\p2\d; +f:/etc/default/passwd -> !r:^minupper\p1; +f:/etc/default/passwd -> !r:^# && r:minupper\p1\d; +f:/etc/default/passwd -> !r:^minlower\p1; +f:/etc/default/passwd -> !r:^# && r:minlower\p1\d; +f:/etc/default/passwd -> !r:^minnonalpha\p1; +f:/etc/default/passwd -> !r:^# && r:minnonalpha\p1\d; +f:/etc/default/passwd -> !r:^maxrepeats\p0; +f:/etc/default/passwd -> !r:^# && r:maxrepeats\p0\d; +f:/etc/default/passwd -> !r:^whitespace\pyes; +f:/etc/default/passwd -> !r:^# && r:whitespace\pno; +f:/etc/default/passwd -> !r:^dictiondbdir\p/var/passwd; +f:/etc/default/passwd -> !r:^dictionlist\p/usr/share/lib/dict/words; +# +# +#7.3 Set Default umask for users +[CIS - Solaris 11 Configuration - 7.3 Set Default umask for users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^umask\p027|^umask\p077; +f:/etc/default/login -> !r:^# && r:umask\p026; +f:/etc/default/login -> !r:^# && r:umask\p022; +# +# +#7.4 Set Default File Creation Mask for FTP Users +[CIS - Solaris 11 Configuration - 7.4 Set Default File Creation Mask for FTP Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/proftpd.conf -> !r:^umask\s*027; +f:/etc/proftpd.conf -> !r:^# && r:umask\s*026; +f:/etc/proftpd.conf -> !r:^# && r:umask\s*022; +# +# +#7.5 Set "mesg n" as Default for All Users +[CIS - Solaris 11 Configuration - 7.5 Set "mesg n" as Default for All Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/.login -> !r:^mesg\s*n; +f:/etc/profile -> !r:^mesg\s*n; +# +# +#8.1 Create Warnings for Standard Login Services +[CIS - Solaris 11 Configuration - 8.1 Create Warnings for Standard Login Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/issue -> r:SunOS; +f:/etc/issue -> r:Oracle; +f:/etc/issue -> r:solaris; +f:/etc/issue -> !r:Authorized users only. All activity may be monitored and reported; +f:/etc/motd -> r:SunOS; +f:/etc/motd -> r:Oracle; +f:/etc/motd -> r:solaris; +f:/etc/motd -> !r:Authorized users only. All activity may be monitored and reported; +# +# +#8.2 Enable a Warning Banner for the SSH Service +[CIS - Solaris 11 Configuration - 8.2 Enable a Warning Banner for the SSH Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^Banner\s*/etc/issue; +# +# +#8.3 Enable a Warning Banner for the GNOME Service +[CIS - Solaris 11 Configuration - 8.3 Enable a Warning Banner for the GNOME Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/gdm/Init/Default -> !r:^/usr/bin/zenity\s\.; +# +# +#8.4 Enable a Warning Banner for the FTP service +[CIS - Solaris 11 Configuration - 8.4 Enable a Warning Banner for the FTP service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/proftpd.conf -> !r:^DisplayConnect\s+/etc/issue; +# +# +#8.5 Check that the Banner Setting for telnet is Null +[CIS - Solaris 11 Configuration - 8.5 Check that the Banner Setting for telnet is Null] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/telnetd -> !r:^# && r:BANNER=\.; +f:/etc/default/telnetd -> !r:BANNER=$; +# +# +#9.3 Verify System Account Default Passwords +[CIS - Solaris 11 Configuration - 9.3 Verify System Account Default Passwords] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/shadow -> r:daemon && !r::NL:|:NP:; +f:/etc/shadow -> r:lp && !r::NL:|:NP:; +f:/etc/shadow -> r:adm && !r::NL:|:NP:; +f:/etc/shadow -> r:bin && !r::NL:|:NP:; +f:/etc/shadow -> r:gdm && !r::\p*LK\p*:; +f:/etc/shadow -> r:noaccess && !r::\p*LK\p*:; +f:/etc/shadow -> r:nobody && !r::\p*LK\p*:; +f:/etc/shadow -> r:nobody4 && !r::\p*LK\p*:; +f:/etc/shadow -> r:openldap && !r::\p*LK\p*:; +f:/etc/shadow -> r:unknown && !r::\p*LK\p*:; +f:/etc/shadow -> r:webservd && !r::\p*LK\p*:; +f:/etc/shadow -> r:mysql && !r::NL:|:NP:; +f:/etc/shadow -> r:nuuc && !r::NL:|:NP:; +f:/etc/shadow -> r:postgres && !r::NL:|:NP:; +f:/etc/shadow -> r:smmsp && !r::NL:|:NP:; +f:/etc/shadow -> r:sys && !r::NL:|:NP:; +f:/etc/shadow -> r:uucp && !r::NL:|:NP:; +f:/etc/shadow -> r:aiuser && !r::\p*LK\p*:; +f:/etc/shadow -> r:dhcpserv && !r::\p*LK\p*:; +f:/etc/shadow -> r:dladm && !r::\p*LK\p*:; +f:/etc/shadow -> r:ftp && !r::\p*LK\p*:; +f:/etc/shadow -> r:netadm && !r::\p*LK\p*:; +f:/etc/shadow -> r:netcfg && !r::\p*LK\p*:; +f:/etc/shadow -> r:pkg5srv && !r::\p*LK\p*:; +f:/etc/shadow -> r:svctag && !r::\p*LK\p*:; +f:/etc/shadow -> r:xvm && !r::\p*LK\p*:; +f:/etc/shadow -> r:upnp && !r::NL:|:NP:; +f:/etc/shadow -> r:zfssnap && !r::NL:|:NP:; +# +# +#9.4 Ensure Password Fields are Not Empty +[CIS - Solaris 11 Configuration - 9.4 Ensure Password Fields are Not Empty] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/shadow -> r:\.+::\.+\w+\.*$; +# +# +#9.5 Verify No UID 0 Accounts Exist Other than root +[CIS - Solaris 11 Configuration - 9.5 Verify No UID 0 Accounts Exist Other than root] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/passwd -> !r:^root && r::\.:0:\.*; +# +# +#9.6 Ensure root PATH Integrity +[CIS - Solaris 11 Configuration - Ensure root PATH Integrity] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/profile -> r:.; +f:/etc/environment -> r:.; +f:/.profile -> r:.; +f:/.bash_profile -> r:.; +f:/.bashrc -> r:.; +f:/etc/profile -> r:::; +f:/etc/environment -> r:::; +f:/.profile -> r:::; +f:/.bash_profile -> r:::; +f:/.bashrc -> r:::; +f:/etc/profile -> r::$; +f:/etc/environment -> r::$; +f:/.profile -> r::$; +f:/.bash_profile -> r::$; +f:/.bashrc -> r::$; +# +# +#9.10 Check for Presence of User .rhosts Files +[CIS - Solaris 11 Configuration - 9.10 Check for Presence of User .rhosts Files] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:$home_dirs -> ^.rhosts$; +# +# +#9.12 Check That Users Are Assigned Home Directories +[CIS - Solaris 11 Configuration - 9.12 Check That Users Are Assigned Home Directories] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/passwd -> \w+:\.*:\d*:\d*:\.*:\S+:\.*; +# +# +#9.20 Check for Presence of User .netrc Files +[CIS - Solaris 11 Configuration - 9.20 Check for Presence of User .netrc Files] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:$home_dirs -> ^.netrc$; +# +# +#9.21 Check for Presence of User .forward Files +[CIS - Solaris 11 Configuration - 9.21 Check for Presence of User .forward Files] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:$home_dirs -> ^.forward$; +# +# +# diff --git a/openarmor-rules/shared/cis_win10_enterprise_L1_rcl.txt b/openarmor-rules/shared/cis_win10_enterprise_L1_rcl.txt new file mode 100644 index 000000000..d8a8456af --- /dev/null +++ b/openarmor-rules/shared/cis_win10_enterprise_L1_rcl.txt @@ -0,0 +1,1548 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows 10 +# Based on Center for Internet Security Benchmark v1.4.0 for Microsoft Windows 10 Release 1709 (https://workbench.cisecurity.org/benchmarks/766) +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows 10 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'[CIS - Microsoft Windows 10 - 2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users' +[CIS - Microsoft Windows 10 - 2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'[CIS - Microsoft Windows 10 - 2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> !0; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> !1; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> !1; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> !0; +# +# +#2.3.7.4 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'[CIS - Microsoft Windows 10 - 2.3.7.4 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.8 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows 10 - 2.3.7.8 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows 10 - 2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows 10 - 2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher +[CIS - Microsoft Windows 10 - 2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> SMBServerNameHardeningLevel -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> !SMBServerNameHardeningLevel; +# +# +#2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymousSAM -> 0; +# +# +#2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> !1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> !RestrictAnonymous; +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows 10 - 2.3.10.6 Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> r:\S*; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Ensure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows 10 - 2.3.10.7 Ensure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> !Machine; +# +# +#2.3.10.8 Ensure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows 10 - 2.3.10.8 Ensure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> !Machine; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' +[CIS - Microsoft Windows 10 - 2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> restrictremotesam -> !r:O:BAG:BAD:\(A;;RC;;;BA\); +# +# +#2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows 10 - 2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows 10 - 2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows 10 - 2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> !SupportedEncryptionTypes; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows 10 - 2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows 10 - 2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows 10 - 2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows 10 - 2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows 10 - 2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows 10 - 2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#5.3 Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.3 Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser -> Start -> !4; +# +# +#5.6 Ensure 'HomeGroup Listener (HomeGroupListener)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.6 Ensure 'HomeGroup Listener (HomeGroupListener)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupListener -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupListener -> !Start; +# +# +#5.7 Ensure 'HomeGroup Provider (HomeGroupProvider)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.7 Ensure 'HomeGroup Provider (HomeGroupProvider)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupProvider -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupProvider -> !Start; +# +# +#5.8 Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.8 Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN -> Start -> !4; +# +# +#5.9 Ensure 'Infrared monitor service (irmon)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.9 Ensure 'Infrared monitor service (irmon)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon -> !Start; +# +# +#5.10 Ensure 'Internet Connection Sharing (ICS) (SharedAccess) ' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.10 Ensure 'Internet Connection Sharing (ICS) (SharedAccess) ' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess -> !Start; +# +# +#5.12 Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.12 Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LxssManager -> Start -> !4; +# +# +#5.13 Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.13 Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC -> Start -> !4; +# +# +#5.24 Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.24 Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator -> !Start; +# +# +#5.26 Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.26 Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess -> !Start; +# +# +#5.28 Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.28 Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp -> Start -> !4; +# +# +#5.30 Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.30 Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV -> !Start; +# +# +#5.31 Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.31 Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost -> !Start; +# +# +#5.32 Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.32 Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc -> Start -> !4; +# +# +#5.35 Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.35 Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc -> Start -> !4; +# +# +#5.36 Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.36 Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc -> !Start; +# +# +#5.41 Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.41 Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC -> Start -> !4; +# +# +#5.42 Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.42 Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc -> !Start; +# +# +#5.43 Ensure 'Xbox Game Monitoring (xbgm)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.43 Ensure 'Xbox Game Monitoring (xbgm)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\xbgm -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\xbgm -> !Start; +# +# +#5.44 Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.44 Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager -> !Start;# +# +#5.45 Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.45 Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave -> !Start; +# +# +#4.46 Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 4.46 Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvce -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvce -> !Start; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows 10 - 9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows 10 - 9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows 10 - 9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows 10 - 9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows 10 - 9.1.5 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows 10 - 9.1.6 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.1.7 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.1.8 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows 10 - 9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows 10 - 9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows 10 - 9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows 10 - 9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows 10 - 9.2.5 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows 10 - 9.2.6 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.2.7 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.2.8 Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows 10 - 9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows 10 - 9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows 10 - 9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows 10 - 9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows 10 - 9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows 10 - 9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows 10 - 9.3.7 Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows 10 - 9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.1.2.2 Ensure 'Allow input personalization' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.1.2.2 Ensure 'Allow input personalization' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> AllowInputPersonalization -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> !AllowInputPersonalization; +# +# +#18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed +[CIS - Microsoft Windows 10 - 18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA} -> !DllName; +# +# +#18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PwdExpirationProtectionEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PwdExpirationProtectionEnabled; +# +# +#18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> AdmPwdEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !AdmPwdEnabled; +# +# +#18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' +[CIS - Microsoft Windows 10 - 18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordComplexity -> !4; +# +# +#18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' +[CIS - Microsoft Windows 10 - 18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PasswordLength; +# +# +#18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' +[CIS - Microsoft Windows 10 - 18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> 1F; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:2\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:3\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:4\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:5\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:6\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:7\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:8\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:9\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\w\w\w+; +# +# +#18.3.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.3.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> LocalAccountTokenFilterPolicy -> !0; +# +# +#18.3.2 Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver' +[CIS - Microsoft Windows 10 - 18.3.2 Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10 -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10 -> !Start; +# +# +#18.3.3 Ensure 'Configure SMB v1 server' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.3.3 Ensure 'Configure SMB v1 server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters -> SMB1 -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters -> !SMB1; +# +# +#18.3.4 Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.3.4 Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel -> DisableExceptionChainValidation -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel -> !DisableExceptionChainValidation; +# +# +#18.3.5 Ensure 'Turn on Windows Defender protection against Potentially Unwanted Applications' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.3.5 Ensure 'Turn on Windows Defender protection against Potentially Unwanted Applications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine -> MpEnablePus -> 0; +# +# +#18.3.6 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.3.6 Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.4.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.4.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.4.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows 10 - Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.4.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows 10 - 18.4.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.4.5 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.4.5 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.4.7 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.4.7 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.4.9 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.4.9 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.4.10 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows 10 - 18.4.10 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.4.13 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows 10 - 18.4.13 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.5.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)') +[CIS - Microsoft Windows 10 - 18.5.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)')] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> NodeType -> !2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> !NodeType; +# +# +#18.5.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> EnableMulticast -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> !EnableMulticast; +# +# +#18.5.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> AllowInsecureGuestAuth -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> !AllowInsecureGuestAuth; +# +# +#18.5.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.5.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_ShowSharedAccessUI -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_ShowSharedAccessUI; +# +# +#18.5.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.5.14.1 Ensure 'Hardened UNC Paths' is set to 'Enabled, with "Require Mutual Authentication" and "Require Integrity" set for all NETLOGON and SYSVOL shares' +[CIS - Microsoft Windows 10 - 18.5.14.1 Ensure 'Hardened UNC Paths' is set to 'Enabled, with "Require Mutual Authentication" and "Require Integrity" set for all NETLOGON and SYSVOL shares'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths -> \\\\*\\NETLOGON -> !r:RequireMutualAuthentication=1, RequireIntegrity=1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths -> \\\\*\\SYSVOL -> !r:RequireMutualAuthentication=1, RequireIntegrity=1; +# +# +#18.5.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.5.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fBlockNonDomain -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> !fBlockNonDomain; +# +# +#18.5.23.2.1 Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.23.2.1 Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config -> AutoConnectAllowedOEM -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config -> !AutoConnectAllowedOEM; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.4.1 Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.4.1 Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation -> AllowProtectedCreds -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation -> !AllowProtectedCreds; +# +# +#18.8.14.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows 10 - 18.8.14.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.21.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows 10 - 18.8.21.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.21.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows 10 - 18.8.21.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.21.4 Ensure 'Continue experiences on this device' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.21.4 Ensure 'Continue experiences on this device' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableCdp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableCdp; +# +# +#18.8.21.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.21.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.22.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.22.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.22.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.27.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockUserFromShowingAccountDetailsOnSignin -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !BlockUserFromShowingAccountDetailsOnSignin; +# +# +#18.8.27.2 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.2 Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.27.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.27.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.27.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.27.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.27.6 Ensure 'Turn off picture password sign-in' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.6 Ensure 'Turn off picture password sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockDomainPicturePassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !BlockDomainPicturePassword; +# +# +#18.8.27.7 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.27.7 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.33.6.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> DCSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !DCSettingIndex; +# +# +#18.8.33.6.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> ACSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !ACSettingIndex; +# +# +#18.8.33.6.5 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.5 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.33.6.6 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.6 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.35.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.35.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.35.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.35.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.8.36.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.36.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> EnableAuthEpResolution -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !EnableAuthEpResolution; +# +# +#18.8.36.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' +[CIS - Microsoft Windows 10 - 18.8.36.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> RestrictRemoteClients -> !1; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows 10 - 18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows 10 - 18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.10.1.1 Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.10.1.1 Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> EnhancedAntiSpoofing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> !EnhancedAntiSpoofing; +# +# +#18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> DisableWindowsConsumerFeatures -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> !DisableWindowsConsumerFeatures; +# +# +#18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> RequirePinForPairing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> !RequirePinForPairing; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.16.1 Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security (Enterprise Only)' or 'Enabled: 1 - Basic' +[CIS - Microsoft Windows 10 - 18.9.16.1 Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security (Enterprise Only)' or 'Enabled: 1 - Basic'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> AllowTelemetry -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> AllowTelemetry -> 3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !AllowTelemetry; +# +# +#18.9.16.3 Ensure 'Disable pre-release features or settings' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.16.3 Ensure 'Disable pre-release features or settings' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> EnableConfigFlighting -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !EnableConfigFlighting; +# +# +#18.9.16.4 Ensure 'Do not show feedback notifications' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.16.4 Ensure 'Do not show feedback notifications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DoNotShowFeedbackNotifications -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DoNotShowFeedbackNotifications; +# +# +#18.9.16.5 Ensure 'Toggle user control over Insider builds' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.16.5 Ensure 'Toggle user control over Insider builds' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> AllowBuildPreview -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !AllowBuildPreview; +# +# +#18.9.17.1 Ensure 'Download Mode' is NOT set to 'Enabled: Internet' +[CIS - Microsoft Windows 10 - 18.9.17.1 Ensure 'Download Mode' is NOT set to 'Enabled: Internet'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization -> DODownloadMode -> 3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization -> !DODownloadMode; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> 1; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'[CIS - Microsoft Windows 10 - 18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.30.2 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.3 Ensure 'Turn off heap termination on corruption' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.30.3 Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.4 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.30.4 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.35.1 Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.35.1 Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HomeGroup -> DisableHomeGroup -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HomeGroup -> !DisableHomeGroup; +# +# +#18.9.44.1 Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.44.1 Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount -> DisableUserAuth -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount -> !DisableUserAuth; +# +# +#18.9.45.4 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher +[CIS - Microsoft Windows 10 - 18.9.45.4 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> Cookies -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !Cookies; +# +# +#18.9.45.5 Ensure 'Configure Password Manager' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.5 Ensure 'Configure Password Manager' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> FormSuggest Passwords -> !no; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !FormSuggest Passwords; +# +# +#18.9.45.8 Ensure 'Configure the Adobe Flash Click-to-Run setting' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.8 Ensure 'Configure the Adobe Flash Click-to-Run setting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Security -> FlashClickToRunMode -> !1; +# +# +#18.9.52.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.52.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.58.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.58.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdma -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.58.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.58.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.58.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows 10 - 18.9.58.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.58.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.58.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.59.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.59.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.60.3 Ensure 'Allow Cortana' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.3 Ensure 'Allow Cortana' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortana -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortana; +# +# +#18.9.60.4 Ensure 'Allow Cortana above lock screen' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.4 Ensure 'Allow Cortana above lock screen' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortanaAboveLock -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortanaAboveLock; +# +# +#18.9.60.5 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.5 Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.60.6 Ensure 'Allow search and Cortana to use location' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.6 Ensure 'Allow search and Cortana to use location' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowSearchToUseLocation -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowSearchToUseLocation; +# +# +#18.9.68.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.68.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.68.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.68.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.76.3.1 Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.3.1 Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> LocalSettingOverrideSpynetReporting -> !0; +# +# +#18.9.76.7.1 Ensure 'Turn on behavior monitoring' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.7.1 Ensure 'Turn on behavior monitoring' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection -> DisableBehaviorMonitoring -> !1; +# +# +#18.9.76.10.1 Ensure 'Scan removable drives' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.10.1 Ensure 'Scan removable drives' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> DisableRemovableDriveScanning -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> !DisableRemovableDriveScanning; +# +# +#18.9.76.10.2 Ensure 'Turn on e-mail scanning' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.10.2 Ensure 'Turn on e-mail scanning' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> DisableEmailScanning -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> !DisableEmailScanning; +# +# +#18.9.76.13.1.1 Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.13.1.1 Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> ExploitGuard_ASR_Rules -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> !ExploitGuard_ASR_Rules; +# +# +#18.9.76.13.1.2 Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is 'configured' +[CIS - Microsoft Windows 10 - 18.9.76.13.1.2 Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is 'configured'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D4F940AB-401B-4EFC-AADC-AD5F3C50688A -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D4F940AB-401B-4EFC-AADC-AD5F3C50688A; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 3B576869-A4EC-4529-8536-B80A7769E899 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !3B576869-A4EC-4529-8536-B80A7769E899; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D3E037E1-3EB8-44C8-A917-57927947596D -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D3E037E1-3EB8-44C8-A917-57927947596D; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !5BEB7EFE-FD9A-4556-801D-275E5FFC04CC; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B; +# +# +#18.9.76.13.3.1 Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block' +[CIS - Microsoft Windows 10 - 18.9.76.13.3.1 Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection -> EnableNetworkProtection -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection -> !EnableNetworkProtection; +# +# +#18.9.76.14 Ensure 'Turn off Windows Defender AntiVirus' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.14 Ensure 'Turn off Windows Defender AntiVirus' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender -> DisableAntiSpyware -> 1; +# +# +#18.9.79.1.1 Ensure 'Prevent users from modifying settings' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.79.1.1 Ensure 'Prevent users from modifying settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection -> DisallowExploitProtectionOverride -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection -> !DisallowExploitProtectionOverride; +# +# +#18.9.80.1.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' +[CIS - Microsoft Windows 10 - 18.9.80.1.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> ShellSmartScreenLevel -> !Block; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !ShellSmartScreenLevel; +# +# +#18.9.80.2.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.80.2.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> EnabledV9 -> !1; +# +# +#18.9.80.2.2 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for files' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.80.2.2 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for files' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverrideAppRepUnknown -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverrideAppRepUnknown; +# +# +#18.9.80.2.3 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.80.2.3 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverride -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverride; +# +# +#18.9.82.1 Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.82.1 Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR -> AllowGameDVR -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR -> !AllowGameDVR; +# +# +#18.9.84.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On' +[CIS - Microsoft Windows 10 - 18.9.84.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowWindowsInkWorkspace -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowWindowsInkWorkspace; +# +# +#18.9.85.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.85.1 Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.85.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.85.2 Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.86.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.86.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.95.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.95.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.95.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.95.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.97.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.97.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.97.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.97.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.97.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.97.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.97.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.101.1.1 Ensure 'Manage preview builds' is set to 'Enabled: Disable preview builds' +[CIS - Microsoft Windows 10 - 18.9.101.1.1 Ensure 'Manage preview builds' is set to 'Enabled: Disable preview builds'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> ManagePreviewBuilds -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !ManagePreviewBuilds; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> ManagePreviewBuildsPolicyValue -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !ManagePreviewBuildsPolicyValue; +# +# +#18.9.101.1.2 Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: Semi-Annual Channel, 180 or more days' +[CIS - Microsoft Windows 10 - 18.9.101.1.2 Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: Semi-Annual Channel, 180 or more days'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferFeatureUpdates; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:10\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:11\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:12\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:13\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:14\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:15\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:16\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:17\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> !r:\d\d\d+; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferFeatureUpdatesPeriodInDays; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> BranchReadinessLevel -> !32; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !BranchReadinessLevel; +# +# +#18.9.101.1.13 Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' +[CIS - Microsoft Windows 10 - 18.9.101.1.13 Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferQualityUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferQualityUpdates; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferQualityUpdatesPeriodInDays -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferQualityUpdatesPeriodInDays; +# +# +#18.9.101.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.101.2 Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.101.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows 10 - 18.9.101.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.101.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.101.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# +# +# diff --git a/openarmor-rules/shared/cis_win10_enterprise_L2_rcl.txt b/openarmor-rules/shared/cis_win10_enterprise_L2_rcl.txt new file mode 100644 index 000000000..6f5e031aa --- /dev/null +++ b/openarmor-rules/shared/cis_win10_enterprise_L2_rcl.txt @@ -0,0 +1,591 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows 10 +# Based on Center for Internet Security Benchmark v1.4.0 for Microsoft Windows 10 Release 1709 (https://workbench.cisecurity.org/benchmarks/766) +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> !AddPrinterDrivers; +# +# +#2.3.7.7 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' +[CIS - Microsoft Windows 10 - 2.3.7.7 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> !4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !CachedLogonsCount; +# +# +#2.3.14.1 Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used' or higher +[CIS - Microsoft Windows 10 - 2.3.14.1 Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography -> ForceKeyProtection -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography -> !ForceKeyProtection; +# +# +#5.1 Ensure 'Bluetooth Handsfree Service (BthHFSrv)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.1 Ensure 'Bluetooth Handsfree Service (BthHFSrv)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BthHFSrv -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BthHFSrv -> !Start; +# +# +#5.2 Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.2 Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv -> !Start; +# +# +#5.4 Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.4 Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker -> !Start; +# +# +#5.5 Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.5 Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc -> !Start; +# +# +#5.11 Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.11 Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc -> !Start; +# +# +#5.14 Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.14 Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI -> !Start; +# +# +#5.15 Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.15 Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc -> !Start; +# +# +#5.16 Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.16 Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc -> !Start; +# +# +#5.17 Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.17 Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc -> !Start; +# +# +#5.18 Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.18 Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg -> !Start; +# +# +#5.19 Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.19 Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport -> !Start; +# +# +#5.20 Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.20 Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto -> !Start; +# +# +#5.21 Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.21 Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv -> !Start; +# +# +#5.22 Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.22 Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService -> !Start; +# +# +#5.23 Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.23 Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService -> !Start; +# +# +#5.25 Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.25 Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry -> !Start; +# +# +#5.27 Ensure 'Server (LanmanServer)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.27 Ensure 'Server (LanmanServer)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer -> !Start; +# +# +#5.29 Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.29 Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP -> Start -> !4; +# +# +#5.33 Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.33 Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc -> !Start; +# +# +#5.34 Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.34 Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc -> !Start; +# +# +#5.37 Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.37 Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService -> !Start; +# +# +#5.38 Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.38 Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall -> !Start; +# +# +#5.39 Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.39 Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM -> !Start; +# +# +#5.40 Ensure 'Windows Store Install Service (InstallService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.40 Ensure 'Windows Store Install Service (InstallService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InstallService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InstallService -> !Start; +# +# +#18.1.3 Ensure 'Allow Online Tips' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.1.3 Ensure 'Allow Online Tips' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> AllowOnlineTips -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !AllowOnlineTips; +# +# +#18.4.4 Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.4.4 Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters -> DisableSavePassword -> !1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters -> !DisableSavePassword; +# +# +#18.4.6 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)' +[CIS - Microsoft Windows 10 - 18.4.6 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.4.8 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.4.8 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.4.11 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows 10 - 18.4.11 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.12 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows 10 - 18.4.12 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.5.5.1 Ensure 'Enable Font Providers' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.5.1 Ensure 'Enable Font Providers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableFontProviders -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableFontProviders; +# +# +#18.5.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.5.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.5.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.5.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows 10 - 18.5.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.5.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.5.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.8.22.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.22.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.22.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.22.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.22.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.22.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.22.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.22.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.22.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.22.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.22.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.22.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.25.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' +[CIS - Microsoft Windows 10 - 18.8.25.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitBehavior -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitEnabled -> !1; +# +# +#18.8.26.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.26.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.44.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.44.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.44.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.44.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.46.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.46.1 Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.49.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.49.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.8.49.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.49.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer -> Enabled -> !0; +# +# +#18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager -> AllowSharedLocalAppData -> !0; +# +# +#18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> BlockHostedAppAccessWinRT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !BlockHostedAppAccessWinRT; +# +# +#18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> AllowCamera -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> !AllowCamera; +# +# +#18.9.16.2 Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage' +[CIS - Microsoft Windows 10 - 18.9.16.2 Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DisableEnterpriseAuthProxy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DisableEnterpriseAuthProxy; +# +# +#18.9.39.2 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.39.2 Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.43.1 Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.43.1 Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging -> AllowMessageSync -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging -> !AllowMessageSync; +# +# +#18.9.45.1 Ensure 'Allow Address bar drop-down list suggestions' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.1 Ensure 'Allow Address bar drop-down list suggestions' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\ServiceUI -> ShowOneBox -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\ServiceUI -> !ShowOneBox; +# +# +#18.9.45.2 Ensure 'Allow Adobe Flash' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.2 Ensure 'Allow Adobe Flash' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Addons -> FlashPlayerEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Addons -> !FlashPlayerEnabled; +# +# +#18.9.45.3 Ensure 'Allow InPrivate Browsing' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.3 Ensure 'Allow InPrivate Browsing' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowInPrivate -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !AllowInPrivate; +# +# +#18.9.45.6 Ensure 'Configure Pop-up Blocker' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.6 Ensure 'Configure Pop-up Blocker' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowPopups -> !r:yes; +# +# +#18.9.45.7 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.7 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> ShowSearchSuggestionsGlobal -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> !ShowSearchSuggestionsGlobal; +# +# +#18.9.45.9 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.9 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> PreventAccessToAboutFlagsInMicrosoftEdge -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !PreventAccessToAboutFlagsInMicrosoftEdge; +# +# +#18.9.45.10 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.10 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> HideLocalHostIP -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !HideLocalHostIP; +# +# +#18.9.57.1 Ensure 'Turn off Push To Install service' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.57.1 Ensure 'Turn off Push To Install service' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall -> DisablePushToInstall -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall -> !DisablePushToInstall; +# +# +#18.9.58.3.2.1 Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.2.1 Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDenyTSConnections -> !1; +# +# +#18.9.58.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.58.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.58.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.58.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows 10 - 18.9.58.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.58.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows 10 - 18.9.58.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.60.2 Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search' +[CIS - Microsoft Windows 10 - 18.9.60.2 Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCloudSearch -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCloudSearch; +# +# +#18.9.65.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.65.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.68.1 Ensure 'Disable all apps from Windows Store' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.68.1 Ensure 'Disable all apps from Windows Store' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableStoreApps -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableStoreApps; +# +# +#18.9.68.4 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.68.4 Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.76.3.2 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.3.2 Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.76.9.1 Ensure 'Configure Watson events' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.9.1 Ensure 'Configure Watson events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> DisableGenericRePorts -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> !DisableGenericRePorts; +# +# +#18.9.84.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.84.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowSuggestedAppsInWindowsInkWorkspace -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowSuggestedAppsInWindowsInkWorkspace; +# +# +#18.9.85.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.85.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.97.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.98.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.98.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# +# +# diff --git a/openarmor-rules/shared/cis_win2012r2_domainL1_rcl.txt b/openarmor-rules/shared/cis_win2012r2_domainL1_rcl.txt new file mode 100644 index 000000000..7f9ae1116 --- /dev/null +++ b/openarmor-rules/shared/cis_win2012r2_domainL1_rcl.txt @@ -0,0 +1,1062 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L1 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +# +#1.1.2 Ensure 'Maximum password age' is set to '60 or fewer days, but not 0' +[CIS - Microsoft Windows Server 2012 R2 - Ensure 'Maximum password age' is set to '60 or fewer days, but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3D; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3E; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3F; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:A\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:B\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:C\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:E\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:F\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:\w\w\w+; +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.2: Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.4: Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.1: Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.2: Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.1: Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.2: Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.5.1 Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only) +[CIS - Microsoft Windows Server 2012 R2 - 2.3.5.1: Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl -> !0; + +# +# +#2.3.5.2 Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.5.2: Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters -> LDAPServerIntegrity -> !2; +# +# +#2.3.5.3 Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.5.3: Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RefusePasswordChange -> 1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.1: Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.2: Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.3: Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.4: Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> 1; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.6: Ensure 'Domain member: Require strong session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> 0; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.1: Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DontDisplayLastUserName; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.2: Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableCAD; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.3: Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.7: Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.9: Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.1: Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.2: Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.3: Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.1: Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.2: Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.3: Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.4: Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.5: Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.6: Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> !r:lsarpc|netlogon|samr; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.7: Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.8: Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.9: Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.10: Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.11 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.11: Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.1: Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.2: Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.3: Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.4: Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.5: Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.6: Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.7: Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.9: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption''] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.10: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.13.1: Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.1: Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.2: Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.1: Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.2: Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.3: Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.4: Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.5: Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.6: Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.7: Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.8: Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.9: Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.1: Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.2: Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.3: Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.4: Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.5: Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.6: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.7: Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.8: Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.9: Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.1: Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.2: Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.3: Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.4: Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.5: Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.6: Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.8: Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.9: Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.1: Ensure 'Windows Firewall: Public: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.2: Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.3: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.4: Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.5: Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.6: Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.8: Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.9: Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.10: Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.1: Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.2: Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.1: Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.2: Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.3: Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.4: Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.6: Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.8: Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.9: Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.12: Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.2: Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.3: Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.21.1: Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.6.2: Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.3.1: Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.12.1: Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.2: Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.3: Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.4: Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.1: Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.2 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.2: Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.3 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.3: Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.4 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.4: Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.5 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.5: Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.1: Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.2: Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.6.1: Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.1: Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.2: Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.3: Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.1: Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.2: Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> !0; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.47.2 Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.2: Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> DisableFileSync -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> !DisableFileSync; +# +# +#18.9.52.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.2: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.61.1 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.1: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.2 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.2: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.70.2.1 Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.2.1: Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting\Consent -> DefaultConsent -> !1; +# +# +#18.9.70.3 Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.3: Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> AutoApproveOSDumps -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !AutoApproveOSDumps; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# diff --git a/openarmor-rules/shared/cis_win2012r2_domainL2_rcl.txt b/openarmor-rules/shared/cis_win2012r2_domainL2_rcl.txt new file mode 100644 index 000000000..065d077a2 --- /dev/null +++ b/openarmor-rules/shared/cis_win2012r2_domainL2_rcl.txt @@ -0,0 +1,340 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L2 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.4: Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.5: Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.7: Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.10: Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.11: Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.1: Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.2: Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.10.2: Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2012 R2 - 18.4.19.2.1: Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.1: Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.2: Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.1: Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.2: Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.3: Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.4: Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.5: Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.6: Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.7: Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.8: Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.9: Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.10: Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.11: Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.12: Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.13: Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.14: Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.24.1: Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.1: Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.29.5.2 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.2: Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.5.1: Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.11.1: Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.41.1: Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.44.1.1: Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.9.37.1 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.37.1: Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.2.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.3: Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.4: Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.1: Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.2: Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.54.3 Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.3: Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> ConnectedSearchPrivacy -> !3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !ConnectedSearchPrivacy; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.59.1: Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.3 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.3: Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.69.3.1: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.3: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.2: Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.87.1: Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# diff --git a/openarmor-rules/shared/cis_win2012r2_memberL1_rcl.txt b/openarmor-rules/shared/cis_win2012r2_memberL1_rcl.txt new file mode 100644 index 000000000..54f63b617 --- /dev/null +++ b/openarmor-rules/shared/cis_win2012r2_memberL1_rcl.txt @@ -0,0 +1,1129 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L2 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +#1.1.2 Ensure 'Maximum password age' is set to '60 or fewer days, but not 0' +[CIS - Microsoft Windows Server 2012 R2 - Ensure 'Maximum password age' is set to '60 or fewer days, but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3D; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3E; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3F; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:A\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:B\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:C\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:E\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:F\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:\w\w\w+; +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.2: Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.4: Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.1: Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.2: Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.1: Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.2: Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.1: Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.2: Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.3: Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.4: Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> 1; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.6: Ensure 'Domain member: Require strong session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> 0; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.1: Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DontDisplayLastUserName; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.2: Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableCAD; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.3: Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.7: Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.8 Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.8: Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ForceUnlockLogon -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !ForceUnlockLogon; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.9: Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.1: Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.2: Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.3: Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.1: Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.2: Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.3: Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.4: Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.5: Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> SMBServerNameHardeningLevel -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> !SMBServerNameHardeningLevel; +# +# +#2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.2: Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymousSAM -> 0; +# +# +#2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.3: Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.5: Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.6: Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> r:\S*; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.7: Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.8: Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.9: Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.10: Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.11 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.11: Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.1: Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.2: Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.3: Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.4: Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.5: Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.6: Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.7: Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.9: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption''] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.10: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.13.1: Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.1: Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.2: Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.1: Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.2: Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.3: Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.4: Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.5: Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.6: Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.7: Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.8: Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.9: Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.1: Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.2: Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.3: Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.4: Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.5: Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.6: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.7: Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.8: Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.9: Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.1: Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.2: Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.3: Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.4: Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.5: Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.6: Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.8: Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.9: Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.1: Ensure 'Windows Firewall: Public: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.2: Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.3: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.4: Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.5: Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.6: Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.8: Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.9: Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.10: Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.1: Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.2: Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed +[CIS - Microsoft Windows Server 2012 R2 - 18.2.1: Ensure LAPS AdmPwd GPO Extension / CSE is installed] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA} -> !DllName; +# +# +#18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.2: Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PwdExpirationProtectionEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PwdExpirationProtectionEnabled; +# +# +#18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.3: Ensure 'Enable Local Admin Password Management' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> AdmPwdEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !AdmPwdEnabled; +# +# +#18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.4: Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordComplexity -> !4; +# +# +#18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.5: Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PasswordLength; +# +# +#18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.6: Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> 1F; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:2\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:3\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:4\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:5\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:6\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:7\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:8\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:9\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\w\w\w+; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.1: Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.2: Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.3: Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.4: Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.6: Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.8: Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.9: Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.12: Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.2: Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.3: Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.21.1: Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.6.1: Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> LocalAccountTokenFilterPolicy -> !0; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.6.2: Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.3.1: Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.12.1: Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.2: Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.3: Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.4: Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.1: Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.2 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.2: Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.3 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.3: Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.4 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.4: Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.5 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.5: Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.1: Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.2: Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.8.32.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.32.1: Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> EnableAuthEpResolution -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !EnableAuthEpResolution; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.6.1: Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.1: Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.2: Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.3: Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.1: Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.2: Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> !0; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.47.2 Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.2: Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> DisableFileSync -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> !DisableFileSync; +# +# +#18.9.52.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.2: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.61.1 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.1: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.2 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.2: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.70.2.1 Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.2.1: Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting\Consent -> DefaultConsent -> !1; +# +# +#18.9.70.3 Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.3: Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> AutoApproveOSDumps -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !AutoApproveOSDumps; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# +# +# diff --git a/openarmor-rules/shared/cis_win2012r2_memberL2_rcl.txt b/openarmor-rules/shared/cis_win2012r2_memberL2_rcl.txt new file mode 100644 index 000000000..994e24cda --- /dev/null +++ b/openarmor-rules/shared/cis_win2012r2_memberL2_rcl.txt @@ -0,0 +1,378 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L2 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +#2.3.7.6 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' +[CIS - Microsoft Windows Server 2012 R2 - Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> f; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> \w\w+; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !CachedLogonsCount; +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.4: Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.5: Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.7: Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.10: Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.11: Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.1: Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.2: Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.10.2: Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2012 R2 - 18.4.19.2.1: Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.1: Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.2: Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.4.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.21.2: Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fBlockNonDomain -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> !fBlockNonDomain; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.1: Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.2: Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.3: Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.4: Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.5: Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.6: Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.7: Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.8: Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.9: Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.10: Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.11: Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.12: Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.13: Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.14: Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.24.1: Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.1: Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> !DCSettingIndex; +# +# +#18.8.29.5.2 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.2: Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> !ACSettingIndex; +# +# +#18.8.32.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.32.2: Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> RestrictRemoteClients -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !RestrictRemoteClients; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.5.1: Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.11.1: Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.41.1: Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.44.1.1: Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.8.44.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.44.1.2: Ensure 'Enable Windows NTP Server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer -> Enabled -> !0; +# +# +#18.9.37.1 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.37.1: Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.2.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.3: Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.4: Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.1: Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.2: Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.54.3 Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.3: Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> ConnectedSearchPrivacy -> !3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !ConnectedSearchPrivacy; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.59.1: Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.3 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.3: Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.69.3.1: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.3: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.2: Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.87.1: Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# + + diff --git a/openarmor-rules/shared/cis_win2016_domainL1_rcl.txt b/openarmor-rules/shared/cis_win2016_domainL1_rcl.txt new file mode 100644 index 000000000..bf595046e --- /dev/null +++ b/openarmor-rules/shared/cis_win2016_domainL1_rcl.txt @@ -0,0 +1,1144 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Domain Controller L1 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2016 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2016 - 2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.5.1 Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.5.1 Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl -> !0; +# +# +#2.3.5.2 Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' +[CIS - Microsoft Windows Server 2016 - 2.3.5.2 Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters -> LDAPServerIntegrity -> !2; +# +# +#2.3.5.3 Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.5.3 Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RefusePasswordChange -> 1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> !0; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.6 Ensure 'Domain member: Require strong session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> !1; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> !1; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> !0; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2016 - 2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2016 - 2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2016 - 2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2016 - 2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> !r:lsarpc|netlogon|samr; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.7 Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2016 - 2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2016 - 2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2016 - 2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2016 - 2.3.11.7: Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.11.8: Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.9: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.10: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.13.1: Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.1: Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.2: Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.1: Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.2: Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2016 - 2.3.17.3: Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2016 - 2.3.17.4: Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.5: Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.6: Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.7: Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.8: Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.9: Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.1.1: Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block' +[CIS - Microsoft Windows Server 2016 - 9.1.2: Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow' +[CIS - Microsoft Windows Server 2016 - 9.1.3: Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.1.4: Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.5: Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.6: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.1.7: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.1.8: Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.9: Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.2.1: Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block' +[CIS - Microsoft Windows Server 2016 - 9.2.2: Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.3: Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.2.4: Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.5: Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.6: Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\privatefw.log' +[CIS - Microsoft Windows Server 2016 - 9.2.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\privatefw.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.2.8: Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.9: Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.10: Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows Server 2016 - 9.3.1: Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.2: Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.3: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.4: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.5: Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.6: Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\publicfw.log' +[CIS - Microsoft Windows Server 2016 - 9.3.7: Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\publicfw.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.3.8: Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.9: Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.10: Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.1: Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.2: Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.1.2.1 Ensure 'Allow Input Personalization' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.1.2.1: Ensure 'Allow Input Personalization' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> AllowInputPersonalization -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> !AllowInputPersonalization; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.1: Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.2: Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.3: Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.4: Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.6: Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.8: Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2016 - 18.3.9: Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2016 - 18.3.12: Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.8.1: Ensure 'Enable insecure guest logons' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> AllowInsecureGuestAuth -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> !AllowInsecureGuestAuth; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.2: Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.3: Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_ShowSharedAccessUI -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_ShowSharedAccessUI; +# +# +#18.4.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.4: Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.21.1: Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.6.2: Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.3.1: Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2016 - 18.8.12.1: Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.2: Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.3: Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Continue experiences on this device' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.4: Ensure 'Continue experiences on this device' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableCdp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableCdp; +# +# +#18.8.19.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.5: Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.1: Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockUserFromShowingAccountDetailsOnSignin -> !1; +# +# +#18.8.25.2 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.2: Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.3: Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.4: Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.5: Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.6 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.6: Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.26.1 Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events' +[CIS - Microsoft Windows Server 2016 - 18.8.26.1: Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions -> MitigationOptions_FontBocking -> !1000000000000; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.1: Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.2: Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.1: Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.8.1: Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2016 - 18.9.8.2: Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2016 - 18.9.8.3: Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.10.1.1 Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.10.1.1: Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> EnhancedAntiSpoofing -> !1; +# +# +#18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.13.1: Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> DisableWindowsConsumerFeatures -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> !DisableWindowsConsumerFeatures; +# +# +#18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled' (Scored) +[CIS - Microsoft Windows Server 2016 - 18.9.14.1: Ensure 'Require pin for pairing' is set to 'Enabled' (Scored)] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> RequirePinForPairing -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> !RequirePinForPairing; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.1: Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.2: Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.16.1 Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security [Enterprise Only]' +[CIS - Microsoft Windows Server 2016 - 18.9.16.1: Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security (Enterprise Only)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> AllowTelemetry -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !AllowTelemetry; +# +# +#18.9.16.2 Ensure 'Disable pre-release features or settings' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.2: Ensure 'Disable pre-release features or settings' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> EnableConfigFlighting -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !EnableConfigFlighting; +# +# +#18.9.16.3 Ensure 'Do not show feedback notifications' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.3: Ensure 'Do not show feedback notifications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DoNotShowFeedbackNotifications -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DoNotShowFeedbackNotifications; +# +# +#18.9.16.4 Ensure 'Toggle user control over Insider builds' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.4: Ensure 'Toggle user control over Insider builds' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> AllowBuildPreview -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !AllowBuildPreview; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> 1; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.41.3 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher +[CIS - Microsoft Windows Server 2016 - 18.9.41.3: Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> Cookies -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !Cookies; +# +# +#18.9.41.4 Ensure 'Configure Password Manager' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.4: Ensure 'Configure Password Manager' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> FormSuggest Passwords -> !no; +# +# +#18.9.41.6 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.6: Ensure 'Configure search suggestions in Address bar' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> ShowSearchSuggestionsGlobal -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> !ShowSearchSuggestionsGlobal; +# +# +#18.9.41.7 Ensure 'Configure SmartScreen Filter' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.7: Ensure 'Configure SmartScreen Filter' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> EnabledV9 -> !1; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.52.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdma -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow Cortana' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.2: Ensure 'Allow Cortana' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortana -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortana; +# +# +#18.9.54.3 Ensure 'Allow Cortana above lock screen' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.3: Ensure 'Allow Cortana above lock screen' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortanaAboveLock -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortanaAboveLock; +# +# +#18.9.54.4 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.4: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.54.5 Ensure 'Allow search and Cortana to use location' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.5: Ensure 'Allow search and Cortana to use location' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowSearchToUseLocation -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowSearchToUseLocation; +# +# +#18.9.61.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.2: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.3: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.73.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On' +[CIS - Microsoft Windows Server 2016 - 18.9.73.2: Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowWindowsInkWorkspace -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowWindowsInkWorkspace; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2016 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# diff --git a/openarmor-rules/shared/cis_win2016_domainL2_rcl.txt b/openarmor-rules/shared/cis_win2016_domainL2_rcl.txt new file mode 100644 index 000000000..69cfcb32e --- /dev/null +++ b/openarmor-rules/shared/cis_win2016_domainL2_rcl.txt @@ -0,0 +1,468 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Domain Controller L2 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)' +[CIS - Microsoft Windows Server 2016 - 18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableFontProviders -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableFontProviders; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2016 - 18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' +[CIS - Microsoft Windows Server 2016 - 18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitBehavior -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitEnabled -> !1; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> DCSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !DCSettingIndex; +# +# +#18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> ACSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !ACSettingIndex; +# +# +#18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager -> AllowSharedLocalAppData -> !0; +# +# +#18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny' +[CIS - Microsoft Windows Server 2016 - 18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessAccountInfo -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessAccountInfo; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCallHistory -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCallHistory; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessContacts -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessContacts; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessEmail -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessEmail; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessLocation -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessLocation; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMessaging -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMessaging; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMotion -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMotion; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCalendar -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCalendar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCamera -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCamera; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMicrophone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMicrophone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessTrustedDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessTrustedDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessRadios -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessRadios; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsSyncWithDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsSyncWithDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessPhone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessPhone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessNotifications -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessNotifications; +# +# +#18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> BlockHostedAppAccessWinRT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !BlockHostedAppAccessWinRT; +# +# +#18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> AllowCamera -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> !AllowCamera; +# +# +#18.9.37.2 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.37.2 Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> ExtensionsEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> !ExtensionsEnabled; +# +# +#18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowInPrivate -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !AllowInPrivate; +# +# +#18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowPopups -> !r:yes; +# +# +#18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> PreventAccessToAboutFlagsInMicrosoftEdge -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !PreventAccessToAboutFlagsInMicrosoftEdge; +# +# +#18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverrideAppRepUnknown -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverrideAppRepUnknown; +# +# +#18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverride -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverride; +# +# +#18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> HideLocalHostIP -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !HideLocalHostIP; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableStoreApps -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableStoreApps; +# +# +#18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.69.8 Ensure 'Configure Watson events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.8 Ensure 'Configure Watson events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> DisableGenericRePorts -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> !DisableGenericRePorts; +# +# +#18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowSuggestedAppsInWindowsInkWorkspace -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowSuggestedAppsInWindowsInkWorkspace; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# diff --git a/openarmor-rules/shared/cis_win2016_memberL1_rcl.txt b/openarmor-rules/shared/cis_win2016_memberL1_rcl.txt new file mode 100644 index 000000000..ed9b215dd --- /dev/null +++ b/openarmor-rules/shared/cis_win2016_memberL1_rcl.txt @@ -0,0 +1,1226 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Member Server L1 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2016 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2016 - 2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> !0; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> 1; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> 0; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DontDisplayLastUserName; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableCAD; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2016 - 2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2016 - 2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.8 Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.8 Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ForceUnlockLogon -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !ForceUnlockLogon; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2016 - Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> SMBServerNameHardeningLevel -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> !SMBServerNameHardeningLevel; +# +# +#2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymousSAM -> 0; +# +# +#2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2016 - 2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> r:\S*; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.7 Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' +[CIS - Microsoft Windows Server 2016 - 2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> restrictremotesam -> !r:O:BAG:BAD:\(A;;RC;;;BA\); +# +# +#2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2016 - 2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2016 - 2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2016 - 2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2016 - 2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2016 - 2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2016 - 2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.1.2.1 Ensure 'Allow Input Personalization' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.1.2.1 Ensure 'Allow Input Personalization' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> AllowInputPersonalization -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> !AllowInputPersonalization; +# +# +#18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed +[CIS - Microsoft Windows Server 2016 - 18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA} -> !DllName; +# +# +#18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PwdExpirationProtectionEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PwdExpirationProtectionEnabled; +# +# +#18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> AdmPwdEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !AdmPwdEnabled; +# +# +#18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' +[CIS - Microsoft Windows Server 2016 - 18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordComplexity -> !4; +# +# +#18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' +[CIS - Microsoft Windows Server 2016 - 18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PasswordLength; +# +# +#18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' +[CIS - Microsoft Windows Server 2016 - 18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> 1F; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:2\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:3\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:4\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:5\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:6\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:7\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:8\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:9\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\w\w\w+; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2016 - 18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2016 - 18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)') +[CIS - Microsoft Windows Server 2016 - 18.4.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)')] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> NodeType -> !2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> !NodeType; +# +# +#18.4.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> EnableMulticast -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> !EnableMulticast; +# +# +#18.4.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> AllowInsecureGuestAuth -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> !AllowInsecureGuestAuth; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_ShowSharedAccessUI -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_ShowSharedAccessUI; +# +# +#18.4.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.6.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> LocalAccountTokenFilterPolicy -> !0; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2016 - 18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Continue experiences on this device' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.4 Ensure 'Continue experiences on this device' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableCdp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableCdp; +# +# +#18.8.19.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockUserFromShowingAccountDetailsOnSignin -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !BlockUserFromShowingAccountDetailsOnSignin; +# +# +#18.8.25.2 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.2 Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.6 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.6 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.26.1 Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events' +[CIS - Microsoft Windows Server 2016 - 18.8.26.1 Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions -> MitigationOptions_FontBocking -> !1000000000000; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions -> !MitigationOptions_FontBocking; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.8.32.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.32.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> EnableAuthEpResolution -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !EnableAuthEpResolution; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2016 - 18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2016 - 18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.10.1.1 Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.10.1.1 Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> EnhancedAntiSpoofing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> !EnhancedAntiSpoofing; +# +# +#18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> DisableWindowsConsumerFeatures -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> !DisableWindowsConsumerFeatures; +# +# +#18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> RequirePinForPairing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> !RequirePinForPairing; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.16.2 Ensure 'Disable pre-release features or settings' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.2 Ensure 'Disable pre-release features or settings' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> EnableConfigFlighting -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !EnableConfigFlighting; +# +# +#18.9.16.3 Ensure 'Do not show feedback notifications' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.3: Ensure 'Do not show feedback notifications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DoNotShowFeedbackNotifications -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DoNotShowFeedbackNotifications; +# +# +#18.9.16.4 Ensure 'Toggle user control over Insider builds' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.4: Ensure 'Toggle user control over Insider builds' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> AllowBuildPreview -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !AllowBuildPreview; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> 1; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.41.3 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher +[CIS - Microsoft Windows Server 2016 - 18.9.41.3: Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> Cookies -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !Cookies; +# +# +#18.9.41.4 Ensure 'Configure Password Manager' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.4: Ensure 'Configure Password Manager' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> FormSuggest Passwords -> !no; +# +# +#18.9.41.6 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.6: Ensure 'Configure search suggestions in Address bar' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> ShowSearchSuggestionsGlobal -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> !ShowSearchSuggestionsGlobal; +# +# +#18.9.41.7 Ensure 'Configure SmartScreen Filter' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.7: Ensure 'Configure SmartScreen Filter' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> EnabledV9 -> !1; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.52.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdma -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow Cortana' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.2: Ensure 'Allow Cortana' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortana -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortana; +# +# +#18.9.54.3 Ensure 'Allow Cortana above lock screen' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.3: Ensure 'Allow Cortana above lock screen' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortanaAboveLock -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortanaAboveLock; +# +# +#18.9.54.4 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.4: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.54.5 Ensure 'Allow search and Cortana to use location' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.5: Ensure 'Allow search and Cortana to use location' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowSearchToUseLocation -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowSearchToUseLocation; +# +# +#18.9.61.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.2: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.3: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.73.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On' +[CIS - Microsoft Windows Server 2016 - 18.9.73.2: Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowWindowsInkWorkspace -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowWindowsInkWorkspace; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2016 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# diff --git a/openarmor-rules/shared/cis_win2016_memberL2_rcl.txt b/openarmor-rules/shared/cis_win2016_memberL2_rcl.txt new file mode 100644 index 000000000..122baf224 --- /dev/null +++ b/openarmor-rules/shared/cis_win2016_memberL2_rcl.txt @@ -0,0 +1,492 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Member Server L2 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +# +#2.3.7.6 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' +[CIS - Microsoft Windows Server 2016 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> !4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !CachedLogonsCount; +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)' +[CIS - Microsoft Windows Server 2016 - 18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableFontProviders -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableFontProviders; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2016 - 18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.4.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fBlockNonDomain -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> !fBlockNonDomain; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' +[CIS - Microsoft Windows Server 2016 - 18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitBehavior -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitEnabled -> !1; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> DCSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !DCSettingIndex; +# +# +#18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> ACSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !ACSettingIndex; +# +# +#18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.32.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' +[CIS - Microsoft Windows Server 2016 - 18.8.32.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> RestrictRemoteClients -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !RestrictRemoteClients; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.8.44.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.44.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer -> Enabled -> !0; +# +# +#18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager -> AllowSharedLocalAppData -> !0; +# +# +#18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny' +[CIS - Microsoft Windows Server 2016 - 18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessAccountInfo -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessAccountInfo; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCallHistory -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCallHistory; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessContacts -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessContacts; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessEmail -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessEmail; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessLocation -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessLocation; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMessaging -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMessaging; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMotion -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMotion; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCalendar -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCalendar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCamera -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCamera; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMicrophone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMicrophone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessTrustedDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessTrustedDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessRadios -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessRadios; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsSyncWithDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsSyncWithDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessPhone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessPhone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessNotifications -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessNotifications; +# +# +#18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> BlockHostedAppAccessWinRT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !BlockHostedAppAccessWinRT; +# +# +#18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> AllowCamera -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> !AllowCamera; +# +# +#18.9.37.2 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.37.2 Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> ExtensionsEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> !ExtensionsEnabled; +# +# +#18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowInPrivate -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !AllowInPrivate; +# +# +#18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowPopups -> !r:yes; +# +# +#18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> PreventAccessToAboutFlagsInMicrosoftEdge -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !PreventAccessToAboutFlagsInMicrosoftEdge; +# +# +#18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverrideAppRepUnknown -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverrideAppRepUnknown; +# +# +#18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverride -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverride; +# +# +#18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> HideLocalHostIP -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !HideLocalHostIP; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableStoreApps -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableStoreApps; +# +# +#18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.69.8.1 Ensure 'Configure Watson events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.8 Ensure 'Configure Watson events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> DisableGenericRePorts -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> !DisableGenericRePorts; +# +# +#18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowSuggestedAppsInWindowsInkWorkspace -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowSuggestedAppsInWindowsInkWorkspace; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# diff --git a/openarmor-rules/shared/rootkit_files.txt b/openarmor-rules/shared/rootkit_files.txt new file mode 100644 index 000000000..c7dc6d580 --- /dev/null +++ b/openarmor-rules/shared/rootkit_files.txt @@ -0,0 +1,419 @@ +# rootkit_files.txt, (C) 2018 openarmor Project +# Imported from the rootcheck project. +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# Blank lines and lines starting with '#' are ignored. +# +# Each line must be in the following format: +# file_name ! Name ::Link to it +# +# Files that start with an '*' will be searched in the whole system. + +# Bash door +tmp/mcliZokhb ! Bash door ::/rootkits/bashdoor.php +tmp/mclzaKmfa ! Bash door ::/rootkits/bashdoor.php + +# adore Worm +dev/.shit/red.tgz ! Adore Worm ::/rootkits/adorew.php +usr/lib/libt ! Adore Worm ::/rootkits/adorew.php +usr/bin/adore ! Adore Worm ::/rootkits/adorew.php +*/klogd.o ! Adore Worm ::/rootkits/adorew.php +*/red.tar ! Adore Worm ::/rootkits/adorew.php + +# T.R.K rootkit +usr/bin/soucemask ! TRK rootkit ::/rootkits/trk.php +usr/bin/sourcemask ! TRK rootkit ::/rootkits/trk.php + +# 55.808.A Worm +tmp/.../a ! 55808.A Worm :: +tmp/.../r ! 55808.A Worm :: + +# Volc Rootkit +usr/lib/volc ! Volc Rootkit :: +usr/bin/volc ! Volc Rootkit :: + +# Illogic +lib/security/.config ! Illogic Rootkit ::rootkits/illogic.php +usr/bin/sia ! Illogic Rootkit ::rootkits/illogic.php +etc/ld.so.hash ! Illogic Rootkit ::rootkits/illogic.php +*/uconf.inv ! Illogic Rootkit ::rootkits/illogic.php + +# T0rnkit +usr/src/.puta ! t0rn Rootkit ::rootkits/torn.php +usr/info/.t0rn ! t0rn Rootkit ::rootkits/torn.php +lib/ldlib.tk ! t0rn Rootkit ::rootkits/torn.php +etc/ttyhash ! t0rn Rootkit ::rootkits/torn.php +sbin/xlogin ! t0rn Rootkit ::rootkits/torn.php +*/ldlib.tk ! t0rn Rootkit ::rootkits/torn.php +*/.t0rn ! t0rn Rootkit ::rootkits/torn.php +*/.puta ! t0rn Rootkit ::rootkits/torn.php + +# RK17 +bin/rtty ! RK17 :: +bin/squit ! RK17 :: +sbin/pback ! RK17 :: +proc/kset ! RK17 :: +usr/src/linux/modules/autod.o ! RK17 :: +usr/src/linux/modules/soundx.o ! RK17 :: + +# Ramen Worm +usr/lib/ldlibps.so ! Ramen Worm ::rootkits/ramen.php +usr/lib/ldlibns.so ! Ramen Worm ::rootkits/ramen.php +usr/lib/ldliblogin.so ! Ramen Worm ::rootkits/ramen.php +usr/src/.poop ! Ramen Worm ::rootkits/ramen.php +tmp/ramen.tgz ! Ramen Worm ::rootkits/ramen.php +etc/xinetd.d/asp ! Ramen Worm ::rootkits/ramen.php + +# Sadmind/IIS Worm +dev/cuc ! Sadmind/IIS Worm :: + +# Monkit +lib/defs ! Monkit :: +usr/lib/libpikapp.a ! Monkit found :: + +# RSHA +usr/bin/kr4p ! RSHA :: +usr/bin/n3tstat ! RSHA :: +usr/bin/chsh2 ! RSHA :: +usr/bin/slice2 ! RSHA :: +etc/rc.d/rsha ! RSHA :: + +# ShitC worm +bin/home ! ShitC :: +sbin/home ! ShitC :: +usr/sbin/in.slogind ! ShitC :: + +# Omega Worm +dev/chr ! Omega Worm :: + +# rh-sharpe +bin/.ps ! Rh-Sharpe :: +usr/bin/cleaner ! Rh-Sharpe :: +usr/bin/slice ! Rh-Sharpe :: +usr/bin/vadim ! Rh-Sharpe :: +usr/bin/.ps ! Rh-Sharpe :: +bin/.lpstree ! Rh-Sharpe :: +usr/bin/.lpstree ! Rh-Sharpe :: +usr/bin/lnetstat ! Rh-Sharpe :: +bin/lnetstat ! Rh-Sharpe :: +usr/bin/ldu ! Rh-Sharpe :: +bin/ldu ! Rh-Sharpe :: +usr/bin/lkillall ! Rh-Sharpe :: +bin/lkillall ! Rh-Sharpe :: +usr/include/rpcsvc/du ! Rh-Sharpe :: + +# Maniac RK +usr/bin/mailrc ! Maniac RK :: + +# Showtee / Romanian +usr/lib/.egcs ! Showtee :: +usr/lib/.wormie ! Showtee :: +usr/lib/.kinetic ! Showtee :: +usr/lib/liblog.o ! Showtee :: +usr/include/addr.h ! Showtee / Romanian rootkit :: +usr/include/cron.h ! Showtee :: +usr/include/file.h ! Showtee / Romanian rootkit :: +usr/include/syslogs.h ! Showtee / Romanian rootkit :: +usr/include/proc.h ! Showtee / Romanian rootkit :: +usr/include/chk.h ! Showtee :: +usr/sbin/initdl ! Romanian rootkit :: +usr/sbin/xntps ! Romanian rootkit :: + +# Optickit +usr/bin/xchk ! Optickit :: +usr/bin/xsf ! Optickit :: + +# LDP worm +dev/.kork ! LDP Worm :: +bin/.login ! LDP Worm :: +bin/.ps ! LDP Worm :: + +# Telekit +dev/hda06 ! TeLeKit trojan :: +usr/info/libc1.so ! TeleKit trojan :: + +# Tribe bot +dev/wd4 ! Tribe bot :: + +# LRK +dev/ida/.inet ! LRK rootkit ::rootkits/lrk.php +*/bindshell ! LRK rootkit ::rootkits/lrk.php + +# Adore Rootkit +etc/bin/ava ! Adore Rootkit :: +etc/sbin/ava ! Adore Rootkit :: + +# Slapper +tmp/.bugtraq ! Slapper installed :: +tmp/.bugtraq.c ! Slapper installed :: +tmp/.cinik ! Slapper installed :: +tmp/.b ! Slapper installed :: +tmp/httpd ! Slapper installed :: +tmp./update ! Slapper installed :: +tmp/.unlock ! Slapper installed :: +tmp/.font-unix/.cinik ! Slapper installed :: +tmp/.cinik ! Slapper installed :: + +# Scalper +tmp/.uua ! Scalper installed :: +tmp/.a ! Scalper installed :: + +# Knark +proc/knark ! Knark Installed ::rootkits/knark.php +dev/.pizda ! Knark Installed ::rootkits/knark.php +dev/.pula ! Knark Installed ::rootkits/knark.php +dev/.pula ! Knark Installed ::rootkits/knark.php +*/taskhack ! Knark Installed ::rootkits/knark.php +*/rootme ! Knark Installed ::rootkits/knark.php +*/nethide ! Knark Installed ::rootkits/knark.php +*/hidef ! Knark Installed ::rootkits/knark.php +*/ered ! Knark Installed ::rootkits/knark.php + +# Lion worm +dev/.lib ! Lion Worm ::rootkits/lion.php +dev/.lib/1iOn.sh ! Lion Worm ::rootkits/lion.php +bin/mjy ! Lion Worm ::rootkits/lion.php +bin/in.telnetd ! Lion Worm ::rootkits/lion.php +usr/info/torn ! Lion Worm ::rootkits/lion.php +*/1iOn\.sh ! Lion Worm ::rootkits/lion.php + +# Bobkit +usr/include/.../ ! Bobkit Rootkit ::rootkits/bobkit.php +usr/lib/.../ ! Bobkit Rootkit ::rootkits/bobkit.php +usr/sbin/.../ ! Bobkit Rootkit ::rootkits/bobkit.php +usr/bin/ntpsx ! Bobkit Rootkit ::rootkits/bobkit.php +tmp/.bkp ! Bobkit Rootkit ::rootkits/bobkit.php +usr/lib/.bkit- ! Bobkit Rootkit ::rootkits/bobkit.php +*/bkit- ! Bobkit Rootkit ::rootkits/bobkit.php + +# Hidrootkit +var/lib/games/.k ! Hidr00tkit :: + +# Ark +dev/ptyxx ! Ark rootkit :: + +# Mithra Rootkit +usr/lib/locale/uboot ! Mithra`s rootkit :: + +# Optickit +usr/bin/xsf ! OpticKit :: +usr/bin/xchk ! OpticKit :: + +# LOC rookit +tmp/xp ! LOC rookit :: +tmp/kidd0.c ! LOC rookit :: +tmp/kidd0 ! LOC rookit :: + +# TC2 worm +usr/info/.tc2k ! TC2 Worm :: +usr/bin/util ! TC2 Worm :: +usr/sbin/initcheck ! TC2 Worm :: +usr/sbin/ldb ! TC2 Worm :: + +# Anonoiyng rootkit +usr/sbin/mech ! Anonoiyng rootkit :: +usr/sbin/kswapd ! Anonoiyng rootkit :: + +# SuckIt +lib/.x ! SuckIt rootkit :: +*/hide.log ! Suckit rootkit :: +lib/sk ! SuckIT rootkit :: + +# Beastkit +usr/local/bin/bin ! Beastkit rootkit ::rootkits/beastkit.php +usr/man/.man10 ! Beastkit rootkit ::rootkits/beastkit.php +usr/sbin/arobia ! Beastkit rootkit ::rootkits/beastkit.php +usr/lib/elm/arobia ! Beastkit rootkit ::rootkits/beastkit.php +usr/local/bin/.../bktd ! Beastkit rootkit ::rootkits/beastkit.php + +# Tuxkit +dev/tux ! Tuxkit rootkit ::rootkits/Tuxkit.php +usr/bin/xsf ! Tuxkit rootkit ::rootkits/Tuxkit.php +usr/bin/xchk ! Tuxkit rootkit ::rootkits/Tuxkit.php +*/.file ! Tuxkit rootkit ::rootkits/Tuxkit.php +*/.addr ! Tuxkit rootkit ::rootkits/Tuxkit.php + +# Old rootkits +usr/include/rpc/ ../kit ! Old rootkits ::rootkits/Old.php +usr/include/rpc/ ../kit2 ! Old rootkits ::rootkits/Old.php +usr/doc/.sl ! Old rootkits ::rootkits/Old.php +usr/doc/.sp ! Old rootkits ::rootkits/Old.php +usr/doc/.statnet ! Old rootkits ::rootkits/Old.php +usr/doc/.logdsys ! Old rootkits ::rootkits/Old.php +usr/doc/.dpct ! Old rootkits ::rootkits/Old.php +usr/doc/.gifnocfi ! Old rootkits ::rootkits/Old.php +usr/doc/.dnif ! Old rootkits ::rootkits/Old.php +usr/doc/.nigol ! Old rootkits ::rootkits/Old.php + +# Kenga3 rootkit +usr/include/. . ! Kenga3 rootkit + +# ESRK rootkit +usr/lib/tcl5.3 ! ESRK rootkit + +# Fu rootkit +sbin/xc ! Fu rootkit +usr/include/ivtype.h ! Fu rootkit +bin/.lib ! Fu rootkit + +# ShKit rootkit +lib/security/.config ! ShKit rootkit +etc/ld.so.hash ! ShKit rootkit + +# AjaKit rootkit +lib/.ligh.gh ! AjaKit rootkit +lib/.libgh.gh ! AjaKit rootkit +lib/.libgh-gh ! AjaKit rootkit +dev/tux ! AjaKit rootkit +dev/tux/.proc ! AjaKit rootkit +dev/tux/.file ! AjaKit rootkit + +# zaRwT rootkit +bin/imin ! zaRwT rootkit +bin/imout ! zaRwT rootkit + +# Madalin rootkit +usr/include/icekey.h ! Madalin rootkit +usr/include/iceconf.h ! Madalin rootkit +usr/include/iceseed.h ! Madalin rootkit + +# shv5 rootkit XXX http://www.askaboutskating.com/forum/.../shv5/setup +lib/libsh.so ! shv5 rootkit +usr/lib/libsh ! shv5 rootkit + +# BMBL rootkit (http://www.giac.com/practical/GSEC/Steve_Terrell_GSEC.pdf) +etc/.bmbl ! BMBL rootkit +etc/.bmbl/sk ! BMBL rootkit + +# rootedoor rootkit +*/rootedoor ! Rootedoor rootkit + +# 0vason rootkit +*/ovas0n ! ovas0n rootkit ::/rootkits/ovason.php +*/ovason ! ovas0n rootkit ::/rootkits/ovason.php + +# Rpimp reverse telnet +*/rpimp ! rpv21 (Reverse Pimpage)::/rootkits/rpimp.php + +# Cback Linux worm +tmp/cback ! cback worm ::/rootkits/cback.php +tmp/derfiq ! cback worm ::/rootkits/cback.php + +# aPa Kit (from rkhunter) +usr/share/.aPa ! Apa Kit + +# enye-sec Rootkit +etc/.enyelkmHIDE^IT.ko ! enye-sec Rootkit ::/rootkits/enye-sec.php + +# Override Rootkit +dev/grid-hide-pid- ! Override rootkit ::/rootkits/override.php +dev/grid-unhide-pid- ! Override rootkit ::/rootkits/override.php +dev/grid-show-pids ! Override rootkit ::/rootkits/override.php +dev/grid-hide-port- ! Override rootkit ::/rootkits/override.php +dev/grid-unhide-port- ! Override rootkit ::/rootkits/override.php + +# PHALANX rootkit +usr/share/.home* ! PHALANX rootkit :: +usr/share/.home*/tty ! PHALANX rootkit :: +etc/host.ph1 ! PHALANX rootkit :: +bin/host.ph1 ! PHALANX rootkit :: + +# ZK rootkit (http://honeyblog.org/junkyard/reports/redhat-compromise2.pdf) +# and from chkrootkit +usr/share/.zk ! ZK rootkit :: +usr/share/.zk/zk ! ZK rootkit :: +etc/1ssue.net ! ZK rootkit :: +usr/X11R6/.zk ! ZK rootkit :: +usr/X11R6/.zk/xfs ! ZK rootkit :: +usr/X11R6/.zk/echo ! ZK rootkit :: +etc/sysconfig/console/load.zk ! ZK rootkit :: + +# Public sniffers +*/.linux-sniff ! Sniffer log :: +*/sniff-l0g ! Sniffer log :: +*/core_$ ! Sniffer log :: +*/tcp.log ! Sniffer log :: +*/chipsul ! Sniffer log :: +*/beshina ! Sniffer log :: +*/.owned$ | Sniffer log :: + +# Solaris worm - +# http://blogs.sun.com/security/entry/solaris_in_telnetd_worm_seen +var/adm/.profile ! Solaris Worm :: +var/spool/lp/.profile ! Solaris Worm :: +var/adm/sa/.adm ! Solaris Worm :: +var/spool/lp/admins/.lp ! Solaris Worm :: + +# Suspicious files +etc/rc.d/init.d/rc.modules ! Suspicious file ::rootkits/Suspicious.php +lib/ldd.so ! Suspicious file ::rootkits/Suspicious.php +usr/man/muie ! Suspicious file ::rootkits/Suspicious.php +usr/X11R6/include/pain ! Suspicious file ::rootkits/Suspicious.php +usr/bin/sourcemask ! Suspicious file ::rootkits/Suspicious.php +usr/bin/ras2xm ! Suspicious file ::rootkits/Suspicious.php +usr/bin/ddc ! Suspicious file ::rootkits/Suspicious.php +usr/bin/jdc ! Suspicious file ::rootkits/Suspicious.php +usr/sbin/in.telnet ! Suspicious file ::rootkits/Suspicious.php +sbin/vobiscum ! Suspicious file ::rootkits/Suspicious.php +usr/sbin/jcd ! Suspicious file ::rootkits/Suspicious.php +usr/sbin/atd2 ! Suspicious file ::rootkits/Suspicious.php +usr/bin/ishit ! Suspicious file ::rootkits/Suspicious.php +usr/bin/.etc ! Suspicious file ::rootkits/Suspicious.php +usr/bin/xstat ! Suspicious file ::rootkits/Suspicious.php +var/run/.tmp ! Suspicious file ::rootkits/Suspicious.php +usr/man/man1/lib/.lib ! Suspicious file ::rootkits/Suspicious.php +usr/man/man2/.man8 ! Suspicious file ::rootkits/Suspicious.php +var/run/.pid ! Suspicious file ::rootkits/Suspicious.php +lib/.so ! Suspicious file ::rootkits/Suspicious.php +lib/.fx ! Suspicious file ::rootkits/Suspicious.php +lib/lblip.tk ! Suspicious file ::rootkits/Suspicious.php +usr/lib/.fx ! Suspicious file ::rootkits/Suspicious.php +var/local/.lpd ! Suspicious file ::rootkits/Suspicious.php +dev/rd/cdb ! Suspicious file ::rootkits/Suspicious.php +dev/.rd/ ! Suspicious file ::rootkits/Suspicious.php +usr/lib/pt07 ! Suspicious file ::rootkits/Suspicious.php +usr/bin/atm ! Suspicious file ::rootkits/Suspicious.php +tmp/.cheese ! Suspicious file ::rootkits/Suspicious.php +dev/.arctic ! Suspicious file ::rootkits/Suspicious.php +dev/.xman ! Suspicious file ::rootkits/Suspicious.php +dev/.golf ! Suspicious file ::rootkits/Suspicious.php +dev/srd0 ! Suspicious file ::rootkits/Suspicious.php +dev/ptyzx ! Suspicious file ::rootkits/Suspicious.php +dev/ptyzg ! Suspicious file ::rootkits/Suspicious.php +dev/xdf1 ! Suspicious file ::rootkits/Suspicious.php +dev/ttyop ! Suspicious file ::rootkits/Suspicious.php +dev/ttyof ! Suspicious file ::rootkits/Suspicious.php +dev/hd7 ! Suspicious file ::rootkits/Suspicious.php +dev/hdx1 ! Suspicious file ::rootkits/Suspicious.php +dev/hdx2 ! Suspicious file ::rootkits/Suspicious.php +dev/xdf2 ! Suspicious file ::rootkits/Suspicious.php +dev/ptyp ! Suspicious file ::rootkits/Suspicious.php +dev/ptyr ! Suspicious file ::rootkits/Suspicious.php +sbin/pback ! Suspicious file ::rootkits/Suspicious.php +usr/man/man3/psid ! Suspicious file ::rootkits/Suspicious.php +proc/kset ! Suspicious file ::rootkits/Suspicious.php +usr/bin/gib ! Suspicious file ::rootkits/Suspicious.php +usr/bin/snick ! Suspicious file ::rootkits/Suspicious.php +usr/bin/kfl ! Suspicious file ::rootkits/Suspicious.php +tmp/.dump ! Suspicious file ::rootkits/Suspicious.php +var/.x ! Suspicious file ::rootkits/Suspicious.php +var/.x/psotnic ! Suspicious file ::rootkits/Suspicious.php +*/.log ! Suspicious file ::rootkits/Suspicious.php +*/ecmf ! Suspicious file ::rootkits/Suspicious.php +*/mirkforce ! Suspicious file ::rootkits/Suspicious.php +*/mfclean ! Suspicious file ::rootkits/Suspicious.php + +/reptile/reptile_cmd ! Suspicious file ::reptile +/lib/udev/reptile ! Suspicious file ::reptile + +# BEURK rootkit +/lib/libselinux.so ! BEURK rootkit + +# JynxKit2 rootkit +*/jynx2.so ! JynxKit2 rootkit + +# JynxKit rootkit +*/ld_poison.so ! JynxKit rootkit diff --git a/openarmor-rules/shared/rootkit_trojans.txt b/openarmor-rules/shared/rootkit_trojans.txt new file mode 100644 index 000000000..dcc3bd785 --- /dev/null +++ b/openarmor-rules/shared/rootkit_trojans.txt @@ -0,0 +1,107 @@ +# rootkit_trojans.txt, (C) 2018 openarmor Project +# Imported from the rootcheck project. +# Some entries taken from the chkrootkit project. +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# Blank lines and lines starting with '#' are ignored. +# +# Each line must be in the following format: +# file_name !string_to_search!Description + +# Common binaries and public trojan entries +ls !bash|^/bin/sh|dev/[^clu]|\.tmp/lsfile|duarawkz|/prof|/security|file\.h! +env !bash|^/bin/sh|file\.h|proc\.h|/dev/|^/bin/.*sh! +echo !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +chown !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +chmod !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +chgrp !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +cat !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +bash !proc\.h|/dev/[0-9]|/dev/[hijkz]! +sh !proc\.h|/dev/[0-9]|/dev/[hijkz]! +uname !bash|^/bin/sh|file\.h|proc\.h|^/bin/.*sh! +date !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cln]|^/bin/.*sh! +du !w0rm|/prof|file\.h! +df !bash|^/bin/sh|file\.h|proc\.h|/dev/[^clurdv]|^/bin/.*sh! +login !elite|SucKIT|xlogin|vejeta|porcao|lets_log|sukasuk! +passwd !bash|file\.h|proc\.h|/dev/ttyo|/dev/[A-Z]|/dev/[b-s,uvxz]! +mingetty !bash|Dimensioni|pacchetto! +chfn !bash|file\.h|proc\.h|/dev/ttyo|/dev/[A-Z]|/dev/[a-s,uvxz]! +chsh !bash|file\.h|proc\.h|/dev/ttyo|/dev/[A-Z]|/dev/[a-s,uvxz]! +mail !file\.h|proc\.h|/dev/[^nu]! +su !/dev/[d-s,abuvxz]|/dev/[A-D]|/dev/[F-Z]|/dev/[0-9]|satori|vejeta|conf\.inv! +sudo !satori|vejeta|conf\.inv! +crond !/dev/[^nt]|bash! +gpm !bash|mingetty! +ifconfig !bash|^/bin/sh|/dev/tux|session.null|/dev/[^cludisopt]! +diff !bash|^/bin/sh|file\.h|proc\.h|^/bin/.*sh! +md5sum !bash|^/bin/sh|file\.h|proc\.h|/dev/|^/bin/.*sh! +hdparm !bash|/dev/ida! +ldd !/dev/[^n]|proc\.h|libshow.so|libproc.a! + +# Trojan entries for troubleshooting binaries +grep !bash|givemer! +egrep !bash|^/bin/sh|file\.h|proc\.h|/dev/|^/bin/.*sh! +find !bash|/dev/[^tnlcs]|/prof|/home/virus|file\.h! +lsof !/prof|/dev/[^apcmnfk]|proc\.h|bash|^/bin/sh|/dev/ttyo|/dev/ttyp! +netstat !bash|^/bin/sh|/dev/[^aik]|/prof|grep|addr\.h! +top !/dev/[^npi3st%]|proc\.h|/prof/! +ps !/dev/ttyo|\.1proc|proc\.h|bash|^/bin/sh! +tcpdump !bash|^/bin/sh|file\.h|proc\.h|/dev/[^bu]|^/bin/.*sh! +pidof !bash|^/bin/sh|file\.h|proc\.h|/dev/[^f]|^/bin/.*sh! +fuser !bash|^/bin/sh|file\.h|proc\.h|/dev/[a-dtz]|^/bin/.*sh! +w !uname -a|proc\.h|bash! + +# Trojan entries for common daemons +sendmail !bash|fuck! +named !bash|blah|/dev/[0-9]|^/bin/sh! +inetd !bash|^/bin/sh|file\.h|proc\.h|/dev/[^un%]|^/bin/.*sh! +apachectl !bash|^/bin/sh|file\.h|proc\.h|/dev/[^n]|^/bin/.*sh! +sshd !check_global_passwd|panasonic|satori|vejeta|\.ark|/hash\.zk|bash|/dev[a-s]|/dev[A-Z]/! +syslogd !bash|/usr/lib/pt07|/dev/[^cln]]|syslogs\.h|proc\.h! +xinetd !bash|file\.h|proc\.h! +in.telnetd !cterm100|vt350|VT100|ansi-term|bash|^/bin/sh|/dev[A-R]|/dev/[a-z]/! +in.fingerd !bash|^/bin/sh|cterm100|/dev/! +identd !bash|^/bin/sh|file\.h|proc\.h|/dev/[^n]|^/bin/.*sh! +init !bash|/dev/h +tcpd !bash|proc\.h|p1r0c4|hack|/dev/[^n]! +rlogin !p1r0c4|r00t|bash|/dev/[^nt]! + +# Kill trojan +killall !/dev/[^t%]|proc\.h|bash|tmp! +kill !/dev/[ab,d-k,m-z]|/dev/[F-Z]|/dev/[A-D]|/dev/[0-9]|proc\.h|bash|tmp! + +# Rootkit entries +/etc/rc.d/rc.sysinit !enyelkmHIDE! enye-sec Rootkit + +# ZK rootkit (http://honeyblog.org/junkyard/reports/redhat-compromise2.pdf) +/etc/sysconfig/console/load.zk !/bin/sh! ZK rootkit +/etc/sysconfig/console/load.zk !usr/bin/run! ZK rootkit + +# Modified /etc/hosts entries +# Idea taken from: +# http://blog.tenablesecurity.com/2006/12/detecting_compr.html +# http://www.sophos.com/security/analyses/trojbagledll.html +# http://www.f-secure.com/v-descs/fantibag_b.shtml +/etc/hosts !^[^#]*avp.ch!Anti-virus site on the hosts file +/etc/hosts !^[^#]*avp.ru!Anti-virus site on the hosts file +/etc/hosts !^[^#]*awaps.net! Anti-virus site on the hosts file +/etc/hosts !^[^#]*ca.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*mcafee.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*microsoft.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*f-secure.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*sophos.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*symantec.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*my-etrust.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*nai.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*networkassociates.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*viruslist.ru! Anti-virus site on the hosts file +/etc/hosts !^[^#]*kaspersky! Anti-virus site on the hosts file +/etc/hosts !^[^#]*symantecliveupdate.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*grisoft.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*clamav.net! Anti-virus site on the hosts file +/etc/hosts !^[^#]*bitdefender.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*antivirus.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*sans.org! Security site on the hosts file diff --git a/openarmor-rules/shared/system_audit_pw.txt b/openarmor-rules/shared/system_audit_pw.txt new file mode 100644 index 000000000..cc2012a6d --- /dev/null +++ b/openarmor-rules/shared/system_audit_pw.txt @@ -0,0 +1,103 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). +# +# Checks for Password Security on Linux Systems +# +#1 Set Default Algorithm for Password Encryption to SHA256 or SHA 512 +[Password Hardening - 1: Set Default Algorithm for Password Encryption to SHA256 or SHA 512] [any] [https://security.stackexchange.com/questions/77349/how-can-i-find-out-the-password-hashing-schemes-used-by-the-specific-unix-accoun, https://docs.oracle.com/cd/E26505_01/html/E27224/secsystask-42.html] +f:/etc/security/policy.conf -> !r:^# && r:^CRYPT_DEFAULT=1|^CRYPT_DEFAULT=2|^CRYPT_DEFAULT=2a|^CRYPT_DEFAULT=2x|^CRYPT_DEFAULT=2y|^CRYPT_DEFAULT=md5|^CRYPT_DEFAULT=__unix__; +f:/etc/security/policy.conf -> !r:^CRYPT_DEFAULT=\d; +f:/etc/login.defs -> !r:^# && r:^ENCRYPT_METHOD\s+MD5|^ENCRYPT_METHOD\s+DES; +f:/etc/login.defs -> !r:^ENCRYPT_METHOD\s+SHA512|^ENCRYPT_METHOD\s+SHA256; +f:/etc/pam.d/common-password -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/common-password -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +f:/etc/pam.d/password-auth -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/password-auth -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +f:/etc/pam.d/system-auth -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/system-auth -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +f:/etc/pam.d/system-auth-ac -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/system-auth-ac -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +# +# +#2 Passwords in /etc/shadow not hashed with SHA-256 or SHA-512 +[Password Hardening - 2: Not all Passwords in /etc/shadow are hashed with SHA-256 or SHA-512] [any] [https://linux-audit.com/password-security-with-linux-etc-shadow-file/, https://docs.oracle.com/cd/E19253-01/816-4557/concept-23/index.html] +f:/etc/shadow -> !r:^# && !r:^\w+:NP:\d+:\d*:\d*:\d*:\d*:\d*:\d*$ && r:^\w+:\w\.*:\d+:\d*:\d*:\d*:\d*:\d*:\d*$; +f:/etc/shadow -> !r:^# && r:\w+:\$1\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2a\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2x\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2y\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$md5\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$__unix__\$\.+; +# +# +#3 Set Password Creation Requirement Parameters +[Password Hardening - 3: Set Password Creation Requirement Parameters] [any] [https://linux-audit.com/configure-the-minimum-password-length-on-linux-systems/, https://workbench.cisecurity.org] +f:/etc/pam.d/common-password -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/common-password -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/password-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/password-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/system-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/system-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/system-auth-ac -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/system-auth-ac -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/passwd -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass|^@include\s+common-password; +f:/etc/pam.d/passwd -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+|^@include\s+common-password; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/security/pwquality.conf -> !r:^minlen=\d\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^dcredit=\p*\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^lcredit=\p*\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^ocredit=\p*\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^ucredit=\p*\d+; +# +# +#4 Set default password expiration / aging parameters +[Password Hardening - 4: Set password expiration / aging parameters] [any] [https://www.thegeekdiary.com/understanding-etclogin-defs-file, https://workbench.cisecurity.org/sections/26024/recommendations/63001] +f:/etc/default/passwd -> !r:^MAXWEEKS=\d\d$; +f:/etc/default/passwd -> !r:^MINWEEKS=\d; +f:/etc/default/passwd -> !r:^WARNWEEKS=\d; +f:/etc/login.defs -> !r:^PASS_MAX_DAYS\s*\t*\d\d$; +f:/etc/login.defs -> !r:^PASS_MIN_DAYS\s*\t*\d; +f:/etc/login.defs -> !r:^PASS_WARN_AGE\s*\t*\d; diff --git a/openarmor-rules/shared/system_audit_rcl.txt b/openarmor-rules/shared/system_audit_rcl.txt new file mode 100644 index 000000000..2a1be7138 --- /dev/null +++ b/openarmor-rules/shared/system_audit_rcl.txt @@ -0,0 +1,95 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +$php.ini=/etc/php.ini,/var/www/conf/php.ini,/etc/php5/apache2/php.ini,/usr/local/etc/php.ini; +$web_dirs=/var/www,/var/htdocs,/home/httpd,/usr/local/apache,/usr/local/apache2,/usr/local/www; + +# PHP checks +[PHP - Register globals are enabled] [any] [] +f:$php.ini -> r:^register_globals = On; + +# PHP checks +[PHP - Expose PHP is enabled] [any] [] +f:$php.ini -> r:^expose_php = On; + +# PHP checks +[PHP - Allow URL fopen is enabled] [any] [] +f:$php.ini -> r:^allow_url_fopen = On; + +# PHP checks +[PHP - Displaying of errors is enabled] [any] [] +f:$php.ini -> r:^display_errors = On; + +# PHP checks - consider open_basedir && disable_functions + + +## Looking for common web exploits (might indicate that you are owned). +## Using http://dcid.me/blog/logsamples/webattacks_links as a reference. +#[Web exploits - Possible compromise] [any] [] +#d:$web_dirs -> .txt$ -> r:^ ^.yop$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^id$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^.ssh$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^...$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^.shell$; + +## Looking for outdated Web applications +## Taken from http://sucuri.net/latest-versions +[Web vulnerability - Outdated WordPress installation {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://sucuri.net/latest-versions] +d:$web_dirs -> ^version.php$ -> r:^\.wp_version && >:$wp_version = '4.4.2'; + +[Web vulnerability - Outdated Joomla installation {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://sucuri.net/latest-versions] +d:$web_dirs -> ^version.php$ -> r:var \.RELEASE && r:'3.4.8'; + +[Web vulnerability - Outdated osCommerce (v2.2) installation {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://sucuri.net/latest-versions] +d:$web_dirs -> ^application_top.php$ -> r:'osCommerce 2.2-; + +## Looking for known backdoors +[Web vulnerability - Backdoors / Web based malware found - eval(base64_decode {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> .php$ -> r:eval\(base64_decode\(\paWYo; + +[Web vulnerability - Backdoors / Web based malware found - eval(base64_decode(POST {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> .php$ -> r:eval\(base64_decode\(\S_POST; + +[Web vulnerability - .htaccess file compromised {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://blog.sucuri.net/2011/05/understanding-htaccess-attacks-part-1.html] +d:$web_dirs -> ^.htaccess$ -> r:RewriteCond \S+HTTP_REFERERS \S+google; + +[Web vulnerability - .htaccess file compromised - auto append {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://blog.sucuri.net/2011/05/understanding-htaccess-attacks-part-1.html] +d:$web_dirs -> ^.htaccess$ -> r:php_value auto_append_file; diff --git a/openarmor-rules/shared/system_audit_ssh.txt b/openarmor-rules/shared/system_audit_ssh.txt new file mode 100644 index 000000000..8edfa91d6 --- /dev/null +++ b/openarmor-rules/shared/system_audit_ssh.txt @@ -0,0 +1,81 @@ +# SSH Rootcheck +# +# v1.0 2016/01/20 +# Created by Wazuh, Inc. . +# jesus@wazuh.com +# This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2 +# + + +$sshd_file=/etc/ssh/sshd_config; + + +# Listen PORT != 22 +# The option Port specifies on which port number ssh daemon listens for incoming connections. +# Changing the default port you may reduce the number of successful attacks from zombie bots, an attacker or bot doing port-scanning can quickly identify your SSH port. +[SSH Hardening - 1: Port 22 {PCI_DSS: 2.2.4}] [any] [1] +f:$sshd_file -> !r:^# && r:Port\.+22; + + +# Protocol 2 +# The Protocol parameter dictates which version of the SSH communication and encryption protocols are in use. +# Version 1 of the SSH protocol has weaknesses. +[SSH Hardening - 2: Protocol 1 {PCI_DSS: 2.2.4}] [any] [2] +f:$sshd_file -> !r:^# && r:Protocol\.+1; + + +# PermitRootLogin no +# The option PermitRootLogin specifies whether root can log in using ssh. +# If you want log in as root, you should use the option "Match" and restrict it to a few IP addresses. +[SSH Hardening - 3: Root can log in] [any] [3] +f:$sshd_file -> !r:^# && r:PermitRootLogin\.+yes; +f:$sshd_file -> r:^#\s*PermitRootLogin; + + +# PubkeyAuthentication yes +# Access only by public key +# Generally people will use weak passwords and have poor password practices. Keys are considered stronger than password. +[SSH Hardening - 4: No Public Key autentication {PCI_DSS: 2.2.4}] [any] [4] +f:$sshd_file -> !r:^# && r:PubkeyAuthentication\.+no; +f:$sshd_file -> r:^#\s*PubkeyAuthentication; + + +# PasswordAuthentication no +# The option PasswordAuthentication specifies whether we should use password-based authentication. +# Use public key authentication instead of passwords +[SSH Hardening - 5: Password Authentication {PCI_DSS: 2.2.4}] [any] [5] +f:$sshd_file -> !r:^# && r:PasswordAuthentication\.+yes; +f:$sshd_file -> r:^#\s*PasswordAuthentication; + + +# PermitEmptyPasswords no +# The option PermitEmptyPasswords specifies whether the server allows logging in to accounts with a null password +# Accounts with null passwords are a bad practice. +[SSH Hardening - 6: Empty passwords allowed {PCI_DSS: 2.2.4}] [any] [6] +f:$sshd_file -> !r:^# && r:PermitEmptyPasswords\.+yes; +f:$sshd_file -> r:^#\s*PermitEmptyPasswords; + + +# IgnoreRhosts yes +# The option IgnoreRhosts specifies whether rhosts or shosts files should not be used in authentication. +# For security reasons it is recommended to no use rhosts or shosts files for authentication. +[SSH Hardening - 7: Rhost or shost used for authentication {PCI_DSS: 2.2.4}] [any] [7] +f:$sshd_file -> !r:^# && r:IgnoreRhosts\.+no; +f:$sshd_file -> r:^#\s*IgnoreRhosts; + + +# LoginGraceTime 30 +# The option LoginGraceTime specifies how long in seconds after a connection request the server will wait before disconnecting if the user has not successfully logged in. +# 30 seconds is the recommended time for avoiding open connections without authenticate +[SSH Hardening - 8: Wrong Grace Time {PCI_DSS: 2.2.4}] [any] [8] +f:$sshd_file -> !r:^# && r:LoginGraceTime && !r:30\s*$; +f:$sshd_file -> r:^#\s*LoginGraceTime; + + +# MaxAuthTries 3 +# The MaxAuthTries parameter specifices the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged. +# This should be set to 3. +[SSH Hardening - 9: Wrong Maximum number of authentication attempts {PCI_DSS: 2.2.4}] [any] [9] +f:$sshd_file -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:$sshd_file -> r:^#\s*MaxAuthTries; +f:$sshd_file -> !r:MaxAuthTries; diff --git a/openarmor-rules/shared/win_applications_rcl.txt b/openarmor-rules/shared/win_applications_rcl.txt new file mode 100644 index 000000000..ab61dceb4 --- /dev/null +++ b/openarmor-rules/shared/win_applications_rcl.txt @@ -0,0 +1,126 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +[Chat/IM/VoIP - Skype {PCI_DSS: 10.6.1}] [any] [] +f:\Program Files\Skype\Phone; +f:\Documents and Settings\All Users\Documents\My Skype Pictures; +f:\Documents and Settings\Skype; +f:\Documents and Settings\All Users\Start Menu\Programs\Skype; +r:HKLM\SOFTWARE\Skype; +r:HKEY_LOCAL_MACHINE\Software\Policies\Skype; +p:r:Skype.exe; + +[Chat/IM - Yahoo {PCI_DSS: 10.6.1}] [any] [] +f:\Documents and Settings\All Users\Start Menu\Programs\Yahoo! Messenger; +r:HKLM\SOFTWARE\Yahoo; + +[Chat/IM - ICQ {PCI_DSS: 10.6.1}] [any] [] +r:HKEY_CURRENT_USER\Software\Mirabilis\ICQ; + +[Chat/IM - AOL {PCI_DSS: 10.6.1}] [any] [http://www.aol.com] +r:HKEY_LOCAL_MACHINE\SOFTWARE\America Online\AOL Instant Messenger; +r:HKEY_CLASSES_ROOT\aim\shell\open\command; +r:HKEY_CLASSES_ROOT\AIM.Protocol; +r:HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/x-aim; +f:\Program Files\AIM95; +p:r:aim.exe; + +[Chat/IM - MSN {PCI_DSS: 10.6.1}] [any] [http://www.msn.com] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSNMessenger; +r:HKEY_CURRENT_USER\SOFTWARE\Microsoft\MSNMessenger; +f:\Program Files\MSN Messenger; +f:\Program Files\Messenger; +p:r:msnmsgr.exe; + +[Chat/IM - ICQ {PCI_DSS: 10.6.1}] [any] [http://www.icq.com] +r:HKLM\SOFTWARE\Mirabilis\ICQ; + +[P2P - UTorrent {PCI_DSS: 10.6.1}] [any] [] +p:r:utorrent.exe; + +[P2P - LimeWire {PCI_DSS: 11.4}] [any] [] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Limewire; +r:HKLM\software\microsoft\windows\currentversion\run -> limeshop; +f:\Program Files\limewire; +f:\Program Files\limeshop; + +[P2P/Adware - Kazaa {PCI_DSS: 11.4}] [any] [] +f:\Program Files\kazaa; +f:\Documents and Settings\All Users\Start Menu\Programs\kazaa; +f:\Documents and Settings\All Users\DESKTOP\Kazaa Media Desktop.lnk; +f:\Documents and Settings\All Users\DESKTOP\Kazaa Promotions.lnk; +f:%WINDIR%\System32\Cd_clint.dll; +r:HKEY_LOCAL_MACHINE\SOFTWARE\KAZAA; +r:HKEY_CURRENT_USER\SOFTWARE\KAZAA; +r:HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN\KAZAA; + +# http://vil.nai.com/vil/content/v_135023.htm +[Adware - RxToolBar {PCI_DSS: 11.4}] [any] [http://vil.nai.com/vil/content/v_135023.htm] +r:HKEY_CURRENT_USER\Software\Infotechnics; +r:HKEY_CURRENT_USER\Software\Infotechnics\RX Toolbar; +r:HKEY_CURRENT_USER\Software\RX Toolbar; +r:HKEY_CLASSES_ROOT\BarInfoUrl.TBInfo; +r:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RX Toolbar; +f:\Program Files\RXToolBar; + +# http://btfaq.com/serve/cache/18.html +[P2P - BitTorrent {PCI_DSS: 10.6.1}] [any] [http://btfaq.com/serve/cache/18.html] +f:\Program Files\BitTorrent; +r:HKEY_CLASSES_ROOT\.torrent; +r:HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/x-bittorrent; +r:HKEY_CLASSES_ROOT\bittorrent; +r:HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\BitTorrent; + +# http://www.gotomypc.com +[Remote Access - GoToMyPC {PCI_DSS: 10.6.1}] [any] [] +f:\Program Files\Citrix\GoToMyPC; +f:\Program Files\Citrix\GoToMyPC\g2svc.exe; +f:\Program Files\Citrix\GoToMyPC\g2comm.exe; +f:\Program Files\expertcity\GoToMyPC; +r:HKLM\software\microsoft\windows\currentversion\run -> gotomypc; +r:HKEY_LOCAL_MACHINE\software\citrix\gotomypc; +r:HKEY_LOCAL_MACHINE\system\currentcontrolset\services\gotomypc; +p:r:g2svc.exe; +p:r:g2pre.exe; + +[Spyware - Twain Tec Spyware {PCI_DSS: 11.4}] [any] [] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TwaintecDll.TwaintecDllObj.1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\twaintech; +f:%WINDIR%\twaintec.dll; + +# http://www.symantec.com/security_response/writeup.jsp?docid=2004-062611-4548-99&tabid=2 +[Spyware - SpyBuddy {PCI_DSS: 11.4}] [any] [] +f:\Program Files\ExploreAnywhere\SpyBuddy\sb32mon.exe; +f:\Program Files\ExploreAnywhere\SpyBuddy; +f:\Program Files\ExploreAnywhere; +f:%WINDIR%\System32\sysicept.dll; +r:HKEY_LOCAL_MACHINE\Software\ExploreAnywhere Software\SpyBuddy; + +[Spyware - InternetOptimizer {PCI_DSS: 11.4}] [any] [] +r:HKLM\SOFTWARE\Avenue Media; +r:HKEY_CLASSES_ROOT\\safesurfinghelper.iebho.1; +r:HKEY_CLASSES_ROOT\\safesurfinghelper.iebho; diff --git a/openarmor-rules/shared/win_audit_rcl.txt b/openarmor-rules/shared/win_audit_rcl.txt new file mode 100644 index 000000000..e39ed7ea4 --- /dev/null +++ b/openarmor-rules/shared/win_audit_rcl.txt @@ -0,0 +1,74 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# http://technet2.microsoft.com/windowsserver/en/library/486896ba-dfa1-4850-9875-13764f749bba1033.mspx?mfr=true +[Disabled Registry tools set {PCI_DSS: 10.6.1}] [any] [] +r:HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableRegistryTools -> 1; +r:HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableRegistryTools -> 1; + +# http://support.microsoft.com/kb/825750 +[DCOM disabled {PCI_DSS: 10.6.1}] [any] [] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\OLE -> EnableDCOM -> N; + +# http://web.mit.edu/is/topics/windows/server/winmitedu/security.html +[LM authentication allowed (weak passwords) {PCI_DSS: 10.6.1, 11.4}] [any] [] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA -> LMCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA -> LMCompatibilityLevel -> 1; + +# http://research.eeye.com/html/alerts/AL20060813.html +# Disabled by some Malwares (sometimes by McAfee and Symantec +# security center too). +[Firewall/Anti Virus notification disabled {PCI_DSS: 10.6.1}] [any] [] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> FirewallDisableNotify -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> antivirusoverride -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> firewalldisablenotify -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> firewalldisableoverride -> !0; + +# Checking for the microsoft firewall. +[Microsoft Firewall disabled {PCI_DSS: 10.6.1, 1.4}] [all] [] +r:HKEY_LOCAL_MACHINE\software\policies\microsoft\windowsfirewall\domainprofile -> enablefirewall -> 0; +r:HKEY_LOCAL_MACHINE\software\policies\microsoft\windowsfirewall\standardprofile -> enablefirewall -> 0; + +#http://web.mit.edu/is/topics/windows/server/winmitedu/security.html +[Null sessions allowed {PCI_DSS: 11.4}] [any] [] +r:HKLM\System\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> 0; + +[Error reporting disabled {PCI_DSS: 10.6.1}] [any] [http://windowsir.blogspot.com/2007/04/something-new-to-look-for.html] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> DoReport -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeKernelFaults -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeMicrosoftApps -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeWindowsApps -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeShutdownErrs -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> ShowUI -> 0; + +# http://support.microsoft.com/default.aspx?scid=315231 +[Automatic Logon enabled {PCI_DSS: 10.6.1}] [any] [http://support.microsoft.com/default.aspx?scid=315231] +r:HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon -> DefaultPassword; +r:HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AutoAdminLogon -> 1; + +[Winpcap packet filter driver found {PCI_DSS: 10.6.1}] [any] [] +f:%WINDIR%\System32\drivers\npf.sys; diff --git a/openarmor-rules/shared/win_malware_rcl.txt b/openarmor-rules/shared/win_malware_rcl.txt new file mode 100644 index 000000000..cab4ef0d8 --- /dev/null +++ b/openarmor-rules/shared/win_malware_rcl.txt @@ -0,0 +1,122 @@ +# openarmor Windows Malware list - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Malware name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# # Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# http://www.iss.net/threats/ginwui.html +[Ginwui Backdoor {PCI_DSS: 11.4}] [any] [http://www.iss.net/threats/ginwui.html] +f:%WINDIR%\System32\zsyhide.dll; +f:%WINDIR%\System32\zsydll.dll; +r:HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\zsydll; +r:HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows -> AppInit_DLLs -> r:zsyhide.dll; + +# http://www.symantec.com/security_response/writeup.jsp?docid=2006-081312-3302-99&tabid=2 +[Wargbot Backdoor {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\wgareg.exe; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\wgareg; + +# http://www.f-prot.com/virusinfo/descriptions/sober_j.html +[Sober Worm {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\nonzipsr.noz; +f:%WINDIR%\System32\clonzips.ssc; +f:%WINDIR%\System32\clsobern.isc; +f:%WINDIR%\System32\sb2run.dii; +f:%WINDIR%\System32\winsend32.dal; +f:%WINDIR%\System32\winroot64.dal; +f:%WINDIR%\System32\zippedsr.piz; +f:%WINDIR%\System32\winexerun.dal; +f:%WINDIR%\System32\winmprot.dal; +f:%WINDIR%\System32\dgssxy.yoi; +f:%WINDIR%\System32\cvqaikxt.apk; +f:%WINDIR%\System32\sysmms32.lla; +f:%WINDIR%\System32\Odin-Anon.Ger; + +# http://www.symantec.com/security_response/writeup.jsp?docid=2005-042611-0148-99&tabid=2 +[Hotword Trojan {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\_; +f:%WINDIR%\System32\explore.exe; +f:%WINDIR%\System32\ svchost.exe; +f:%WINDIR%\System32\mmsystem.dlx; +f:%WINDIR%\System32\WINDLL-ObjectsWin*.DLX; +f:%WINDIR%\System32\CFXP.DRV; +f:%WINDIR%\System32\CHJO.DRV; +f:%WINDIR%\System32\MMSYSTEM.DLX; +f:%WINDIR%\System32\OLECLI.DL; + +[Beagle worm {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\winxp.exe; +f:%WINDIR%\System32\winxp.exeopen; +f:%WINDIR%\System32\winxp.exeopenopen; +f:%WINDIR%\System32\winxp.exeopenopenopen; +f:%WINDIR%\System32\winxp.exeopenopenopenopen; + +# http://symantec.com/security_response/writeup.jsp?docid=2007-071711-3132-99 +[Gpcoder Trojan {PCI_DSS: 11.4}] [any] [http://symantec.com/security_response/writeup.jsp?docid=2007-071711-3132-99] +f:%WINDIR%\System32\ntos.exe; +f:%WINDIR%\System32\wsnpoem; +f:%WINDIR%\System32\wsnpoem\audio.dll; +f:%WINDIR%\System32\wsnpoem\video.dll; +r:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run -> userinit -> r:ntos.exe; + +# [http://www.symantec.com/security_response/writeup.jsp?docid=2006-112813-0222-99&tabid=2 +[Looked.BK Worm {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\uninstall\rundl132.exe; +f:%WINDIR%\Logo1_.exe; +f:%Windir%\RichDll.dll; +r:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run -> load -> r:rundl132.exe; + +[Possible Malware - Svchost running outside system32 {PCI_DSS: 11.4}] [all] [] +p:r:svchost.exe && !%WINDIR%\System32\svchost.exe; +f:!%WINDIR%\SysWOW64; + +[Possible Malware - Inetinfo running outside system32\inetsrv {PCI_DSS: 11.4}] [all] [] +p:r:inetinfo.exe && !%WINDIR%\System32\inetsrv\inetinfo.exe; +f:!%WINDIR%\SysWOW64; + +[Possible Malware - Rbot/Sdbot detected {PCI_DSS: 11.4}] [any] [] +f:%Windir%\System32\rdriv.sys; +f:%Windir%\lsass.exe; + +[Possible Malware File {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\utorrent.exe; +f:%WINDIR%\System32\utorrent.exe; +f:%WINDIR%\System32\Files32.vxd; + +# Modified /etc/hosts entries +# Idea taken from: +# http://blog.tenablesecurity.com/2006/12/detecting_compr.html +# http://www.sophos.com/security/analyses/trojbagledll.html +# http://www.f-secure.com/v-descs/fantibag_b.shtml +[Anti-virus site on the hosts file] [any] [] +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:avp.ch|avp.ru|nai.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:awaps.net|ca.com|mcafee.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:microsoft.com|f-secure.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:sophos.com|symantec.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:my-etrust.com|viruslist.ru; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:networkassociates.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:kaspersky|grisoft.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:symantecliveupdate.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:clamav.net|bitdefender.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:antivirus.com|sans.org; diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 000000000..18a3bd010 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,1455 @@ + +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +EXTERNAL_JSON=external/cJSON/ +EXTERNAL_LUA=external/lua-5.2.3/ +EXTERNAL_ZLIB=external/zlib-1.2.11/ +EXTERNAL_PCRE2=external/pcre2-10.32/ +ZLIB_SYSTEM?=yes +PCRE2_SYSTEM?=yes +LUA_PLAT=posix +LUA_ENABLE?=no +MAXAGENTS?=2048 +REUSE_ID?=no +# XXX Becareful NO EXTRA Spaces here +PREFIX?=/var/openarmor +PG_CONFIG?=pg_config +MY_CONFIG?=mysql_config +PRELUDE_CONFIG?=libprelude-config +openarmor_GROUP?=openarmor +openarmor_USER?=openarmor +openarmor_USER_MAIL?=openarmorm +openarmor_USER_REM?=openarmorr + +INSTALL_LOCALTIME?=yes +INSTALL_RESOLVCONF?=yes + +USE_PRELUDE?=no +USE_ZEROMQ?=no +USE_GEOIP?=no +USE_INOTIFY=no +USE_PCRE2_JIT=yes +USE_SYSTEMD?=yes + +ifneq (${TARGET},winagent) + USE_OPENSSL?=auto +else + USE_OPENSSL?=no +endif + +ONEWAY?=no +CLEANFULL?=no + +export MYLDFLAGS= "${LDFLAGS}" +export MYCFLAGS= "${CFLAGS}" + +DEFINES=-DMAX_AGENTS=${MAXAGENTS} -DopenarmorHIDS +DEFINES+=-DDEFAULTDIR=\"${PREFIX}\" +DEFINES+=-DUSER=\"${openarmor_USER}\" +DEFINES+=-DREMUSER=\"${openarmor_USER_REM}\" +DEFINES+=-DGROUPGLOBAL=\"${openarmor_GROUP}\" +DEFINES+=-DMAILUSER=\"${openarmor_USER_MAIL}\" +DEFINES+=-D${uname_S} + +# Uncomment the DEFINES statement below if you are +# running Linux and want to use AF_UNSPEC instead of +# AF_INET6 to fully support IPv4 addresses. +#DEFINES+=-DNOV4MAP + +ifneq (,$(filter ${REUSE_ID},yes y Y 1)) + DEFINES+=-DREUSE_ID +endif + +openarmor_LDFLAGS=${LDFLAGS} -lm + +ifneq (${TARGET},winagent) +ifeq (${uname_S},Linux) + DEFINES+=-DINOTIFY_ENABLED + openarmor_LDFLAGS+=-lpthread +ifeq (${USE_SYSTEMD},yes) + DEFINES+=-DHAVE_SYSTEMD + openarmor_LDFLAGS+=-lsystemd +endif +# DEFINES+=-DUSE_MAGIC +# openarmor_LDFLAGS+=-lmagic +else +ifeq (${uname_S},AIX) + DEFINES+=-DAIX + DEFINES+=-DHIGHFIRST + CFLAGS+=-I./external/compat/aix + openarmor_LDFLAGS+=-lpthread + PATH:=${PATH}:/usr/vac/bin +else +ifeq (${uname_S},SunOS) + DEFINES+=-DSOLARIS + DEFINES+=-DHIGHFIRST + openarmor_LDFLAGS+=-lsocket -lnsl -lresolv + LUA_PLAT=solaris + PATH:=${PATH}:/usr/ccs/bin:/usr/xpg4/bin:/opt/csw/gcc3/bin:/opt/csw/bin:/usr/sfw/bin + +else +ifeq (${uname_S},Darwin) + DEFINES+=-DDarwin + DEFINES+=-DHIGHFIRST + LUA_PLAT=macosx + +else +ifeq (${uname_S},FreeBSD) + DEFINES+=-DFreeBSD + openarmor_LDFLAGS+=-pthread + LUA_PLAT=freebsd + CFLAGS+=-I/usr/local/include + openarmor_LDFLAGS+=-L/usr/local/lib +else +ifeq (${uname_S},NetBSD) + DEFINES+=-DNetBSD + openarmor_LDFLAGS+=-pthread + LUA_PLAT=posix + CFLAGS+=-I/usr/local/include + openarmor_LDFLAGS+=-L/usr/local/lib + USE_PCRE2_JIT=n +else +ifeq (${uname_S},OpenBSD) +# DEFINES+=-DOpenBSD + DEFINES+=-pthread + DNS_CFLAGS+=-lutil + LUA_PLAT=posix + CFLAGS+=-I/usr/local/include + openarmor_LDFLAGS+=-L/usr/local/lib + USE_PCRE2_JIT=n +else +ifeq (${uname_S},HP-UX) + DEFINES+=-DHPUX + DEFINES+=-D_XOPEN_SOURCE_EXTENDED + DEFINES+=-DHIGHFIRST + DEFINES+=-D_REENTRANT +else + $(warning Unknown platform) +endif # HPUX +endif # OpenBSD +endif # NetBSD +endif # FreeBSD +endif # Darwin +endif # SunOS +endif # AIX +endif # Linux +endif # winagent + +## OpenBSD doesn't need the imsg stuff. +ifneq (${uname_S},OpenBSD) + CFLAGS+=-I./external/compat + COMPAT_FILES+=./external/compat/imsg.c ./external/compat/imsg-buffer.c +endif + +ifeq (${uname_S},AIX) + INSTALL_CMD?=./install-shim-aix.ksh -m $(1) -o $(2) -g $(3) +else + INSTALL_CMD?=install -m $(1) -o $(2) -g $(3) +endif + +ifdef DEBUGAD + DEFINES+=-DDEBUGAD +endif + +openarmor_CFLAGS=${CFLAGS} +#ANALYSISD_FLAGS="-lsqlite3" + +ifdef DEBUG + openarmor_CFLAGS+=-g +endif #DEBUG + +ifneq (,$(filter ${CLEANFULL},yes y Y 1)) + DEFINES+=-DCLEANFULL +endif + +ifneq (,$(filter ${ONEWAY},yes y Y 1)) + DEFINES+=-DONEWAY_ENABLED +endif + +ifneq (${ZLIB_SYSTEM},no) + DEFINES+=-DZLIB_SYSTEM +endif + +ifeq (${TARGET}, winagent) + PCRE2_SYSTEM=no +endif + +ifeq (${PCRE2_SYSTEM},no) + PCRE2_INCLUDE=-I./${EXTERNAL_PCRE2}/install/include/ + DEFINES+=${PCRE2_INCLUDE} + DEFINES+=-DPCRE2_STATIC +else + PCRE2_LOCATION?=$(shell pcre2-config --prefix)/lib + openarmor_LDFLAGS+=-lpcre2-8 +endif + + +openarmor_CFLAGS+=${DEFINES} +openarmor_CFLAGS+=-Wall -Wextra +openarmor_CFLAGS+=-I./ -I./headers/ + +CCCOLOR="\033[34m" +LINKCOLOR="\033[34;1m" +SRCCOLOR="\033[33m" +BINCOLOR="\033[37;1m" +MAKECOLOR="\033[32;1m" +ENDCOLOR="\033[0m" + +MING_BASE:= +ifeq (${TARGET}, winagent) +CC=gcc +ZLIB_SYSTEM=no +PCRE2_SYSTEM=no +ifneq (,$(shell which amd64-mingw32msvc-gcc)) + MING_BASE:=amd64-mingw32msvc- +else +ifneq (,$(shell which i686-pc-mingw32-gcc)) + MING_BASE:=i686-pc-mingw32- +else +ifneq (,$(shell which i686-w64-mingw32-gcc)) + MING_BASE:=i686-w64-mingw32- +else +$(error No windows cross-compiler found!) #MING_BASE:=unknown- +endif +endif +endif +endif #winagent + + +openarmor_CC =${QUIET_CC}${MING_BASE}${CC} +openarmor_CCBIN =${QUIET_CCBIN}${MING_BASE}${CC} +openarmor_LINK =${QUIET_LINK}${MING_BASE}ar ${AR_FLAGS} -crs +openarmor_RANLIB =${QUIET_RANLIB}${MING_BASE}ranlib +openarmor_WINDRES =${QUIET_CCBIN}${MING_BASE}windres + + +ifneq (,$(filter ${USE_PCRE2_JIT},yes y Y 1)) + DEFINES+=-DUSE_PCRE2_JIT + PCRE2_CONFIGURE_JIT=--enable-jit +else + PCRE2_CONFIGURE_JIT=--disable-jit +endif + +ifneq (,$(filter ${USE_INOTIFY},auto yes y Y 1)) + DEFINES+=-DINOTIFY_ENABLED + ifeq (${uname_S},FreeBSD) + openarmor_LDFLAGS+=-linotify -L/usr/local/lib -I/usr/local/include + openarmor_CFLAGS+=-I/usr/local/include + endif +endif + +ifneq (,$(filter ${USE_PRELUDE},auto yes y Y 1)) + DEFINES+=-DPRELUDE_OUTPUT_ENABLED + openarmor_LDFLAGS+=-lprelude + openarmor_LDFLAGS+=$(shell sh -c '${PRELUDE_CONFIG} --pthread-cflags') + openarmor_LDFLAGS+=$(shell sh -c '${PRELUDE_CONFIG} --libs') +endif # USE_PRELUDE + +ifneq (,$(filter ${USE_ZEROMQ},auto yes y Y 1)) + DEFINES+=-DZEROMQ_OUTPUT_ENABLED + #LDFLAGS+=-L/usr/local/lib -I/usr/local/include -lzmq -lczmq + openarmor_LDFLAGS+=-lzmq -lczmq -lm +endif # USE_ZEROMQ + +ifneq (,$(filter ${USE_GEOIP},auto yes y Y 1)) + DEFINES+=-DLIBGEOIP_ENABLED + openarmor_LDFLAGS+=-lGeoIP +endif # USE_GEOIP + +ifneq (,$(filter ${USE_SQLITE},auto yes y Y 1)) + DEFINES+=-DSQLITE_ENABLED + ANALYSISD_FLAGS="-lsqlite3" +endif # USE_SQLITE + +MI := +PI := +ifdef DATABASE + + ifeq (${DATABASE},mysql) + DEFINES+=-DMYSQL_DATABASE_ENABLED + + ifdef MYSQL_CFLAGS + MI = ${MYSQL_CFLAGS} + else + MI := $(shell sh -c '${MY_CONFIG} --include 2>/dev/null || echo ') + + ifeq (${MI},) # BEGIN MI manual detection + ifneq (,$(wildcard /usr/include/mysql/mysql.h)) + MI="-I/usr/include/mysql/" + else + ifneq (,$(wildcard /usr/local/include/mysql/mysql.h)) + MI="-I/usr/local/include/mysql/" + endif # + endif #MI + + endif + endif # MYSQL_CFLAGS + + ifdef MYSQL_LIBS + ML = ${MYSQL_LIBS} + else + ML := $(shell sh -c '${MY_CONFIG} --libs 2>/dev/null || echo ') + + ifeq (${ML},) + ifneq (,$(wildcard /usr/lib/mysql/*)) + ML="-L/usr/lib/mysql -lmysqlclient" + else + ifneq (,$(wildcard /usr/lib64/mysql/*)) + ML="-L/usr/lib64/mysql -lmysqlclient" + else + ifneq (,$(wildcard /usr/local/lib/mysql/*)) + ML="-L/usr/local/lib/mysql -lmysqlclient" + else + ifneq (,$(wildcard /usr/local/lib64/mysql/*)) + ML="-L/usr/local/lib64/mysql -lmysqlclient" + endif # local/lib64 + endif # local/lib + endif # lib54 + endif # lib + endif + endif # MYSQL_LIBS + + openarmor_LDFLAGS+=${ML} + + else # DATABASE + + ifeq (${DATABASE}, pgsql) + DEFINES+=-DPGSQL_DATABASE_ENABLED + + ifneq (${PGSQL_LIBS},) + PL:=${PGSQL_LIBS} + else + PL:=$(shell sh -c '(${PG_CONFIG} --libdir --pkglibdir 2>/dev/null | sed "s/^/-L/g" | xargs ) || echo ') + endif + + ifneq (${PGSQL_CFLAGS},) + PI:=${PGSQL_CFLAGS} + else + PI:=$(shell sh -c '(${PG_CONFIG} --includedir --pkgincludedir 2>/dev/null | sed "s/^/-I/g" | xargs ) || echo ') + endif + + # XXX need some basic autodetech stuff here. + + openarmor_LDFLAGS+=${PL} + openarmor_LDFLAGS+=-lpq + + endif # pgsql + endif # mysql +endif # DATABASE + + +# openssl ########### +ifeq (${USE_OPENSSL},auto) + ifneq (,$(wildcard /usr/include/openssl/ssl.h)) + DEFINES+=-DLIBOPENSSL_ENABLED + openarmor_LDFLAGS+=-lssl -lcrypto + else + ifneq (,$(wildcard /usr/local/include/openssl/ssl.h)) + DEFINES+=-DLIBOPENSSL_ENABLED + openarmor_LDFLAGS+=-lssl -lcrypto + endif + endif +endif # USE_OPENSSL + +ifneq (,$(filter ${USE_OPENSSL},yes y Y 1)) + DEFINES+=-DLIBOPENSSL_ENABLED + ifeq (${OPENSSL_LIBS},) + openarmor_LDFLAGS+=-lssl -lcrypto + else + openarmor_LDFLAGS+=${OPENSSL_LIBS} + endif + + ifneq (${OPENSSL_CFLAGS},) + openarmor_CFLAGS+=${OPENSSL_CFLAGS} + endif +endif + +#################### +#### Target ######## +#################### + +openarmor_CONTROL_SRC=./init/openarmor-server.sh +openarmor_CONF_SRC=../etc/openarmor-server.conf + +ifndef TARGET + TARGET=failtarget +endif # TARGET + +ifeq (${TARGET},agent) + DEFINES+=-DCLIENT + openarmor_CONTROL_SRC=./init/openarmor-client.sh + openarmor_CONF_SRC=../etc/openarmor-agent.conf +endif + +ifeq (${TARGET},local) + DEFINES+=-DLOCAL + openarmor_CONTROL_SRC=./init/openarmor-local.sh + openarmor_CONF_SRC=../etc/openarmor-local.conf +endif + + +.PHONY: build +build: ${TARGET} +ifneq (${TARGET},failtarget) + ${MAKE} settings + @echo + ${QUIET_NOTICE} + @echo "Done building ${TARGET}" + ${QUIET_ENDCOLOR} +endif + @echo + + +.PHONY: install install-agent install-server install-local install-hybrid +install: install-${TARGET} + +install-agent: install-common + $(call INSTALL_CMD,0550,root,0) openarmor-agentd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) agent-auth ${PREFIX}/bin + + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/rids + +install-local: install-server-generic + +install-hybrid: install-server-generic + +install-server: install-server-generic + +install-common: build + ./init/adduser.sh ${openarmor_USER} ${openarmor_USER_MAIL} ${openarmor_USER_REM} ${openarmor_GROUP} ${PREFIX} + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/ + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/logs + $(call INSTALL_CMD,0660,${openarmor_USER},${openarmor_GROUP}) /dev/null ${PREFIX}/logs/openarmor.log + + $(call INSTALL_CMD,0550,root,0) -d ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-logcollector ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-syscheckd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-execd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) manage_agents ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) ../contrib/util.sh ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) ${openarmor_CONTROL_SRC} ${PREFIX}/bin/openarmor-control + +ifeq (${LUA_ENABLE},yes) + $(call INSTALL_CMD,0550,root,0) -d ${PREFIX}/lua + $(call INSTALL_CMD,0550,root,0) -d ${PREFIX}/lua/native + $(call INSTALL_CMD,0550,root,0) -d ${PREFIX}/lua/compiled + $(call INSTALL_CMD,0550,root,0) ${EXTERNAL_LUA}src/openarmor-lua ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) ${EXTERNAL_LUA}src/openarmor-luac ${PREFIX}/bin/ +endif + + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/queue + $(call INSTALL_CMD,0770,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/alerts + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/openarmor + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/syscheck + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/diff + + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/etc +ifeq (${INSTALL_LOCALTIME},yes) + $(call INSTALL_CMD,0440,root,${openarmor_GROUP}) /etc/localtime ${PREFIX}/etc +endif +ifeq (${INSTALL_RESOLVCONF},yes) + $(call INSTALL_CMD,0440,root,${openarmor_GROUP}) /etc/resolv.conf ${PREFIX}/etc +endif + + $(call INSTALL_CMD,1550,root,${openarmor_GROUP}) -d ${PREFIX}/tmp + +ifneq (,$(wildcard /etc/TIMEZONE)) + $(call INSTALL_CMD,440,root,${openarmor_GROUP}) /etc/TIMEZONE ${PREFIX}/etc/ +endif +# Solaris Needs some extra files +ifeq (${uname_S},SunOS) + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/usr/share/lib/zoneinfo/ + cp -r /usr/share/lib/zoneinfo/* ${PREFIX}/usr/share/lib/zoneinfo/ +endif + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) -b ../etc/internal_options.conf ${PREFIX}/etc/ +ifeq (,$(wildcard ${PREFIX}/etc/local_internal_options.conf)) + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) ../etc/local_internal_options.conf ${PREFIX}/etc/local_internal_options.conf +endif +ifeq (,$(wildcard ${PREFIX}/etc/client.keys)) + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) /dev/null ${PREFIX}/etc/client.keys +endif +ifeq (,$(wildcard ${PREFIX}/etc/openarmor.conf)) +ifneq (,$(wildcard ../etc/openarmor.mc)) + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) ../etc/openarmor.mc ${PREFIX}/etc/openarmor.conf +else + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) ${openarmor_CONF_SRC} ${PREFIX}/etc/openarmor.conf +endif +endif + + $(call INSTALL_CMD,0770,root,${openarmor_GROUP}) -d ${PREFIX}/etc/shared + $(call INSTALL_CMD,0640,${openarmor_USER},${openarmor_GROUP}) rootcheck/db/*.txt ${PREFIX}/etc/shared/ + + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/active-response + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/active-response/bin + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/agentless + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) agentlessd/scripts/* ${PREFIX}/agentless/ + + $(call INSTALL_CMD,0700,root,${openarmor_GROUP}) -d ${PREFIX}/.ssh + + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) ../active-response/*.sh ${PREFIX}/active-response/bin/ + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) ../active-response/firewalls/*.sh ${PREFIX}/active-response/bin/ + + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/var + $(call INSTALL_CMD,0770,root,${openarmor_GROUP}) -d ${PREFIX}/var/run + + ./init/fw-check.sh execute + + + +install-server-generic: install-common + $(call INSTALL_CMD,0660,${openarmor_USER},${openarmor_GROUP}) /dev/null ${PREFIX}/logs/active-responses.log + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/logs/archives + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/logs/alerts + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/logs/firewall + + $(call INSTALL_CMD,0550,root,0) openarmor-agentlessd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-analysisd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-monitord ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-reportd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-maild ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-remoted ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-logtest ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-csyslogd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-authd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-dbd ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) openarmor-makelists ${PREFIX}/bin + $(call INSTALL_CMD,0550,root,0) verify-agent-conf ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) clear_stats ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) list_agents ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) openarmor-regex ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) syscheck_update ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) agent_control ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) syscheck_control ${PREFIX}/bin/ + $(call INSTALL_CMD,0550,root,0) rootcheck_control ${PREFIX}/bin/ + + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/stats + $(call INSTALL_CMD,0550,root,${openarmor_GROUP}) -d ${PREFIX}/rules +ifneq (,$(wildcard ${PREFIX}/rules/local_rules.xml)) + cp ${PREFIX}/rules/local_rules.xml ${PREFIX}/rules/local_rules.xml.installbackup + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) -b ../etc/rules/*.xml ${PREFIX}/rules + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) ${PREFIX}/rules/local_rules.xml.installbackup ${PREFIX}/rules/local_rules.xml + rm ${PREFIX}/rules/local_rules.xml.installbackup +else + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) -b ../etc/rules/*.xml ${PREFIX}/rules +endif + + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/fts + + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/rootcheck + + $(call INSTALL_CMD,0750,${openarmor_USER_REM},${openarmor_GROUP}) -d ${PREFIX}/queue/agent-info + $(call INSTALL_CMD,0750,${openarmor_USER},${openarmor_GROUP}) -d ${PREFIX}/queue/agentless + + $(call INSTALL_CMD,0750,${openarmor_USER_REM},${openarmor_GROUP}) -d ${PREFIX}/queue/rids + + $(call INSTALL_CMD,0640,root,${openarmor_GROUP}) ../etc/decoder.xml ${PREFIX}/etc/ + + rm -f ${PREFIX}/etc/shared/merged.mg + + +.PHONY: failtarget +failtarget: + @echo "TARGET is required: " + @echo " make TARGET=server to build the server" + @echo " make TARGET=local - local version of server" + @echo " make TARGET=hybrid - hybrid version of server" + @echo " make TARGET=agent to build the unix agent" + @echo " make TARGET=winagent to build the windows agent" + +.PHONY: help +help: failtarget + @echo + @echo "General options: " + @echo " make V=1 Display full compiler messages" + @echo " make DEBUG=1 Build with symbols and without optimization" + @echo " make PREFIX=/path Install openarmor to '/path'. Defaults to /var/openarmor" + @echo " make MAXAGENTS=NUMBER Set the number of maximum agents to NUMBER. Defaults to 2048" + @echo " make REUSE_ID=yes Enables agent ID re-use" + @echo + @echo "Database options: " + @echo " make DATABASE=mysql Build with MYSQL Support" + @echo " Use MYSQL_CFLAGS and MYSQL_LIBS to override defaults" + @echo " make DATABASE=pgsql Build with PostgreSQL Support " + @echo " Use PGSQL_CFLAGS and PGSQL_LIBS to override defaults" + @echo + @echo "Geoip support: " + @echo " make USE_GEOIP=1 Build with GeoIP support" + @echo + @echo "External source options: " + @echo " make LUA_ENABLE=no Disable LUA build" + @echo " make ZLIB_SYSTEM=yes Use zlib sources from system" + @echo " make PCRE2_SYSTEM=yes Use pcre2 sources from system" + @echo + @echo "Examples: Client with debugging enabled" + @echo " make TARGET=agent DEBUG=1" + +.PHONY: settings +settings: + @echo + @echo "General settings:" + @echo " TARGET: ${TARGET}" + @echo " V: ${V}" + @echo " DEBUG: ${DEBUG}" + @echo " DEBUGAD: ${DEBUGAD}" + @echo " PREFIX: ${PREFIX}" + @echo " MAXAGENTS: ${MAXAGENTS}" + @echo " REUSE_ID: ${REUSE_ID}" + @echo " DATABASE: ${DATABASE}" + @echo " ONEWAY: ${ONEWAY}" + @echo " CLEANFULL: ${CLEANFULL}" + @echo "User settings:" + @echo " openarmor_GROUP: ${openarmor_GROUP}" + @echo " openarmor_USER: ${openarmor_USER}" + @echo " openarmor_USER_MAIL: ${openarmor_USER_MAIL}" + @echo " openarmor_USER_REM: ${openarmor_USER_REM}" + @echo "ZLIB settings:" + @echo " ZLIB_SYSTEM: ${ZLIB_SYSTEM}" + @echo " ZLIB_INCLUDE: ${ZLIB_INCLUDE}" + @echo " ZLIB_LIB: ${ZLIB_LIB}" + @echo "PCRE2 settings:" + @echo " PCRE2_SYSTEM: ${PCRE2_SYSTEM}" + @echo " PCRE2_INCLUDE: ${PCRE2_INCLUDE}" + @echo "Lua settings:" + @echo " LUA_PLAT: ${LUA_PLAT}" + @echo " LUA_ENABLE: ${LUA_ENABLE}" + @echo "USE settings:" + @echo " USE_ZEROMQ: ${USE_ZEROMQ}" + @echo " USE_GEOIP: ${USE_GEOIP}" + @echo " USE_PRELUDE: ${USE_PRELUDE}" + @echo " USE_OPENSSL: ${USE_OPENSSL}" + @echo " USE_INOTIFY: ${USE_INOTIFY}" + @echo " USE_SQLITE: ${USE_SQLITE}" + @echo " USE_PCRE2_JIT: ${USE_PCRE2_JIT}" + @echo " USE_SYSTEMD: ${USE_SYSTEMD}" + @echo "Mysql settings:" + @echo " includes: ${MI}" + @echo " libs: ${ML}" + @echo "Pgsql settings:" + @echo " includes: ${PI}" + @echo " libs: ${PL}" + @echo "Defines:" + @echo " ${DEFINES}" + @echo "Compiler:" + @echo " CFLAGS ${openarmor_CFLAGS}" + @echo " LDFLAGS ${openarmor_LDFLAGS}" + @echo " CC ${CC}" + @echo " MAKE ${MAKE}" + + +BUILD_SERVER+=external +BUILD_SERVER+=openarmor-maild +BUILD_SERVER+=openarmor-csyslogd +BUILD_SERVER+=openarmor-agentlessd +BUILD_SERVER+=openarmor-execd +BUILD_SERVER+=openarmor-logcollector +BUILD_SERVER+=openarmor-remoted +BUILD_SERVER+=openarmor-agentd +BUILD_SERVER+=manage_agents +BUILD_SERVER+=utils +BUILD_SERVER+=openarmor-syscheckd +BUILD_SERVER+=openarmor-monitord +BUILD_SERVER+=openarmor-reportd +ifneq (,$(filter ${USE_OPENSSL},auto yes)) +BUILD_SERVER+=openarmor-authd +endif +BUILD_SERVER+=openarmor-analysisd +BUILD_SERVER+=openarmor-logtest +BUILD_SERVER+=openarmor-makelists +BUILD_SERVER+=openarmor-dbd + +BUILD_AGENT+=external +BUILD_AGENT+=openarmor-agentd +ifneq (,$(filter ${USE_OPENSSL},auto yes)) +BUILD_AGENT+=agent-auth +endif +BUILD_AGENT+=openarmor-logcollector +BUILD_AGENT+=openarmor-syscheckd +BUILD_AGENT+=openarmor-execd +BUILD_AGENT+=manage_agents + +.PHONY: server local hybrid agent +ifeq (${MAKECMDGOALS},server) +$(error Do not use 'server' directly, use 'TARGET=server') +endif +server: ${BUILD_SERVER} + +ifeq (${MAKECMDGOALS},local) +$(error Do not use 'local' directly, use 'TARGET=local') +endif +local: ${BUILD_SERVER} + +ifeq (${MAKECMDGOALS},hybrid) +$(error Do not use 'hybrid' directly, use 'TARGET=hybrid') +endif +hybrid: ${BUILD_SERVER} + +ifeq (${MAKECMDGOALS},agent) +$(error Do not use 'agent' directly, use 'TARGET=agent') +endif +agent: ${BUILD_AGENT} + + +WINDOWS_BINS:=win32/openarmor-agent.exe win32/openarmor-agent-eventchannel.exe win32/openarmor-rootcheck.exe win32/manage_agents.exe win32/setup-windows.exe win32/setup-syscheck.exe win32/setup-iis.exe win32/add-localfile.exe win32/os_win32ui.exe win32/agent-auth.exe + +ifeq (${MAKECMDGOALS},winagent) +$(error Do not use 'winagent' directly, use 'TARGET=winagent') +endif +.PHONY: winagent +winagent: + ${MAKE} ${WINDOWS_BINS} CFLAGS="-DCLIENT -DWIN32 -I./${EXTERNAL_ZLIB} -I./${EXTERNAL_PCRE2}/install/include" LDFLAGS="-lwsock32 -lwevtapi -lshlwapi -lcomctl32 -lws2_32" + #cd ${EXTERNAL_LUA}src/ && ${MAKE} CC=${MING_BASE}${CC} -f Makefile.mingw mingw + #cp ${EXTERNAL_LUA}src/openarmor-lua.exe win32/ + #cp ${EXTERNAL_LUA}src/openarmor-luac.exe win32/ + cd win32/ && ./unix2dos.pl openarmor.conf > default-openarmor.conf + cd win32/ && ./unix2dos.pl help.txt > help_win.txt + cd win32/ && ./unix2dos.pl ../../etc/internal_options.conf > internal_options.conf + cd win32/ && ./unix2dos.pl ../../etc/local_internal_options-win.conf > default-local_internal_options.conf + cd win32/ && ./unix2dos.pl ../../LICENSE > LICENSE.txt + cd win32/ && ./unix2dos.pl ../../active-response/win/route-null.cmd > route-null.cmd + cd win32/ && ./unix2dos.pl ../../active-response/win/restart-openarmor.cmd > restart-openarmor.cmd + cd win32/ && makensis openarmor-installer.nsi + + +#################### +#### External ###### +#################### + +.PHONY: external lua +ifeq (${PCRE2_SYSTEM},no) +external: libcJSON.a ${EXTERNAL_ZLIB}libz.a lua libpcre2-8.a +else +external: libcJSON.a ${EXTERNAL_ZLIB}libz.a lua +endif + +lua: +ifeq (${LUA_ENABLE},yes) + cd ${EXTERNAL_LUA} && ${MAKE} ${LUA_PLAT} +endif + +${EXTERNAL_ZLIB}libz.a: +ifeq (${TARGET},winagent) + cd ${EXTERNAL_ZLIB} && cp zconf.h.in zconf.h && ${MAKE} -f win32/Makefile.gcc PREFIX=${MING_BASE} libz.a +else +ifeq (${ZLIB_SYSTEM},no) + cd ${EXTERNAL_ZLIB} && ./configure && ${MAKE} libz.a +endif +endif + +#### zlib ########## + +ifeq (${ZLIB_SYSTEM},no) +ZLIB_LIB=os_zlib.a ${EXTERNAL_ZLIB}libz.a +ZLIB_INCLUDE=-I./${EXTERNAL_ZLIB} +else +ZLIB_LIB=os_zlib.a +ZLIB_INCLUDE= +openarmor_LDFLAGS+=-lz +endif + +os_zlib_c := os_zlib/os_zlib.c +os_zlib_o := $(os_zlib_c:.c=.o) + +os_zlib/%.o: os_zlib/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $< -o $@ + +os_zlib.a: ${os_zlib_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + + + +#### cJSON ######### + +JSON_LIB=libcJSON.a +JSON_INCLUDE=-I./${EXTERNAL_JSON} + +cjson_c := ${EXTERNAL_JSON}cJSON.c +cjson_o := $(cjson_c:.c=.o) + +${EXTERNAL_JSON}%.o: ${EXTERNAL_JSON}%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +libcJSON.a: ${cjson_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + + + +#### pcre2 ########## + +ifeq (${PCRE2_SYSTEM},no) +libpcre2-8.a: ${EXTERNAL_PCRE2}/install/lib/libpcre2-8.a + cp $< $@ + ${openarmor_RANLIB} $@ + +${EXTERNAL_PCRE2}/install/lib/libpcre2-8.a: +ifeq (${TARGET}, winagent) + cd ${EXTERNAL_PCRE2} && \ + CC= ./configure \ + --prefix=$(shell pwd)/${EXTERNAL_PCRE2}/install \ + ${PCRE2_CONFIGURE_JIT} \ + --disable-shared \ + --enable-static \ + --host=${MING_BASE:%-=%} && \ + make install-libLTLIBRARIES install-nodist_includeHEADERS +else + cd ${EXTERNAL_PCRE2} && \ + ./configure \ + --prefix=$(shell pwd)/${EXTERNAL_PCRE2}/install \ + ${PCRE2_CONFIGURE_JIT} \ + --disable-shared \ + --enable-static && \ + make install-libLTLIBRARIES install-nodist_includeHEADERS +endif +endif + + +#################### +#### openarmor Libs #### +#################### + +openarmor_libs = os_crypto.a config.a shared.a os_net.a os_regex.a os_xml.a + +#### os_xml ######## + +os_xml_c := $(wildcard os_xml/*.c) +os_xml_o := $(os_xml_c:.c=.o) + +os_xml/%.o: os_xml/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +os_xml.a: ${os_xml_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + + +#### os_regex ###### + +os_regex_c := $(wildcard os_regex/*.c) +os_regex_o := $(os_regex_c:.c=.o) + +os_regex/%.o: os_regex/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +ifeq (${PCRE2_SYSTEM},no) +os_regex.a: ${os_regex_o} libpcre2-8.a + (mkdir -p libpcre2_objs && cd libpcre2_objs && ${QUIET_LINK}${MING_BASE}ar -x ../libpcre2-8.a) + ${openarmor_LINK} $@ ${os_regex_o} $(addprefix libpcre2_objs/,$(shell ${MING_BASE}ar -t libpcre2-8.a)) + ${openarmor_RANLIB} $@ + rm -rf libpcre2_objs +else +os_regex.a: ${os_regex_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ +endif + +#### os_net ########## + +os_net_c := $(wildcard os_net/*.c) +os_net_o := $(os_net_c:.c=.o) + +os_net/%.o: os_net/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +os_net.a: ${os_net_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + +#### Shared ########## + +shared_c := $(wildcard shared/*.c) +shared_o := $(shared_c:.c=.o) + +shared/%.o: shared/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +shared.a: ${shared_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + +#### Config ########## + +config_c := $(wildcard config/*.c) +config_o := $(config_c:.c=.o) + +config/%.o: config/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +config.a: ${config_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + +#### crypto ########## + +crypto_blowfish_c := os_crypto/blowfish/bf_op.c \ + os_crypto/blowfish/bf_skey.c \ + os_crypto/blowfish/bf_enc.c +crypto_blowfish_o := $(crypto_blowfish_c:.c=.o) + +os_crypto/blowfish/%.o: os_crypto/blowfish/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -Wno-implicit-fallthrough -c $^ -o $@ + +crypto_md5_c := os_crypto/md5/md5.c \ + os_crypto/md5/md5_op.c +crypto_md5_o := $(crypto_md5_c:.c=.o) + +os_crypto/md5/%.o: os_crypto/md5/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +crypto_sha1_c := os_crypto/sha1/sha1_op.c +crypto_sha1_o := $(crypto_sha1_c:.c=.o) + +os_crypto/sha1/%.o: os_crypto/sha1/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -Wno-implicit-fallthrough -c $^ -o $@ + +crypto_md5_sha1_c := os_crypto/md5_sha1/md5_sha1_op.c +crypto_md5_sha1_o := $(crypto_md5_sha1_c:.c=.o) + +os_crypto/md5_sha1/%.o: os_crypto/md5_sha1/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +crypto_shared_c := $(wildcard os_crypto/shared/*.c) +crypto_shared_o := $(crypto_shared_c:.c=.o) + +os_crypto/shared/%.o: os_crypto/shared/%.c ${ZLIB_LIB} + ${openarmor_CC} ${openarmor_CFLAGS} -c $< -o $@ + + +crypto_o := ${crypto_blowfish_o} \ + ${crypto_md5_o} \ + ${crypto_sha1_o} \ + ${crypto_shared_o} \ + ${crypto_md5_sha1_o} + +os_crypto.a: ${crypto_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + +#### os_mail ######### + +os_maild_c := $(wildcard os_maild/*.c) +os_maild_o := $(os_maild_c:.c=.o) + +os_maild/%.o: os_maild/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-maild\" -c $^ -o $@ + +openarmor-maild: ${os_maild_o} ${openarmor_libs} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} ${DNS_CFLAGS} ${COMPAT_FILES} -o $@ + +#### os_dbd ########## + +os_dbd_c := $(wildcard os_dbd/*.c) +os_dbd_o := $(os_dbd_c:.c=.o) + +os_dbd/%.o: os_dbd/%.c + ${openarmor_CC} ${openarmor_CFLAGS} ${MI} ${PI} -DARGV0=\"openarmor-dbd\" -c $^ -o $@ + +openarmor-dbd: ${os_dbd_o} ${openarmor_libs} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${MI} ${PI} ${JSON_INCLUDE} $^ -lm ${openarmor_LDFLAGS} -o $@ + + +#### os_csyslogd ##### + +os_csyslogd_c := $(wildcard os_csyslogd/*.c) +os_csyslogd_o := $(os_csyslogd_c:.c=.o) + +os_csyslogd/%.o: os_csyslogd/%.c + ${openarmor_CC} ${openarmor_CFLAGS} ${JSON_INCLUDE} -DARGV0=\"openarmor-csyslogd\" -c $^ -o $@ + +openarmor-csyslogd: ${os_csyslogd_o} ${openarmor_libs} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${JSON_INCLUDE} $^ -lm ${openarmor_LDFLAGS} -o $@ + + +#### agentlessd #### + +os_agentlessd_c := $(wildcard agentlessd/*.c) +os_agentlessd_o := $(os_agentlessd_c:.c=.o) + +agentlessd/%.o: agentlessd/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-agentlessd\" -c $^ -o $@ + +openarmor-agentlessd: ${os_agentlessd_o} ${openarmor_libs} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +#### os_execd ##### + +os_execd_c := $(wildcard os_execd/*.c) +os_execd_o := $(os_execd_c:.c=.o) + +os_execd/%.o: os_execd/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-execd\" -c $^ -o $@ + +openarmor-execd: ${os_execd_o} ${openarmor_libs} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${JSON_INCLUDE} $^ -lm ${openarmor_LDFLAGS} -o $@ + + +#### logcollectord #### + +os_logcollector_c := $(wildcard logcollector/*.c) +os_logcollector_o := $(os_logcollector_c:.c=.o) +os_logcollector_eventchannel_o := $(os_logcollector_c:.c=-event.o) + +logcollector/%.o: logcollector/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-logcollector\" -c $^ -o $@ + +logcollector/%-event.o: logcollector/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DEVENTCHANNEL_SUPPORT -DARGV0=\"openarmor-logcollector\" -c $^ -o $@ + +openarmor-logcollector: ${os_logcollector_o} ${openarmor_libs} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +#### remoted ######### + +remoted_c := $(wildcard remoted/*.c) +remoted_o := $(remoted_c:.c=.o) + +remoted/%.o: remoted/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -I./remoted ${ZLIB_INCLUDE} -DARGV0=\"openarmor-remoted\" -c $^ -o $@ + +openarmor-remoted: ${remoted_o} ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +#### openarmor-agentd #### + +ifneq (${TARGET},winagent) +client_agent_c := $(wildcard client-agent/*.c) +else +client_agent_c := $(wildcard client-agent/*.c) +endif +client_agent_o := $(client_agent_c:.c=.o) + +client-agent/%.o: client-agent/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -I./client-agent ${ZLIB_INCLUDE} -DARGV0=\"openarmor-agentd\" -c $^ -o $@ + +openarmor-agentd: ${client_agent_o} ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} ${DNS_CFLAGS} ${COMPAT_FILES} -o $@ + +#### addagent ###### + +addagent_c := $(wildcard addagent/*.c) +addagent_o := $(addagent_c:.c=.o) + +addagent/%.o: addagent/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -I./addagent ${ZLIB_INCLUDE} -DARGV0=\"manage_agents\" -c $^ -o $@ + + +manage_agents: ${addagent_o} ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} ${JSON_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +#### Util ########## + +util_programs = syscheck_update clear_stats list_agents agent_control syscheck_control rootcheck_control verify-agent-conf openarmor-regex openarmor-regex-convert + +.PHONY: utils +utils: ${util_programs} + +util_c := $(wildcard util/*.c) +util_o := $(util_c:.c=.o) + +util/%.o: util/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -I./util ${ZLIB_INCLUDE} -DARGV0=\"utils\" -c $^ -o $@ + +syscheck_update: util/syscheck_update.o addagent/validate.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} ${JSON_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +clear_stats: util/clear_stats.o ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +list_agents: util/list_agents.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +verify-agent-conf: util/verify-agent-conf.o ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +agent_control: util/agent_control.o addagent/validate.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} ${JSON_INCLUDE} $^ -lm ${openarmor_LDFLAGS} -o $@ + +syscheck_control: util/syscheck_control.o addagent/validate.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} ${JSON_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +rootcheck_control: util/rootcheck_control.o addagent/validate.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} ${JSON_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +openarmor-regex: util/openarmor-regex.o ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +openarmor-regex-convert: util/openarmor-regex-convert.o ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +#### rootcheck ##### + +rootcheck_c := $(wildcard rootcheck/*.c) +rootcheck_o := $(rootcheck_c:.c=.o) +rootcheck_rk_o := $(rootcheck_c:.c=_rk.o) +rootcheck_o_lib := $(filter-out rootcheck/rootcheck-config.o, ${rootcheck_o}) +rootcheck_o_cmd := $(filter-out rootcheck/config.o, ${rootcheck_o}) + + +rootcheck/%.o: rootcheck/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"rootcheck\" -c $^ -o $@ + +rootcheck/%_rk.o: rootcheck/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"rootcheck\" -UopenarmorHIDS -c $^ -o $@ + + +rootcheck.a: ${rootcheck_o_lib} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + +#openarmor-rootcheck: rootcheck/rootcheck-config.o rootcheck.a ${openarmor_libs} +# @echo ${rootcheck_o_cmd} +# @echo ${rootcheck_o_lib} +# @echo ${rootcheck_o} +# ${openarmor_CC} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} rootcheck/rootcheck-config.o rootcheck.a rootcheck/rootcheck.c ${ZLIB_LIB} ${openarmor_libs} -o $@ + +#### syscheck ###### + + +syscheck_c := $(wildcard syscheckd/*.c) +syscheck_o := $(syscheck_c:.c=.o) + +syscheckd/%.o: syscheckd/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-syscheckd\" -c $^ -o $@ + +openarmor-syscheckd: ${syscheck_o} rootcheck.a ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + +#### Monitor ####### + +monitor_c := $(wildcard monitord/*.c) +monitor_o := $(monitor_c:.c=.o) + +monitord/%.o: monitord/%.c ${ZLIB_LIB} + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-monitord\" -c $< -o $@ + +openarmor-monitord: ${monitor_o} ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${ZLIB_INCLUDE} $^ ${openarmor_LDFLAGS} -o $@ + + +#### reportd ####### + +report_c := reportd/report.c +report_o := $(report_c:.c=.o) + +reportd/%.o: reportd/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-reportd\" -c $^ -o $@ + +openarmor-reportd: ${report_o} ${openarmor_libs} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + + +#### os_auth ####### + +os_auth_c := ${wildcard os_auth/*.c} +os_auth_o := $(os_auth_c:.c=.o) + +os_auth/%.o: os_auth/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -I./os_auth -DARGV0=\"openarmor-authd\" -c $^ -o $@ + +agent-auth: addagent/validate.o os_auth/main-client.o os_auth/ssl.o os_auth/check_cert.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${JSON_INCLUDE} -I./os_auth $^ ${openarmor_LDFLAGS} -o $@ + +openarmor-authd: addagent/validate.o os_auth/main-server.o os_auth/ssl.o os_auth/check_cert.o ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} ${JSON_INCLUDE} -I./os_auth $^ ${openarmor_LDFLAGS} -o $@ + +#### analysisd ##### + +cdb_c := ${wildcard analysisd/cdb/*.c} +cdb_o := $(cdb_c:.c=.o) +all_analysisd_o += ${cdb_o} +all_analysisd_libs += cdb.a + +analysisd/cdb/%.o: analysisd/cdb/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/cdb -c $^ -o $@ + +cdb.a: ${cdb_o} + ${openarmor_LINK} $@ $^ + ${openarmor_RANLIB} $@ + + +alerts_c := ${wildcard analysisd/alerts/*.c} +alerts_o := $(alerts_c:.c=.o) +all_analysisd_o += ${alerts_o} +all_analysisd_libs += alerts.a + +analysisd/alerts/%.o: analysisd/alerts/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/alerts -c $^ -o $@ + +alerts.a: ${alerts_o} + ${openarmor_LINK} $@ $^ + +decoders_c := ${wildcard analysisd/decoders/*.c} ${wildcard analysisd/decoders/plugins/*.c} ${wildcard analysisd/compiled_rules/*.c} +decoders_o := $(decoders_c:.c=.o) +## XXX Nasty hack +decoders_test_o := $(decoders_c:.c=-test.o) +decoders_live_o := $(decoders_c:.c=-live.o) + +all_analysisd_o += ${decoders_o} ${decoders_test_o} ${decoders_live_o} +all_analysisd_libs += decoders.a decoders-test.a decoders-live.a + + +analysisd/decoders/%-test.o: analysisd/decoders/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DTESTRULE -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + + +analysisd/decoders/%-live.o: analysisd/decoders/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + +analysisd/decoders/plugins/%-test.o: analysisd/decoders/plugins/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DTESTRULE -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + + +analysisd/decoders/plugins/%-live.o: analysisd/decoders/plugins/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + +analysisd/compiled_rules/compiled_rules.h: analysisd/compiled_rules/.function_list analysisd/compiled_rules/register_rule.sh + ./analysisd/compiled_rules/register_rule.sh build + +analysisd/compiled_rules/%-test.o: analysisd/compiled_rules/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DTESTRULE -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + +analysisd/compiled_rules/%-live.o: analysisd/compiled_rules/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + +decoders-live.a: ${decoders_live_o} + ${openarmor_LINK} $@ $^ + +decoders-test.a: ${decoders_test_o} + ${openarmor_LINK} $@ $^ + +format_c := ${wildcard analysisd/format/*.c} +format_o := ${format_c:.c=.o} +all_analysisd_o += ${format_o} + +analysisd/format/%.o: analysisd/format/%.c + ${openarmor_CC} ${openarmor_CFLAGS} ${JSON_INCLUDE} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + +output_c := ${wildcard analysisd/output/*c} +output_o := ${output_c:.c=.o} +all_analysisd_o += ${output_o} + +analysisd/output/%.o: analysisd/output/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -I./analysisd/decoders -c $^ -o $@ + + + +analysisd_c := ${filter-out analysisd/analysisd.c, ${filter-out analysisd/testrule.c, ${filter-out analysisd/makelists.c, ${wildcard analysisd/*.c}}}} +analysisd_o := ${analysisd_c:.c=.o} +all_analysisd_o += ${analysisd_o} + +analysisd_test_o := $(analysisd_o:.o=-test.o) +analysisd_live_o := $(analysisd_o:.o=-live.o) +all_analysisd_o += ${analysisd_test_o} ${analysisd_live_o} analysisd/testrule-test.o analysisd/analysisd-live.o analysisd/analysisd-test.o analysisd/makelists-live.o + +analysisd/%-live.o: analysisd/%.c analysisd/compiled_rules/compiled_rules.h + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-analysisd\" -I./analysisd -c $< -o $@ + +analysisd/%-test.o: analysisd/%.c analysisd/compiled_rules/compiled_rules.h + ${openarmor_CC} ${openarmor_CFLAGS} -DTESTRULE -DARGV0=\"openarmor-analysisd\" -I./analysisd -c $< -o $@ + + +openarmor-logtest: ${analysisd_test_o} ${output_o} ${format_o} analysisd/testrule-test.o analysisd/analysisd-test.o alerts.a cdb.a decoders-test.a ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} -DTESTRULE $^ ${openarmor_LDFLAGS} ${ANALYSISD_FLAGS} -o $@ + +openarmor-analysisd: ${analysisd_live_o} analysisd/analysisd-live.o ${output_o} ${format_o} alerts.a cdb.a decoders-live.a ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} ${ANALYSISD_FLAGS} -o $@ + +openarmor-makelists: analysisd/makelists-live.o ${analysisd_live_o} ${format_o} alerts.a cdb.a decoders-live.a ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + + +#################### +#### test ########## +#################### + +CFLAGS_TEST = -g -O0 --coverage + +LDFLAGS_TEST = -lcheck -lm -pthread -lrt -lsubunit + +ifdef TEST + openarmor_CFLAGS+=${CFLAGS_TEST} + openarmor_LDFLAGS+=${LDFLAGS_TEST} +endif #TEST + +test_programs = test_os_zlib test_os_xml test_os_regex test_os_crypto test_shared + +.PHONY: test run_tests build_tests test_valgrind test_coverage + +test: build_tests + ${MAKE} run_tests + +run_tests: + @$(foreach bin,${test_programs},./${bin} || exit 1;) + +build_tests: external + ${MAKE} DEBUG=1 TEST=1 ${test_programs} + +test_c := $(wildcard tests/*.c) +test_o := $(test_c:.c=.o) + +tests/%.o: tests/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -c $^ -o $@ + +test_os_zlib: tests/test_os_zlib.o ${ZLIB_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +test_os_xml: tests/test_os_xml.o os_xml.a + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +test_os_regex: tests/test_os_regex.c os_regex.a + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +test_os_crypto: tests/test_os_crypto.c os_crypto.a shared.a os_xml.a os_net.a os_regex.a ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +#test_os_net: tests/test_os_net.c os_net.a shared.a os_regex.a os_xml.a +# ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +test_shared: tests/test_shared.c shared.a os_xml.a os_net.a os_regex.a ${JSON_LIB} + ${openarmor_CCBIN} ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +test_valgrind: build_tests + valgrind --leak-check=full --track-origins=yes --trace-children=yes --vgdb=no --error-exitcode=0 --gen-suppressions=all --suppressions=tests/valgrind.supp ${MAKE} run_tests + + +test_coverage: build_tests + lcov --base-directory . --directory . --zerocounters --rc lcov_branch_coverage=1 --quiet + @echo "Running tests\n" + + ${MAKE} run_tests + + @echo "\nTests finished." + + lcov --base-directory . --directory . --capture --quiet --rc lcov_branch_coverage=1 --output-file openarmor.test + + rm -rf coverage-report/ + genhtml --branch-coverage --output-directory coverage-report/ --title "openarmor test coverage" --show-details --legend --num-spaces 4 --quiet openarmor.test + +#################### +#### RUule Tests ### +#################### + +test-rules: + ( cd ../contrib/openarmor-testing && sudo python runtests.py) + + +#################### +#### windows ####### +#################### + +win32/icon.o: win32/icofile.rc + ${openarmor_WINDRES} -i $< -o $@ + +win32_c := $(wildcard win32/*.c) +win32_o := $(win32_c:.c=.o) + +win32/%.o: win32/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -DARGV0=\"openarmor-agent\" -c $^ -o $@ + +win32/%_rk.o: win32/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -UopenarmorHIDS -DARGV0=\"openarmor-agent\" -c $^ -o $@ + +win32_ui_c := $(wildcard win32/ui/*.c) +win32_ui_o := $(win32_ui_c:.c=.o) + +win32/ui/%.o: win32/ui/%.c + ${openarmor_CC} ${openarmor_CFLAGS} -UopenarmorHIDS -DARGV0=\"openarmor-win32ui\" -c $^ -o $@ + +win32/openarmor-agent.exe: win32/icon.o win32/win_agent.o win32/win_service.o $(filter-out syscheckd/seechanges.o, ${syscheck_o}) ${rootcheck_o} $(filter-out client-agent/main.o, $(filter-out client-agent/agentd.o, $(filter-out client-agent/event-forward.o, ${client_agent_o}))) $(filter-out logcollector/main.o, ${os_logcollector_o}) ${os_execd_o} ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} -DARGV0=\"openarmor-agent\" -DopenarmorHIDS ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/openarmor-agent-eventchannel.exe: win32/icon.o win32/win_agent.o win32/win_service.o $(filter-out syscheckd/seechanges.o, ${syscheck_o}) ${rootcheck_o} $(filter-out client-agent/main.o, $(filter-out client-agent/agentd.o, $(filter-out client-agent/event-forward.o, ${client_agent_o}))) $(filter-out logcollector/main-event.o, ${os_logcollector_eventchannel_o}) ${os_execd_o} ${openarmor_libs} ${ZLIB_LIB} + ${openarmor_CCBIN} -DARGV0=\"openarmor-agent\" -DopenarmorHIDS -DEVENTCHANNEL_SUPPORT ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/openarmor-rootcheck.exe: win32/icon.o win32/win_service_rk.o ${rootcheck_rk_o} ${openarmor_libs} + ${openarmor_CCBIN} -DARGV0=\"openarmor-rootcheck\" ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/manage_agents.exe: win32/win_service_rk.o ${addagent_o} ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} -DARGV0=\"manage-agents\" -DMA ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/setup-windows.exe: win32/win_service_rk.o win32/setup-win.o win32/setup-shared.o ${openarmor_libs} + ${openarmor_CCBIN} -DARGV0=\"setup-windows\" ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/setup-syscheck.exe: win32/setup-syscheck.o win32/setup-shared.o ${openarmor_libs} + ${openarmor_CCBIN} -DARGV0=\"setup-syscheck\" ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/setup-iis.exe: win32/setup-iis.o ${openarmor_libs} + ${openarmor_CCBIN} -DARGV0=\"setup-iis\" ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/add-localfile.exe: win32/add-localfile.o ${openarmor_libs} + ${openarmor_CCBIN} -DARGV0=\"add-localfile\" ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -o $@ + +win32/resource.o: win32/ui/win32ui.rc + ${openarmor_WINDRES} -i $< -o $@ + +win32/os_win32ui.exe: win32/resource.o win32/win_service_rk.o ${win32_ui_o} addagent/b64.o ${openarmor_libs} + ${openarmor_CCBIN} -DARGV0=\"openarmor-win32ui\" ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -mwindows -o $@ + +win32/agent-auth.exe: win32/win_service_rk.o addagent/validate.c win32/agent_auth.c ${openarmor_libs} ${ZLIB_LIB} ${JSON_LIB} + ${openarmor_CCBIN} -DARGV0=\"agent-auth\" -DopenarmorHIDS ${openarmor_CFLAGS} $^ ${openarmor_LDFLAGS} -lshlwapi -lwsock32 -lsecur32 -flto -o $@ + + + + +#################### +#### Clean ######### +#################### + +clean: clean-test clean-internals clean-external clean-windows + +clean-test: + rm -f ${test_o} ${test_programs} openarmor.test + rm -Rf coverage-report/ + find . -name "*.gcno" -exec rm {} \; + find . -name "*.gcda" -exec rm {} \; + +clean-external: + rm -f ${cjson_o} libcJSON.a libpcre2-8.a + cd ${EXTERNAL_ZLIB} && ${MAKE} -f Makefile.in distclean + cd ${EXTERNAL_LUA} && ${MAKE} clean + #cd ${EXTERNAL_PCRE2} && ${MAKE} distclean + + +clean-internals: + rm -f ${os_zlib_o} os_zlib.a + rm -f ${os_xml_o} os_xml.a + rm -f ${os_regex_o} os_regex.a + rm -f ${os_net_o} os_net.a + rm -f ${shared_o} shared.a + rm -f ${config_o} config.a + rm -f ${os_maild_o} openarmor-maild + rm -f ${crypto_o} os_crypto.a + rm -f ${os_csyslogd_o} openarmor-csyslogd + rm -f ${os_dbd_o} openarmor-dbd + rm -f ${os_agentlessd_o} openarmor-agentlessd + rm -f ${os_execd_o} openarmor-execd + rm -f ${os_logcollector_o} ${os_logcollector_eventchannel_o} openarmor-logcollector + rm -f ${remoted_o} openarmor-remoted + rm -f ${report_o} openarmor-reportd + rm -f ${client_agent_o} openarmor-agentd + rm -f ${addagent_o} manage_agents + rm -f ${util_o} ${util_programs} + rm -f ${rootcheck_o} ${rootcheck_rk_o} rootcheck.a + rm -f ${syscheck_o} openarmor-syscheckd + rm -f ${monitor_o} openarmor-monitord + rm -f ${os_auth_o} openarmor-authd agent-auth + rm -f ${all_analysisd_o} ${all_analysisd_libs} analysisd/compiled_rules/compiled_rules.h + rm -f openarmor-logtest openarmor-analysisd openarmor-makelists + +clean-windows: + rm -f win32/LICENSE.txt + rm -f win32/help_win.txt + rm -f win32/internal_options.conf + rm -f win32/default-local_internal_options.conf + rm -f win32/default-openarmor.conf + rm -f win32/restart-openarmor.cmd + rm -f win32/route-null.cmd + rm -f ${win32_o} ${win32_ui_o} win32/win_service_rk.o + rm -f win32/icon.o win32/resource.o + rm -f ${WINDOWS_BINS} + #rm -f ${EXTERNAL_LUA}src/lua52.dll + #rm -f ${EXTERNAL_LUA}src/openarmor-lua.exe + #rm -f ${EXTERNAL_LUA}src/openarmor-luac.exe + #rm -f win32/openarmor-lua.exe + #rm -f win32/openarmor-luac.exe + rm -f win32/openarmor-win32-agent.exe diff --git a/src/VERSION b/src/VERSION new file mode 100644 index 000000000..40c06ccb7 --- /dev/null +++ b/src/VERSION @@ -0,0 +1 @@ +v3.8.0 diff --git a/src/addagent/b64.c b/src/addagent/b64.c new file mode 100644 index 000000000..de5d03304 --- /dev/null +++ b/src/addagent/b64.c @@ -0,0 +1,225 @@ +/* + * Copyright (C), 2000-2004 by the monit project group. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* base64 encoding/decoding + * Author: Jan-Henrik Haukeland + */ + +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/* Prototypes */ +static int is_base64(char c); +static char encode(unsigned char u); +static unsigned char decode(char c); + +/* Global variables */ +char *decode_base64(const char *src); +char *encode_base64(int size, char *src); + + +/* Base64 encode and return size data in 'src'. The caller must free the + * returned string. + * Returns encoded string otherwise NULL + */ +char *encode_base64(int size, char *src) +{ + int i; + char *out, *p; + + if (!src) { + return NULL; + } + + if (!size) { + size = strlen((char *)src); + } + + out = (char *)calloc(sizeof(char), size * 4 / 3 + 4); + if (!out) { + return NULL; + } + + p = out; + + for (i = 0; i < size; i += 3) { + unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0, b7 = 0; + + b1 = src[i]; + + if (i + 1 < size) { + b2 = src[i + 1]; + } + + if (i + 2 < size) { + b3 = src[i + 2]; + } + + b4 = b1 >> 2; + b5 = ((b1 & 0x3) << 4) | (b2 >> 4); + b6 = ((b2 & 0xf) << 2) | (b3 >> 6); + b7 = b3 & 0x3f; + + *p++ = encode(b4); + *p++ = encode(b5); + + if (i + 1 < size) { + *p++ = encode(b6); + } else { + *p++ = '='; + } + + if (i + 2 < size) { + *p++ = encode(b7); + } else { + *p++ = '='; + } + } + + return out; +} + +/* Decode the base64 encoded string 'src' into the memory pointed to by + * 'dest'. The dest buffer is NUL terminated. + * Returns NULL in case of error + */ +char *decode_base64(const char *src) +{ + if (src && *src) { + char *dest; + unsigned char *p; + int k, l = strlen(src) + 1; + unsigned char *buf; + + /* The size of the dest will always be less than the source */ + dest = (char *)calloc(sizeof(char), l + 13); + if (!dest) { + return (NULL); + } + + p = (unsigned char *)dest; + + buf = (unsigned char *) malloc(l); + if (!buf) { + free(dest); + return (NULL); + } + + /* Ignore non base64 chars as per the POSIX standard */ + for (k = 0, l = 0; src[k]; k++) { + if (is_base64(src[k])) { + buf[l++] = src[k]; + } + } + + for (k = 0; k < l; k += 4) { + char c1 = 'A', c2 = 'A', c3 = 'A', c4 = 'A'; + unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0; + + c1 = buf[k]; + + if (k + 1 < l) { + c2 = buf[k + 1]; + } + + if (k + 2 < l) { + c3 = buf[k + 2]; + } + + if (k + 3 < l) { + c4 = buf[k + 3]; + } + + b1 = decode(c1); + b2 = decode(c2); + b3 = decode(c3); + b4 = decode(c4); + + *p++ = ((b1 << 2) | (b2 >> 4) ); + + if (c3 != '=') { + *p++ = (((b2 & 0xf) << 4) | (b3 >> 2) ); + } + + if (c4 != '=') { + *p++ = (((b3 & 0x3) << 6) | b4 ); + } + + } + + free(buf); + + return (dest); + } + return (NULL); +} + +static char encode(unsigned char u) +{ + if (u < 26) { + return 'A' + u; + } + if (u < 52) { + return 'a' + (u - 26); + } + if (u < 62) { + return '0' + (u - 52); + } + if (u == 62) { + return '+'; + } + + return '/'; +} + +/* Decode a base64 character */ +static unsigned char decode(char c) +{ + if (c >= 'A' && c <= 'Z') { + return (c - 'A'); + } + if (c >= 'a' && c <= 'z') { + return (c - 'a' + 26); + } + if (c >= '0' && c <= '9') { + return (c - '0' + 52); + } + if (c == '+') { + return 62; + } + + return 63; +} + +/* Returns TRUE if 'c' is a valid base64 character, otherwise FALSE */ +static int is_base64(char c) +{ + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || (c == '+') || + (c == '/') || (c == '=')) { + + return TRUE; + } + return FALSE; +} + diff --git a/src/addagent/main.c b/src/addagent/main.c new file mode 100644 index 000000000..885f7ba18 --- /dev/null +++ b/src/addagent/main.c @@ -0,0 +1,374 @@ +/* Copyright (C) 2019 openarmor Foundation + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "manage_agents.h" +#include + +/* Prototypes */ +static void helpmsg(void) __attribute__((noreturn)); +static void print_banner(void); +#ifndef WIN32 +static void manage_shutdown(int sig) __attribute__((noreturn)); +#endif + +int willchroot; + +#if defined(__MINGW32__) +static int setenv(const char *name, const char *val, __attribute__((unused)) int overwrite) +{ + int len = strlen(name) + strlen(val) + 2; + char *str = (char *)malloc(len); + if(str == NULL) { + merror("%s: malloc failed", ARGV0); + exit(errno); + } + snprintf(str, len, "%s=%s", name, val); + putenv(str); + return 0; +} +#endif + +static void helpmsg() +{ + print_header(); + print_out(" %s: -[Vhlj] [-a -n ] [-d sec] [-e id] [-r id] [-i id] [-f file]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -j Use JSON output"); + print_out(" -l List available agents."); + print_out(" -a Add new agent"); + + print_out(" -e Extracts key for an agent (Manager only)"); + print_out(" -r Remove an agent (Manager only)"); + print_out(" -i Import authentication key (Agent only)"); + print_out(" -n Name for new agent"); + print_out(" -F Remove agents with duplicated IP if disconnected since seconds"); + print_out(" -f Bulk generate client keys from file (Manager only)"); + print_out(" contains lines in IP,NAME format"); + print_out(" should also exist within /var/openarmor due to manage_agents chrooting"); + exit(1); +} + +static void print_banner() +{ + printf("\n"); + printf(BANNER, __openarmor_name, __openarmor_version); + +#ifdef CLIENT + printf(BANNER_CLIENT); +#else + printf(BANNER_OPT); +#endif + + return; +} + +#ifndef WIN32 +/* Clean shutdown on kill */ +static void manage_shutdown(__attribute__((unused)) int sig) +{ + /* Checking if restart message is necessary */ + if (restart_necessary) { + printf(MUST_RESTART); + } else { + printf("\n"); + } + printf(EXIT); + + exit(0); +} +#endif + +int main(int argc, char **argv) +{ + char *user_msg; + int c = 0, cmdlist = 0, json_output = 0; + int force_antiquity; + char *end; + const char *cmdexport = NULL; + const char *cmdimport = NULL; + const char *cmdbulk = NULL; +#ifndef WIN32 + const char *dir = DEFAULTDIR; + const char *group = GROUPGLOBAL; + gid_t gid; +#else + FILE *fp; + TCHAR path[2048]; + DWORD last_error; + int ret; +#endif + + extern int willchroot; + willchroot = 1; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vhle:r:i:f:ja:n:F:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + helpmsg(); + break; + case 'e': +#ifdef CLIENT + ErrorExit("%s: Key export only available on a master.", ARGV0); +#endif + if (!optarg) { + ErrorExit("%s: -e needs an argument.", ARGV0); + } + cmdexport = optarg; + break; + case 'r': +#ifdef CLIENT + ErrorExit("%s: Key removal only available on a master.", ARGV0); +#endif + if (!optarg) { + ErrorExit("%s: -r needs an argument.", ARGV0); + } + + /* Use environment variables already available to remove_agent() */ + setenv("openarmor_ACTION", "r", 1); + setenv("openarmor_AGENT_ID", optarg, 1); + setenv("openarmor_ACTION_CONFIRMED", "y", 1); + break; + case 'i': +#ifndef CLIENT + ErrorExit("%s: Key import only available on an agent.", ARGV0); +#endif + if (!optarg) { + ErrorExit("%s: -i needs an argument.", ARGV0); + } + cmdimport = optarg; + break; + case 'f': +#ifdef CLIENT + ErrorExit("%s: Bulk generate keys only available on a master.", ARGV0); +#endif + if (!optarg) { + ErrorExit("%s: -f needs an argument.", ARGV0); + } + cmdbulk = optarg; + willchroot = 0; + printf("Bulk load file: %s\n", cmdbulk); + break; + case 'l': + cmdlist = 1; + break; + case 'j': + json_output = 1; + break; + case 'a': +#ifdef CLIENT + ErrorExit("%s: Agent adding only available on a master.", ARGV0); +#endif + if (!optarg) + ErrorExit("%s: -a needs an argument.", ARGV0); + setenv("openarmor_ACTION", "a", 1); + setenv("openarmor_ACTION_CONFIRMED", "y", 1); + setenv("openarmor_AGENT_IP", optarg, 1); + setenv("openarmor_AGENT_ID", "0", 1); + break; + case 'n': + if (!optarg) + ErrorExit("%s: -n needs an argument.", ARGV0); + setenv("openarmor_AGENT_NAME", optarg, 1); + break; + case 'F': + if (!optarg) + ErrorExit("%s: -d needs an argument.", ARGV0); + + force_antiquity = strtol(optarg, &end, 10); + + if (optarg == end || force_antiquity < 0) + ErrorExit("%s: Invalid number for -d", ARGV0); + + setenv("openarmor_REMOVE_DUPLICATED", optarg, 1); + break; + default: + helpmsg(); + break; + } + } + + /* Get current time */ + time1 = time(0); + restart_necessary = 0; + + /* Before chroot */ + srandom_init(); + +#ifndef WIN32 + /* Get the group name */ + gid = Privsep_GetGroup(group); + if (gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, "", group); + } + + /* Set the group */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Inside chroot now */ + if(willchroot > 0) { + + /* Chroot to the default directory */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + nowChroot(); + } + + /* Start signal handler */ + StartSIG2(ARGV0, manage_shutdown); +#else + /* Get full path to the directory this executable lives in */ + ret = GetModuleFileName(NULL, path, sizeof(path)); + + /* Check for errors */ + if (!ret) { + ErrorExit(GMF_ERROR); + } + + /* Get last error */ + last_error = GetLastError(); + + /* Look for errors */ + if (last_error != ERROR_SUCCESS) { + if (last_error == ERROR_INSUFFICIENT_BUFFER) { + ErrorExit(GMF_BUFF_ERROR, ret, sizeof(path)); + } else { + ErrorExit(GMF_UNKN_ERROR, last_error); + } + } + + /* Remove file name from path */ + PathRemoveFileSpec(path); + + /* Move to correct directory */ + if (chdir(path)) { + ErrorExit(CHDIR_ERROR, ARGV0, path, errno, strerror(errno)); + } + + /* Check permissions */ + fp = fopen(openarmorCONF, "r"); + if (fp) { + fclose(fp); + } else { + ErrorExit(CONF_ERROR, openarmorCONF); + } +#endif + + if (cmdlist == 1) { + list_agents(cmdlist); + exit(0); + } else if (cmdimport) { + k_import(cmdimport); + exit(0); + } else if (cmdexport) { + k_extract(cmdexport, json_output); + exit(0); + } else if (cmdbulk) { + k_bulkload(cmdbulk); + exit(0); + } + + /* Little shell */ + while (1) { + int leave_s = 0; + + if (!json_output) + print_banner(); + + + /* Get ACTION from the environment. If ACTION is specified, + * we must set leave_s = 1 to ensure that the loop will end */ + user_msg = getenv("openarmor_ACTION"); + if (user_msg == NULL) { + user_msg = read_from_user(); + } else { + leave_s = 1; + } + + /* All the allowed actions */ + switch (user_msg[0]) { + case 'A': + case 'a': +#ifdef CLIENT + printf("\n ** Agent adding only available on a master ** \n\n"); + break; +#endif + add_agent(json_output); + break; + case 'e': + case 'E': +#ifdef CLIENT + printf("\n ** Key export only available on a master ** \n\n"); + break; +#endif + k_extract(NULL, json_output); + break; + case 'i': + case 'I': +#ifndef CLIENT + printf("\n ** Key import only available on an agent ** \n\n"); + break; +#else //CLIENT + k_import(NULL); + break; +#endif + case 'l': + case 'L': + list_agents(0); + break; + case 'r': + case 'R': +#ifdef CLIENT + printf("\n ** Key removal only available on a master ** \n\n"); + break; +#endif + remove_agent(json_output); + break; + case 'q': + case 'Q': + leave_s = 1; + break; + case 'V': + print_version(); + break; + default: + printf("\n ** Invalid Action ** \n\n"); + break; + } + + if (leave_s) { + break; + } + + continue; + } + + if (!json_output) { + if (restart_necessary) { + printf(MUST_RESTART); + } else { + printf("\n"); + } + + printf(EXIT); + } + printf(EXIT); + + return (0); +} diff --git a/src/addagent/manage_agents.c b/src/addagent/manage_agents.c new file mode 100644 index 000000000..19822c4dd --- /dev/null +++ b/src/addagent/manage_agents.c @@ -0,0 +1,571 @@ +/* Copyright (C) 2019 openarmor Foundation + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Manage agents tool + * Add/extract and remove agents from a server + */ + +#include "manage_agents.h" +#include "os_crypto/md5/md5_op.h" +#include "external/cJSON/cJSON.h" +#include + +/* Global variables */ +int restart_necessary; +time_t time1; +time_t time2; +time_t time3; +long int rand1; +long int rand2; + + +/* Remove spaces, newlines, etc from a string */ +char *chomp(char *str) +{ + char *tmp_str; + ssize_t size; + + /* Remove spaces from the beginning */ + while (*str == ' ' || *str == '\t') { + str++; + } + + /* Remove any trailing newlines or \r */ + do { + tmp_str = strchr(str, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + continue; + } + + tmp_str = strchr(str, '\r'); + if (tmp_str) { + *tmp_str = '\0'; + } + } while (tmp_str != NULL); + + /* Remove spaces at the end of the string */ + tmp_str = str; + size = (ssize_t) strlen(str) - 1; + + while ((size >= 0) && (tmp_str[size] == ' ' || tmp_str[size] == '\t')) { + tmp_str[size] = '\0'; + size--; + } + + return (str); +} + +int add_agent(int json_output) +{ + int i = 1; + FILE *fp; + char str1[STR_SIZE + 1]; + char str2[STR_SIZE + 1]; + + os_md5 md1; + os_md5 md2; + + char *user_input; + char *_name; + char *_id; + char *_ip; + + char name[FILE_SIZE + 1]; + char id[FILE_SIZE + 1] = { '\0' }; + char ip[FILE_SIZE + 1]; + os_ip c_ip; + c_ip.ip = NULL; + + char authfile[257]; + + extern int willchroot; + + if(willchroot > 0) { + snprintf(authfile, 256, "%s", AUTH_FILE); //XXX + } else { + const char *dir = DEFAULTDIR; + snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX + } + + + char *id_exist = NULL; + int force_antiquity; + + /* Check if we can open the auth_file */ + fp = fopen(authfile, "a"); + if (!fp) { + if (json_output) { + char buffer[1024]; + cJSON *json_root = cJSON_CreateObject(); + snprintf(buffer, 1023, "Could not open file '%s' due to [(%d)-(%s)]", AUTH_FILE, errno, strerror(errno)); + cJSON_AddNumberToObject(json_root, "error", 71); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); + } + fclose(fp); + + +#ifndef WIN32 + if (chmod(authfile, 0440) == -1) { + if (json_output) { + char buffer[1024]; + cJSON *json_root = cJSON_CreateObject(); + snprintf(buffer, 1023, "Could not chmod object '%s' due to [(%d)-(%s)]", AUTH_FILE, errno, strerror(errno)); + cJSON_AddNumberToObject(json_root, "error", 71); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); + + } +#endif + + /* Set time 2 */ + time2 = time(0); + + rand1 = random(); + + /* Zero strings */ + memset(str1, '\0', STR_SIZE + 1); + memset(str2, '\0', STR_SIZE + 1); + + if (!json_output) + printf(ADD_NEW); + + /* Get the name */ + memset(name, '\0', FILE_SIZE + 1); + + do { + if (!json_output) { + printf(ADD_NAME); + fflush(stdout); + } + /* Read the agent's name from user environment. If it is invalid + * we should force user to provide a name from input device. + */ + _name = getenv("openarmor_AGENT_NAME"); + if (_name == NULL || NameExist(_name) || !OS_IsValidName(_name)) { + if (json_output) { + cJSON *json_root = cJSON_CreateObject(); + cJSON_AddNumberToObject(json_root, "error", 76); + cJSON_AddStringToObject(json_root, "description", "Invalid name for agent"); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + _name = read_from_user(); + + } + + if (strcmp(_name, QUIT) == 0) { + goto cleanup; + } + + strncpy(name, _name, FILE_SIZE - 1); + + /* Check the name */ + if (!OS_IsValidName(name)) { + printf(INVALID_NAME, name); + } + + /* Search for name -- no duplicates */ + if (NameExist(name)) { + printf(ADD_ERROR_NAME, name); + } + } while (NameExist(name) || !OS_IsValidName(name)); + + /* Get IP */ + memset(ip, '\0', FILE_SIZE + 1); + + do { + if (!json_output) { + printf(ADD_IP); + fflush(stdout); + } + + + /* Read IP address from user's environment. If that IP is invalid, + * force user to provide IP from input device */ + _ip = getenv("openarmor_AGENT_IP"); + if (_ip == NULL || !OS_IsValidIP(_ip, &c_ip)) { + if (json_output) { + cJSON *json_root = cJSON_CreateObject(); + cJSON_AddNumberToObject(json_root, "error", 77); + cJSON_AddStringToObject(json_root, "description", "Invalid IP for agent"); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + _ip = read_from_user(); + + } + + /* Quit */ + if (strcmp(_ip, QUIT) == 0) { + goto cleanup; + } + + strncpy(ip, _ip, FILE_SIZE - 1); + + if (!OS_IsValidIP(ip, &c_ip)) { + printf(IP_ERROR, ip); + _ip = NULL; + } else if ((id_exist = IPExist(ip))) { + double antiquity = -1; + + const char *env_remove_dup = getenv("openarmor_REMOVE_DUPLICATED"); + + if (env_remove_dup) { + force_antiquity = strtol(env_remove_dup, NULL, 10); + antiquity = OS_AgentAntiquity(id_exist); + } + + if (env_remove_dup && (antiquity >= force_antiquity || antiquity < 0)) { + /* TODO: Save backup */ +#ifdef REUSE_ID + strncpy(id, id_exist, FILE_SIZE); +#endif + OS_RemoveAgent(id_exist); + } else { + /* TODO: Send alert */ + + if (json_output) { + cJSON *json_root = cJSON_CreateObject(); + cJSON_AddNumberToObject(json_root, "error", 79); + cJSON_AddStringToObject(json_root, "description", "Duplicated IP for agent"); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else { + printf(IP_DUP_ERROR, ip); + _ip = NULL; + } + } + } + + } while (!_ip); + + if (!*id) { + do { + /* Default ID */ + i = MAX_AGENTS + 32512; + snprintf(id, 8, "%03d", i); //XXX + while (!IDExist(id)) { + i--; + snprintf(id, 8, "%03d", i); + + /* No key present, use id 0 */ + if (i <= 0) { + i = 0; + break; + } + } + snprintf(id, 8, "%03d", i + 1); + + /* Get ID */ + if (!json_output) { + printf(ADD_ID, id); + fflush(stdout); + } + + + /* Get Agent ID from environment. If 0, use default ID. If null, + * get from user input. If value from environment is invalid, + * we force user to specify an ID from the terminal. Otherwise, + * our program goes to infinite loop. + */ + _id = getenv("openarmor_AGENT_ID"); + if (_id == NULL || IDExist(_id) || !OS_IsValidID(_id)) { + _id = read_from_user(); + } + + /* Quit */ + if (strcmp(_id, QUIT) == 0) { + goto cleanup; + } + + if (_id[0] != '\0' && strcmp(_id, "0")) { + strncpy(id, _id, FILE_SIZE - 1); + } + + if (OS_IsValidID(id)) { + FormatID(id); + } else { + printf(INVALID_ID, id); + } + + /* Search for ID KEY -- no duplicates */ + if (IDExist(id)) { + printf(ADD_ERROR_ID, id); + } + + } while (IDExist(id) || !OS_IsValidID(id)); + } + + if (!json_output) { + printf(AGENT_INFO, id, name, ip); + fflush(stdout); + } + + + do { + if (!json_output) + printf(ADD_CONFIRM); + + /* Confirmation by an environment variable. The valid value is y/Y. + * If the user provides anything other string, it is considered as + * n/N; please note that the old code only accepts y/Y/n/N. So if + * the variable openarmor_ACTION_CONFIRMED is 'foobar', the program will + * go into an infinite loop. + */ + user_input = getenv("openarmor_ACTION_CONFIRMED"); + if (user_input == NULL) { + user_input = read_from_user(); + } + + /* If user accepts to add */ + if (user_input[0] == 'y' || user_input[0] == 'Y') { + time3 = time(0); + rand2 = random(); + + fp = fopen(authfile, "a"); + if (!fp) { + if (json_output) { + char buffer[1024]; + cJSON *json_root = cJSON_CreateObject(); + snprintf(buffer, 1023, "Could not open file '%s' due to [(%d)-(%s)]", KEYS_FILE, errno, strerror(errno)); + cJSON_AddNumberToObject(json_root, "error", 71); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); + } +#ifndef WIN32 + if ((chmod(authfile, 0440)) != 0) { + if(json_output) { + char buffer[1024]; + snprintf(buffer, 1023, "%s: Could not chmod file %s due to [(%d)-(%s)]", ARGV0, authfile, errno, strerror(errno)); + cJSON *json_root = cJSON_CreateObject(); + cJSON_AddNumberToObject(json_root, "error", 76); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(errno); + } else { + ErrorExit("%s: Cannot chmod %s: %s", ARGV0, authfile, strerror(errno)); + } + } +#endif + + /* Random 1: Time took to write the agent information + * Random 2: Time took to choose the action + * Random 3: All of this + time + pid + * Random 4: Md5 all of this + the name, key and IP + * Random 5: Final key + */ + + snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1); + snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2); + + OS_MD5_Str(str1, md1); + OS_MD5_Str(str2, md2); + + snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(), + (int)time3); + OS_MD5_Str(str1, md1); + + fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip.ip, md1, md2); + fclose(fp); + + if (json_output) { + char buffer[1024]; + cJSON *json_root = cJSON_CreateObject(); + snprintf(buffer, 1023, "Agent added with ID %s", id); + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(AGENT_ADD, id); + + + restart_necessary = 1; + break; + } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */ + printf(ADD_NOT); + break; + } + } while (1); + + cleanup: + free(c_ip.ip); + + return (0); +} + +int remove_agent(int json_output) +{ + FILE *fp; + char *user_input; + char u_id[FILE_SIZE + 1]; + int id_exist; + + u_id[FILE_SIZE] = '\0'; + + extern int willchroot; + char authfile[257]; + if(willchroot > 0) { + snprintf(authfile, 256, "%s", AUTH_FILE); //XXX + } else { + const char *dir = DEFAULTDIR; + snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX + } + + + + if (!(json_output || print_agents(0, 0, 0, 0))) { + printf(NO_AGENT); + return (0); + } + + do { + if (!json_output) { + printf(REMOVE_ID); + fflush(stdout); + } + + user_input = getenv("openarmor_AGENT_ID"); + if (user_input == NULL) { + user_input = read_from_user(); + } else if (!json_output) { + printf("%s\n", user_input); + } + + if (strcmp(user_input, QUIT) == 0) { + return (0); + } + + FormatID(user_input); + strncpy(u_id, user_input, FILE_SIZE); + + id_exist = IDExist(user_input); + + if (!id_exist) { + if (json_output) { + char buffer[1024]; + cJSON *json_root = cJSON_CreateObject(); + snprintf(buffer, 1023, "Invalid ID '%s' given. ID is not present", user_input); + cJSON_AddNumberToObject(json_root, "error", 78); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + printf(NO_ID, user_input); + + + /* Exit here if we are using environment variables + * and our ID does not exist + */ + if (getenv("openarmor_AGENT_ID")) { + return (1); + } + } + } while (!id_exist); + + do { + if (!json_output) { + printf(REMOVE_CONFIRM); + fflush(stdout); + } + + + user_input = getenv("openarmor_ACTION_CONFIRMED"); + if (user_input == NULL) { + user_input = read_from_user(); + } else if (!json_output) { + printf("%s\n", user_input); + } + + /* If user confirms */ + if (user_input[0] == 'y' || user_input[0] == 'Y') { + /* Get full agent name */ + char *full_name = getFullnameById(u_id); + if (!full_name) { + if (json_output) { + char buffer[1024]; + cJSON *json_root = cJSON_CreateObject(); + snprintf(buffer, 1023, "Invalid ID '%s' given. ID is not present", u_id); + cJSON_AddNumberToObject(json_root, "error", 78); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + printf(NO_ID, u_id); + return (1); + } + + fp = fopen(authfile, "r+"); + if (!fp) { + free(full_name); + ErrorExit(FOPEN_ERROR, ARGV0, authfile, errno, strerror(errno)); + } +#ifndef WIN32 + chmod(authfile, 0440); +#endif + + /* Remove the agent, but keep the id */ + fsetpos(fp, &fp_pos); +#ifdef REUSE_ID + fprintf(fp, "#%s #*#*#*#*#*#*#*#*#*#*#", u_id); +#else + fprintf(fp, "%s #*#*#*#*#*#*#*#*#*#*#", u_id); +#endif + + fclose(fp); + + /* Remove counter for ID */ + delete_agentinfo(full_name); + OS_RemoveCounter(u_id); + free(full_name); + full_name = NULL; + + if (json_output) { + cJSON *json_root = cJSON_CreateObject(); + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", "Agent removed"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(REMOVE_DONE, u_id); + + restart_necessary = 1; + break; + } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */ + printf(REMOVE_NOT); + break; + } + } while (1); + + return (0); +} + +int list_agents(int cmdlist) +{ + if (!print_agents(0, 0, 0, 0)) { + printf(NO_AGENT); + } + + printf("\n"); + if (!cmdlist) { + printf(PRESS_ENTER); + read_from_user(); + } + + return (0); +} diff --git a/src/addagent/manage_agents.h b/src/addagent/manage_agents.h new file mode 100644 index 000000000..14002054e --- /dev/null +++ b/src/addagent/manage_agents.h @@ -0,0 +1,150 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "sec.h" +#include "external/cJSON/cJSON.h" + +/** Prototypes **/ + +/* b64 function prototypes */ +char *decode_base64(const char *src); +char *encode_base64(int size, char *src); + +/* Read any input from the user (stdin) */ +char *read_from_user(void); + +/* Add or remove an agent */ +int add_agent(int json_output); +int remove_agent(int json_output); + + +/* Extract or import a key */ +int k_extract(const char *cmdextract, int json_output); +int k_import(const char *cmdimport); +int k_bulkload(const char *cmdbulk); + +/* Validation functions */ +int OS_IsValidName(const char *u_name); +int OS_IsValidID(const char *id); +int IDExist(const char *id); +int NameExist(const char *u_name); +char *IPExist(const char *u_name); +char *getFullnameById(const char *id); +char *OS_AddNewAgent(const char *name, const char *ip, const char *id); +int OS_RemoveAgent(const char *id); +double OS_AgentAntiquity(const char *id); +void FormatID(char *id); + +/* Print available agents */ +int print_agents(int print_status, int active_only, int csv_output, cJSON *json_output); +int list_agents(int cmdlist); + +/* Clear a line */ +char *chomp(char *str); + +/* Shared variables */ +extern int restart_necessary; +extern time_t time1; +extern time_t time2; +extern time_t time3; +extern long int rand1; +extern long int rand2; +extern fpos_t fp_pos; + +/* Internal defines */ +#define USER_SIZE 514 +#define FILE_SIZE 257 +#define STR_SIZE 66 + +/* Internal strings */ +#define QUIT "\\q" + +/* Print agents */ +#define PRINT_AVAILABLE "\nAvailable agents: \n" +#define PRINT_AGENT " ID: %s, Name: %s, IP: %s\n" +#define PRINT_AGENT_STATUS " ID: %s, Name: %s, IP: %s, %s\n" + +/* Add new agent */ +#define ADD_NEW "\n- Adding a new agent"\ + " (use '\\q' to return to the main menu).\n"\ + " Please provide the following:\n" +#define ADD_NAME " * A name for the new agent: " +#define ADD_IP " * The IP Address of the new agent: " +#define ADD_ID " * An ID for the new agent[%s]: " +#define AGENT_INFO "Agent information:\n ID:%s\n Name:%s\n " \ + "IP Address:%s\n\n" +#define ADD_CONFIRM "Confirm adding it?(y/n): " +#define AGENT_ADD "Agent added with ID %s.\n" +#define ADDED "Added.\n" +#define ADD_NOT "Not Adding.\n" +#define PRESS_ENTER "** Press ENTER to return to the main menu.\n" +#define MUST_RESTART "\n** You must restart openarmor for your changes" \ + " to take effect.\n\n" + +/* Add errors */ +#define ADD_ERROR_ID "\n** ID '%s' already present. They must be unique.\n\n" +#define ADD_ERROR_NAME "\n** Name '%s' already present. Please enter a new name.\n\n" +#define IP_ERROR "\n** Invalid IP '%s'. Please enter a valid IP Address.\n\n" +#define IP_DUP_ERROR "\n** Duplicated IP '%s'. Please enter an unique IP Address.\n\n" +#define NO_AGENT "\n** No agent available. You need to add one first.\n" +#define NO_ID "\n** Invalid ID '%s' given. ID is not present.\n" +#define NO_KEY "\n** Invalid authentication key. Starting over again.\n" +#define INVALID_ID "\n** Invalid ID '%s' given. ID must be numeric (max 8 digits).\n\n" +#define INVALID_NAME "\n** Invalid name '%s' given. Name must contain only alphanumeric characters (min=2, max=32).\n\n" +#define NO_DEFAULT "\n** Could not get default ID. Ran out of IDs to try with a max of '%d'. Either need to raise max agents or clean out client.keys.\n\n" + +/* Remove agent */ +#define REMOVE_ID "Provide the ID of the agent to be removed (or '\\q' to quit): " +#define REMOVE_CONFIRM "Confirm deleting it?(y/n): " +#define REMOVE_DONE "Agent '%s' removed.\n" +#define REMOVE_NOT "Not removing.\n" + +/* Import agent */ +#define IMPORT_KEY "\n* Provide the Key generated by the server.\n" \ + "* The best approach is to cut and paste it.\n" \ + "*** OBS: Do not include spaces or new lines.\n\n" \ + "Paste it here (or '\\q' to quit): " + +/* Extract key */ +#define EXTRACT_KEY "Provide the ID of the agent to extract " \ + "the key (or '\\q' to quit): " +#define EXTRACT_MSG "\nAgent key information for '%s' is: \n%s\n" + + +/* Common errors */ +#define ERROR_KEYS "Unable to handle keys file. Exiting.\n" +#define EXTRACT_ERROR "Unable to extract agent key.\n" +#define INPUT_LARGE ARGV0 ": Input too large. Not adding it.\n" +#define EXIT ARGV0 ": Exiting.\n" + +#define BANNER "\n****************************************" \ + "\n* %s %s Agent manager. *" \ + "\n* The following options are available: *" \ + "\n****************************************\n" + +#define BANNER_OPT " (A)dd an agent (A).\n" \ + " (E)xtract key for an agent (E).\n" \ + " (L)ist already added agents (L).\n" \ + " (R)emove an agent (R).\n" \ + " (Q)uit.\n" \ + "Choose your action: A,E,L,R or Q: " + +#define BANNER_CLIENT " (I)mport key from the server (I).\n" \ + " (Q)uit.\n" \ + "Choose your action: I or Q: " + +/* WIN32 errors */ +#define CONF_ERROR ARGV0 ": Could not read (%s) (Make sure config exists and executable is running with Administrative privileges).\n" +#define GMF_ERROR ARGV0 ": Could not run GetModuleFileName.\n" +#define GMF_BUFF_ERROR ARGV0 ": Could not get path because it is too long and was shrunk by (%d) characters with a max of (%d).\n" +#define GMF_UNKN_ERROR ARGV0 ": Could not run GetModuleFileName which returned (%ld).\n" + + +//int willchroot; diff --git a/src/addagent/manage_keys.c b/src/addagent/manage_keys.c new file mode 100644 index 000000000..682454dcb --- /dev/null +++ b/src/addagent/manage_keys.c @@ -0,0 +1,484 @@ +/* Copyright (C) 2019 openarmor Foundation + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "manage_agents.h" +#include "os_crypto/md5/md5_op.h" +#include "external/cJSON/cJSON.h" +#include + + +/* Prototypes */ +static char *trimwhitespace(char *str); + + +static char *trimwhitespace(char *str) +{ + char *end; + + /* Trim leading space */ + while (isspace(*str)) { + str++; + } + + if (*str == 0) { /* All spaces? */ + return str; + } + + /* Trim trailing space */ + end = str + strlen(str) - 1; + while (end > str && isspace(*end)) { + end--; + } + + /* Write new null terminator */ + *(end + 1) = 0; + + return str; +} + +/* Import a key */ +int k_import(const char *cmdimport) +{ + FILE *fp; + const char *user_input; + char *b64_dec; + + char *name; + char *ip; + char *tmp_key; + + char line_read[FILE_SIZE + 1]; + + char auth_file_tmp[] = AUTH_FILE; + char *keys_file = basename_ex(auth_file_tmp); + + char tmp_path[strlen(TMP_DIR) + 1 + strlen(keys_file) + 6 + 1]; + + snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, keys_file); + + /* Parse user argument */ + if (cmdimport) { + user_input = cmdimport; + } else { + printf(IMPORT_KEY); + + user_input = getenv("openarmor_AGENT_KEY"); + if (user_input == NULL) { + user_input = read_from_user(); + } + } + + /* Quit */ + if (strcmp(user_input, QUIT) == 0) { + return (0); + } + + b64_dec = decode_base64(user_input); + if (b64_dec == NULL) { + printf(NO_KEY); + printf(PRESS_ENTER); + read_from_user(); + return (0); + } + + memset(line_read, '\0', FILE_SIZE + 1); + strncpy(line_read, b64_dec, FILE_SIZE); + + name = strchr(b64_dec, ' '); + if (name && strlen(line_read) < FILE_SIZE) { + *name = '\0'; + name++; + ip = strchr(name, ' '); + if (ip) { + *ip = '\0'; + ip++; + + tmp_key = strchr(ip, ' '); + if (!tmp_key) { + printf(NO_KEY); + free(b64_dec); + return (0); + } + *tmp_key = '\0'; + + printf("\n"); + printf(AGENT_INFO, b64_dec, name, ip); + + while (1) { + printf(ADD_CONFIRM); + fflush(stdout); + + user_input = getenv("openarmor_ACTION_CONFIRMED"); + if (user_input == NULL) { + user_input = read_from_user(); + } + + if (user_input[0] == 'y' || user_input[0] == 'Y') { + if (mkstemp_ex(tmp_path)) { + ErrorExit(MKSTEMP_ERROR, ARGV0, tmp_path, errno, strerror(errno)); + } + +#ifndef WIN32 + if (chmod(tmp_path, 0440) == -1) { + if (unlink(tmp_path)) { + verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno)); + } + + ErrorExit(CHMOD_ERROR, ARGV0, tmp_path, errno, strerror(errno)); + } +#endif + + fp = fopen(tmp_path, "w"); + if (!fp) { + if (unlink(tmp_path)) { + verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno)); + } + + ErrorExit(FOPEN_ERROR, ARGV0, tmp_path, errno, strerror(errno)); + } + fprintf(fp, "%s\n", line_read); + fclose(fp); + + if (rename_ex(tmp_path, KEYS_FILE)) { + if (unlink(tmp_path)) { + verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno)); + } + + ErrorExit(RENAME_ERROR, ARGV0, tmp_path, KEYS_FILE, errno, strerror(errno)); + } + + /* Remove sender counter */ + OS_RemoveCounter("sender"); + + printf(ADDED); + printf(PRESS_ENTER); + read_from_user(); + restart_necessary = 1; + + free(b64_dec); + return (1); + } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */ + printf("%s", ADD_NOT); + + free(b64_dec); + return (0); + } + } + } + } + + printf(NO_KEY); + printf(PRESS_ENTER); + read_from_user(); + + free(b64_dec); + return (0); +} + +/* Extract base64 for a specific agent */ +int k_extract(const char *cmdextract, int json_output) +{ + FILE *fp; + char *user_input; + char *b64_enc; + char line_read[FILE_SIZE + 1]; + char n_id[USER_SIZE + 1]; + cJSON *json_root = NULL; + + if (json_output) + json_root = cJSON_CreateObject(); + + if (cmdextract) { + user_input = strdup(cmdextract); + FormatID(user_input); + + if (!IDExist(user_input)) { + if (json_output) { + char buffer[1024]; + snprintf(buffer, 1023, "Invalid ID '%s' given. ID is not present", user_input); + cJSON_AddNumberToObject(json_root, "error", 70); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(NO_ID, user_input); + exit(1); + } + } else { + if (!print_agents(0, 0, 0, 0)) { + printf(NO_AGENT); + printf(PRESS_ENTER); + read_from_user(); + return (0); + } + + while (1) { + printf(EXTRACT_KEY); + fflush(stdout); + user_input = read_from_user(); + + /* quit */ + if (strcmp(user_input, QUIT) == 0) { + return (0); + } + + FormatID(user_input); + + if (IDExist(user_input)) { + break; + } else { + printf(NO_ID, user_input); + } + + } + } + + /* Try to open the auth file */ + char authfile[257]; + extern int willchroot; + if(willchroot > 0) { + snprintf(authfile, 256, "%s", AUTH_FILE); //XXX + } else { + const char *dir = DEFAULTDIR; + snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX + } + + fp = fopen(authfile, "r"); + if (!fp) { + if (json_output) { + char buffer[1024]; + snprintf(buffer, 1023, "Could not open file '%s' due to [(%d)-(%s)]", AUTH_FILE, errno, strerror(errno)); + cJSON_AddNumberToObject(json_root, "error", 71); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); + + + } + + if (fsetpos(fp, &fp_pos)) { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 72); + cJSON_AddStringToObject(json_root, "description", "Can not set fileposition"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + merror("%s: Can not set fileposition.", ARGV0); + exit(1); + } + + memset(n_id, '\0', USER_SIZE + 1); + strncpy(n_id, user_input, USER_SIZE - 1); + + if (fgets(line_read, FILE_SIZE, fp) == NULL) { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 73); + cJSON_AddStringToObject(json_root, "description", "Unable to handle keys file"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(ERROR_KEYS); + + + exit(1); + } + chomp(line_read); + + b64_enc = encode_base64(strlen(line_read), line_read); + if (b64_enc == NULL) { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 74); + cJSON_AddStringToObject(json_root, "description", "Unable to extract agent key"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(EXTRACT_ERROR); + exit(1); + } + + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", b64_enc); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(EXTRACT_MSG, n_id, b64_enc); + + + if (!cmdextract) { + printf("\n" PRESS_ENTER); + read_from_user(); + } + + free(b64_enc); + fclose(fp); + + return (0); +} + +/* Bulk generate client keys from file */ +int k_bulkload(const char *cmdbulk) +{ + int i = 1; + FILE *fp, *infp; + char str1[STR_SIZE + 1]; + char str2[STR_SIZE + 1]; + + os_md5 md1; + os_md5 md2; + char line[FILE_SIZE + 1]; + char name[FILE_SIZE + 1]; + char id[FILE_SIZE + 1]; + char ip[FILE_SIZE + 1]; + char delims[] = ","; + char *token = NULL; + + extern int willchroot; + + /* Check if we can open the input file */ + printf("Opening: [%s]\n", cmdbulk); + infp = fopen(cmdbulk, "r"); + if (!infp) { + perror("Failed."); + ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk, errno, strerror(errno)); + } + + /* Check if we can open the auth_file */ + char authfile[257]; + if(willchroot > 0) { + snprintf(authfile, 256, "%s", AUTH_FILE); //XXX + } else { + const char *dir = DEFAULTDIR; + snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX + } + + fp = fopen(authfile, "a"); + if (!fp) { + ErrorExit(FOPEN_ERROR, ARGV0, authfile, errno, strerror(errno)); + } + fclose(fp); + + while (fgets(line, FILE_SIZE - 1, infp) != NULL) { + os_ip c_ip; + c_ip.ip = NULL; + + if (1 >= strlen(trimwhitespace(line))) { + continue; + } + + memset(ip, '\0', FILE_SIZE + 1); + token = strtok(line, delims); + strncpy(ip, trimwhitespace(token), FILE_SIZE - 1); + + memset(name, '\0', FILE_SIZE + 1); + token = strtok(NULL, delims); + strncpy(name, trimwhitespace(token), FILE_SIZE - 1); + +#ifndef WIN32 + if (chmod(authfile, 0440) == -1) { + ErrorExit(CHMOD_ERROR, ARGV0, authfile, errno, strerror(errno)); + } +#endif + + /* Set time 2 */ + time2 = time(0); + + srandom_init(); + rand1 = random(); + + /* Zero strings */ + memset(str1, '\0', STR_SIZE + 1); + memset(str2, '\0', STR_SIZE + 1); + + /* Check the name */ + if (!OS_IsValidName(name)) { + printf(INVALID_NAME, name); + continue; + } + + /* Search for name -- no duplicates */ + if (NameExist(name)) { + printf(ADD_ERROR_NAME, name); + continue; + } + + if (!OS_IsValidIP(ip, &c_ip)) { + printf(IP_ERROR, ip); + continue; + } + + /* Default ID */ + i = MAX_AGENTS + 32512; + snprintf(id, 8, "%03d", i); + while (!IDExist(id)) { + i--; + snprintf(id, 8, "%03d", i); + + /* No key present, use id 0 */ + if (i <= 0) { + i = 0; + break; + } + } + snprintf(id, 8, "%03d", i + 1); + + if (!OS_IsValidID(id)) { + printf(INVALID_ID, id); + goto cleanup; + } + + /* Search for ID KEY -- no duplicates */ + if (IDExist(id)) { + printf(NO_DEFAULT, i + 1); + goto cleanup; + } + + printf(AGENT_INFO, id, name, ip); + fflush(stdout); + + time3 = time(0); + rand2 = random(); + + fp = fopen(authfile, "a"); + if (!fp) { + ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); + } +#ifndef WIN32 + if (chmod(authfile, 0440) == -1) { + ErrorExit(CHMOD_ERROR, ARGV0, authfile, errno, strerror(errno)); + } +#endif + + /* Random 1: Time took to write the agent information + * Random 2: Time took to choose the action + * Random 3: All of this + time + pid + * Random 4: MD5 all of this + the name, key and IP + * Random 5: Final key + */ + + snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1); + snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2); + + OS_MD5_Str(str1, md1); + OS_MD5_Str(str2, md2); + + snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(), + (int)time3); + OS_MD5_Str(str1, md1); + + fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip.ip, md1, md2); + fclose(fp); + + printf(AGENT_ADD, id); + restart_necessary = 1; + +cleanup: + free(c_ip.ip); + }; + + fclose(infp); + return (0); +} diff --git a/src/addagent/read_from_user.c b/src/addagent/read_from_user.c new file mode 100644 index 000000000..673e832f7 --- /dev/null +++ b/src/addagent/read_from_user.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "manage_agents.h" + +/* Global variables */ +static char __user_buffer[USER_SIZE + 1]; +static char *__user_buffer_pt; + + +char *read_from_user() +{ + memset(__user_buffer, '\0', USER_SIZE + 1); + + if ((fgets(__user_buffer, USER_SIZE - 1, stdin) == NULL) || + (strlen(__user_buffer) >= (USER_SIZE - 2))) { + printf(INPUT_LARGE); + exit(1); + } + + __user_buffer_pt = chomp(__user_buffer); + + return (__user_buffer_pt); +} + diff --git a/src/addagent/validate.c b/src/addagent/validate.c new file mode 100644 index 000000000..39ce6e8f8 --- /dev/null +++ b/src/addagent/validate.c @@ -0,0 +1,648 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include "manage_agents.h" +#include "os_crypto/md5/md5_op.h" + +/* Global variables */ +fpos_t fp_pos; + +/*Number bit of int type*/ +#define INT_BIT_SIZE (sizeof(int)*CHAR_BIT) +/*Enable bit at a position*/ +#define SetBit(Array,pos) ( Array[(pos/INT_BIT_SIZE)] |= (1 << (pos%INT_BIT_SIZE)) ) +/*Check state of bit at a */ +#define TestBit(Array,pos) ( Array[(pos/INT_BIT_SIZE)] & (1 << (pos%INT_BIT_SIZE)) ) + +int *MapIDToBitArray() +{ + FILE *fp; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + int *arrayID; + int max = MAX_AGENTS + AUTHD_FIRST_ID; + if (isChroot()) { + fp = fopen(AUTH_FILE, "r"); + } else { + fp = fopen(KEYSFILE_PATH, "r"); + } + + if (!fp) { + return (NULL); + } + + os_calloc(MAX_AGENTS/INT_BIT_SIZE + 1, sizeof(int), arrayID); + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + char *name; + + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + *name = '\0'; + int name_num=atoi(line_read); + /*Enable bit at ID already allocated*/ + if (name_num >= AUTHD_FIRST_ID && name_num < max) { + SetBit(arrayID, (name_num-AUTHD_FIRST_ID)); + } + } + + } + fclose(fp); + return arrayID; +} + +char *OS_AddNewAgent(const char *name, const char *ip, const char *id) +{ + FILE *fp; + os_md5 md1; + os_md5 md2; + char str1[STR_SIZE + 1]; + char str2[STR_SIZE + 1]; + char *muname; + char *finals; + char nid[9] = { '\0' }; + + srandom_init(); + muname = getuname(); + + snprintf(str1, STR_SIZE, "%d%s%d%s", (int)time(0), name, (int)random(), muname); + snprintf(str2, STR_SIZE, "%s%s%ld", ip, id, (long int)random()); + OS_MD5_Str(str1, md1); + OS_MD5_Str(str2, md2); + + free(muname); + + if (id == NULL) { + int *arrayID; + int i; + arrayID=(int *)MapIDToBitArray(); + if (arrayID != NULL) { + /*Find first item in bit array which is not marked as allocated*/ + for (i=0; i 8) { + return (0); + } + + /* Check ID if it contains only numeric characters [0-9] */ + for (i = 0; i < id_len; i++) { + if (!(isdigit((int)id[i]))) { + return (0); + } + } + + return (1); +} + +/* Get full agent name (name + IP) of ID */ +char *getFullnameById(const char *id) +{ + FILE *fp; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + + /* ID must not be null */ + if (!id) { + return (NULL); + } + + fp = fopen(AUTH_FILE, "r"); + if (!fp) { + return (NULL); + } + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + char *name; + char *ip; + char *tmp_str; + + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + *name = '\0'; + /* Didn't match */ + if (strcmp(line_read, id) != 0) { + continue; + } + + name++; + + /* Removed entry */ + if (*name == '#') { + continue; + } + + ip = strchr(name, ' '); + if (ip) { + *ip = '\0'; + ip++; + + /* Clean up IP */ + tmp_str = strchr(ip, ' '); + if (tmp_str) { + char *final_str; + *tmp_str = '\0'; + tmp_str = strchr(ip, '/'); + if (tmp_str) { + *tmp_str = '\0'; + } + + /* If we reached here, we found the IP and name */ + os_calloc(1, FILE_SIZE, final_str); + snprintf(final_str, FILE_SIZE - 1, "%s-%s", name, ip); + + fclose(fp); + return (final_str); + } + } + } + } + + fclose(fp); + return (NULL); +} + +/* ID Search (is valid ID) */ +int IDExist(const char *id) +{ + FILE *fp; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + + /* ID must not be null */ + if (!id) { + return (0); + } + + if (isChroot()) { + fp = fopen(AUTH_FILE, "r"); + } else { + fp = fopen(KEYSFILE_PATH, "r"); + } + + if (!fp) { + return (0); + } + + fseek(fp, 0, SEEK_SET); + fgetpos(fp, &fp_pos); + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + char *name; + + if (line_read[0] == '#') { + fgetpos(fp, &fp_pos); + continue; + } + + name = strchr(line_read, ' '); + if (name) { + *name = '\0'; + name++; + + if (strcmp(line_read, id) == 0) { + fclose(fp); + return (1); /*(fp_pos);*/ + } + } + + fgetpos(fp, &fp_pos); + } + + fclose(fp); + return (0); +} + +/* Validate agent name */ +int OS_IsValidName(const char *u_name) +{ + size_t i, uname_length = strlen(u_name); + + /* We must have something in the name */ + if (uname_length < 2 || uname_length > 128) { + return (0); + } + + /* Check if it contains any non-alphanumeric characters */ + for (i = 0; i < uname_length; i++) { + if ( !( isalnum((int)u_name[i]) || (u_name[i] == '-') || + (u_name[i] == '_') || (u_name[i] == '.') || + (u_name[i] == ':') ) ) { + return (0); + } + } + + return (1); +} + +int NameExist(const char *u_name) +{ + FILE *fp; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + + if ((!u_name) || + (*u_name == '\0') || + (*u_name == '\r') || + (*u_name == '\n')) { + return (0); + } + + if (isChroot()) { + fp = fopen(AUTH_FILE, "r"); + } else { + fp = fopen(KEYSFILE_PATH, "r"); + } + + if (!fp) { + return (0); + } + + fseek(fp, 0, SEEK_SET); + fgetpos(fp, &fp_pos); + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + char *name; + + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + char *ip; + name++; + + if (*name == '#') { + continue; + } + + ip = strchr(name, ' '); + if (ip) { + *ip = '\0'; + if (strcmp(u_name, name) == 0) { + fclose(fp); + return (1); + } + } + } + fgetpos(fp, &fp_pos); + } + + fclose(fp); + return (0); +} + +/* Returns the ID of an agent, or NULL if not found */ +char *IPExist(const char *u_ip) +{ + FILE *fp; + char *name, *ip, *pass; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + + if (!(u_ip && strncmp(u_ip, "any", 3)) || strchr(u_ip, '/')) + return NULL; + + if (isChroot()) + fp = fopen(AUTH_FILE, "r"); + else + fp = fopen(KEYSFILE_PATH, "r"); + + if (!fp) + return NULL; + + fseek(fp, 0, SEEK_SET); + fgetpos(fp, &fp_pos); + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + name++; + + if (*name == '#') { + continue; + } + + ip = strchr(name, ' '); + if (ip) { + ip++; + + pass = strchr(ip, ' '); + if (pass) { + *pass = '\0'; + if (strcmp(u_ip, ip) == 0) { + fclose(fp); + name[-1] = '\0'; + return strdup(line_read); + } + } + } + } + + fgetpos(fp, &fp_pos); + } + + fclose(fp); + return NULL; +} + +/* Returns the number of seconds since last agent connection, or -1 if error. */ +double OS_AgentAntiquity(const char *id) +{ + struct stat file_stat; + char file_name[OS_FLSIZE]; + char *full_name = getFullnameById(id); + + if (!full_name) { + return -1; + } + + snprintf(file_name, OS_FLSIZE - 1, "%s/%s", AGENTINFO_DIR, full_name); + + if (stat(file_name, &file_stat) < 0) { + if(full_name) { + free(full_name); + } + return -1; + } + + free(full_name); + + return difftime(time(NULL), file_stat.st_mtime); +} + +/* Print available agents */ +int print_agents(int print_status, int active_only, int csv_output, cJSON *json_output) +{ + int total = 0; + FILE *fp; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + + fp = fopen(AUTH_FILE, "r"); + if (!fp) { + return (0); + } + + fseek(fp, 0, SEEK_SET); + + memset(line_read, '\0', FILE_SIZE); + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + char *name; + + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + char *ip; + *name = '\0'; + name++; + + /* Removed agent */ + if (*name == '#') { + continue; + } + + ip = strchr(name, ' '); + if (ip) { + char *key; + *ip = '\0'; + ip++; + key = strchr(ip, ' '); + if (key) { + *key = '\0'; + if (!total && !print_status) { + printf(PRINT_AVAILABLE); + } + total++; + + if (print_status) { + int agt_status = get_agent_status(name, ip); + if (active_only && (agt_status != GA_STATUS_ACTIVE)) { + continue; + } + + if (csv_output) { + printf("%s,%s,%s,%s,\n", line_read, name, ip, print_agent_status(agt_status)); + } else if (json_output) { + cJSON *json_agent = cJSON_CreateObject(); + + if (!json_agent) + return 0; + + cJSON_AddStringToObject(json_agent, "id", line_read); + cJSON_AddStringToObject(json_agent, "name", name); + cJSON_AddStringToObject(json_agent, "ip", ip); + cJSON_AddStringToObject(json_agent, "status", print_agent_status(agt_status)); + cJSON_AddItemToArray(json_output, json_agent); + } else { + printf(PRINT_AGENT_STATUS, line_read, name, ip, print_agent_status(agt_status)); + } + } else { + printf(PRINT_AGENT, line_read, name, ip); + } + } + } + } + } + + /* Only print agentless for non-active only searches */ + if (!active_only && print_status) { + const char *aip = NULL; + DIR *dirp; + struct dirent *dp; + + if (!csv_output && !json_output) { + printf("\nList of agentless devices:\n"); + } + + dirp = opendir(AGENTLESS_ENTRYDIR); + if (dirp) { + while ((dp = readdir(dirp)) != NULL) { + if (strncmp(dp->d_name, ".", 1) == 0) { + continue; + } + + aip = strchr(dp->d_name, '@'); + if (aip) { + aip++; + } else { + aip = ""; + } + + if (csv_output) { + printf("na,%s,%s,agentless,\n", dp->d_name, aip); + } else { + printf(" ID: na, Name: %s, IP: %s, agentless\n", + dp->d_name, aip); + } + } + closedir(dirp); + } + } + + fclose(fp); + if (total) { + return (1); + } + + return (0); +} + +void FormatID(char *id) { + int number; + char *end; + + if (id && *id) { + number = strtol(id, &end, 10); + + if (!*end) { + sprintf(id, "%03d", number); + } + } +} diff --git a/src/agentlessd/README b/src/agentlessd/README new file mode 100644 index 000000000..64b68120a --- /dev/null +++ b/src/agentlessd/README @@ -0,0 +1,26 @@ +Agentless Daemon. + +It will use the connection type specified in the configuration to access +a remote box and do integrity checking or log analysis. + +The connection types are specified at /var/openarmor/agentless . + +Example of config: + + + + + ssh_integrity_check_bsd + 3600 + dcid@127.0.0.1 + periodic + /bin /etc/ /sbin + + + + ssh_integrity_check_linux + 3600 + dcid@192.168.2.15 + periodic + /bin /etc/ /sbin + diff --git a/src/agentlessd/agentlessd.c b/src/agentlessd/agentlessd.c new file mode 100644 index 000000000..5ef8d0318 --- /dev/null +++ b/src/agentlessd/agentlessd.c @@ -0,0 +1,482 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_crypto/md5/md5_op.h" +#include "agentlessd.h" + +/* Prototypes */ +static int save_agentless_entry(const char *host, const char *script, const char *agttype); +static int send_intcheck_msg(const char *script, const char *host, const char *msg); +static int send_log_msg(const char *script, const char *host, const char *msg); +static int gen_diff_alert(const char *host, const char *script, time_t alert_diff_time); +static int check_diff_file(const char *host, const char *script); +static FILE *open_diff_file(const char *host, const char *script); +static int run_periodic_cmd(agentlessd_entries *entry, int test_it); + +/* Global variables */ +agentlessd_config lessdc; + + +/* Save agentless entry for the control tools to gather */ +static int save_agentless_entry(const char *host, const char *script, const char *agttype) +{ + FILE *fp; + char sys_location[1024 + 1]; + + sys_location[1024] = '\0'; + snprintf(sys_location, 1024, "%s/(%s) %s", + AGENTLESS_ENTRYDIRPATH, script, host); + + fp = fopen(sys_location, "w"); + if (fp) { + fprintf(fp, "type: %s\n", agttype); + fclose(fp); + } else { + merror(FOPEN_ERROR, ARGV0, sys_location, errno, strerror(errno)); + } + + return (0); +} + +/* Send integrity checking message */ +static int send_intcheck_msg(const char *script, const char *host, const char *msg) +{ + char sys_location[1024 + 1]; + + sys_location[1024] = '\0'; + snprintf(sys_location, 1024, "(%s) %s->%s", script, host, SYSCHECK); + + if (SendMSG(lessdc.queue, msg, sys_location, SYSCHECK_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((lessdc.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* If we reach here, we can try to send it again */ + SendMSG(lessdc.queue, msg, sys_location, SYSCHECK_MQ); + } + + return (0); +} + +/* Send generic log message */ +static int send_log_msg(const char *script, const char *host, const char *msg) +{ + char sys_location[1024 + 1]; + + sys_location[1024] = '\0'; + snprintf(sys_location, 1024, "(%s) %s->%s", script, host, SYSCHECK); + + if (SendMSG(lessdc.queue, msg, sys_location, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((lessdc.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* If we reach here, we can try to send it again */ + SendMSG(lessdc.queue, msg, sys_location, LOCALFILE_MQ); + } + return (0); +} + +/* Generate diffs alert */ +static int gen_diff_alert(const char *host, const char *script, time_t alert_diff_time) +{ + size_t n; + FILE *fp; + char *tmp_str; + char buf[2048 + 1]; + char diff_alert[4096 + 1]; + + buf[2048] = '\0'; + diff_alert[4096] = '\0'; + + snprintf(buf, 2048, "%s/%s->%s/diff.%d", + DIFF_DIR_PATH, host, script, (int)alert_diff_time); + + fp = fopen(buf, "r"); + if (!fp) { + merror("%s: ERROR: Unable to generate diff alert.", ARGV0); + return (0); + } + + n = fread(buf, 1, 2048 - 1, fp); + if (n <= 0) { + merror("%s: ERROR: Unable to generate diff alert (fread).", ARGV0); + fclose(fp); + return (0); + } else if (n >= 2040) { + /* We need to clear the last newline */ + buf[n] = '\0'; + tmp_str = strrchr(buf, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } else { + /* Weird diff with only one large line */ + buf[256] = '\0'; + } + } else { + buf[n] = '\0'; + } + + n = 0; + + /* Get up to 8 line changes */ + tmp_str = buf; + + while (tmp_str && (*tmp_str != '\0')) { + tmp_str = strchr(tmp_str, '\n'); + if (!tmp_str) { + break; + } else if (n >= 7) { + *tmp_str = '\0'; + break; + } + n++; + tmp_str++; + } + + /* Create alert */ + snprintf(diff_alert, 4096 - 1, "openarmor: agentless: Change detected:\n%s%s", + buf, n >= 7 ? + "\nMore changes.." : + ""); + + snprintf(buf, 1024, "(%s) %s->agentless", script, host); + + if (SendMSG(lessdc.queue, diff_alert, buf, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((lessdc.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* If we reach here, we can try to send it again */ + SendMSG(lessdc.queue, diff_alert, buf, LOCALFILE_MQ); + } + + save_agentless_entry(host, script, "diff"); + + fclose(fp); + return (0); +} + +/* Check if the file has changed */ +static int check_diff_file(const char *host, const char *script) +{ + time_t date_of_change; + char old_location[1024 + 1]; + char new_location[1024 + 1]; + char tmp_location[1024 + 1]; + char diff_cmd[2048 + 1]; + + os_md5 md5sum_old; + os_md5 md5sum_new; + + old_location[1024] = '\0'; + new_location[1024] = '\0'; + tmp_location[1024] = '\0'; + diff_cmd[2048] = '\0'; + + snprintf(new_location, 1024, "%s/%s->%s/%s", DIFF_DIR_PATH, host, script, + DIFF_NEW_FILE); + snprintf(old_location, 1024, "%s/%s->%s/%s", DIFF_DIR_PATH, host, script, + DIFF_LAST_FILE); + + /* If the file is not there, rename new location to last location */ + if (OS_MD5_File(old_location, md5sum_old, OS_TEXT) != 0) { + if (rename(new_location, old_location) != 0) { + merror(RENAME_ERROR, ARGV0, new_location, old_location, errno, strerror(errno)); + } + return (0); + } + + /* Get md5sum of the new file */ + if (OS_MD5_File(new_location, md5sum_new, OS_TEXT) != 0) { + merror("%s: ERROR: Invalid internal state (missing '%s').", + ARGV0, new_location); + return (0); + } + + /* If they match, keep the old file and remove the new */ + if (strcmp(md5sum_new, md5sum_old) == 0) { + if ((unlink(new_location)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", ARGV0, new_location, strerror(errno)); + } + return (0); + } + + /* Save the old file at timestamp and rename new to last */ + date_of_change = File_DateofChange(old_location); + snprintf(tmp_location, 1024, "%s/%s->%s/state.%d", DIFF_DIR_PATH, host, script, + (int)date_of_change); + + if (rename(old_location, tmp_location) != 0) { + merror(RENAME_ERROR, ARGV0, old_location, tmp_location, errno, strerror(errno)); + return (0); + } + if (rename(new_location, old_location) != 0) { + merror(RENAME_ERROR, ARGV0, new_location, old_location, errno, strerror(errno)); + return (0); + } + + /* Run diff */ + date_of_change = File_DateofChange(old_location); + snprintf(diff_cmd, 2048, "diff \"%s\" \"%s\" > \"%s/%s->%s/diff.%d\" " + "2>/dev/null", + tmp_location, old_location, + DIFF_DIR_PATH, host, script, (int)date_of_change); + if (system(diff_cmd) != 256) { + merror("%s: ERROR: Unable to run diff for %s->%s", + ARGV0, host, script); + return (0); + } + + /* Generate alert */ + gen_diff_alert(host, script, date_of_change); + + return (0); +} + +/* Get the diff file */ +static FILE *open_diff_file(const char *host, const char *script) +{ + FILE *fp = NULL; + char sys_location[1024 + 1]; + + sys_location[1024] = '\0'; + snprintf(sys_location, 1024, "%s/%s->%s/%s", DIFF_DIR_PATH, host, script, + DIFF_NEW_FILE); + + fp = fopen(sys_location, "w"); + + /* If we can't open, try creating the directory */ + if (!fp) { + snprintf(sys_location, 1024, "%s/%s->%s", DIFF_DIR_PATH, host, script); + if (IsDir(sys_location) == -1) { + if (mkdir(sys_location, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, sys_location, errno, strerror(errno)); + return (NULL); + } + } + + snprintf(sys_location, 1024, "%s/%s->%s/%s", DIFF_DIR_PATH, host, + script, DIFF_NEW_FILE); + fp = fopen(sys_location, "w"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, sys_location, errno, strerror(errno)); + return (NULL); + } + } + + return (fp); +} + +/* Run periodic commands */ +static int run_periodic_cmd(agentlessd_entries *entry, int test_it) +{ + int i = 0; + char *tmp_str; + char buf[OS_SIZE_2048 + 1]; + char command[OS_SIZE_1024 + 1]; + FILE *fp; + FILE *fp_store = NULL; + + buf[0] = '\0'; + command[0] = '\0'; + command[OS_SIZE_1024] = '\0'; + + while (entry->server[i]) { + /* Ignored entry */ + if (entry->server[i][0] == '\0') { + i++; + continue; + } + + /* We only test for the first server entry */ + else if (test_it) { + int ret_code = 0; + snprintf(command, OS_SIZE_1024, + "%s/%s test test >/dev/null 2>&1", + AGENTLESSDIRPATH, entry->type); + ret_code = system(command); + + /* Check if the test worked */ + if (ret_code != 0) { + if (ret_code == 32512) { + merror("%s: ERROR: Expect command not found (or bad " + "arguments) for '%s'.", + ARGV0, entry->type); + } + merror("%s: ERROR: Test failed for '%s' (%d). Ignoring.", + ARGV0, entry->type, ret_code / 256); + entry->error_flag = 99; + return (-1); + } + + verbose("%s: INFO: Test passed for '%s'.", ARGV0, entry->type); + return (0); + } + + if (entry->server[i][0] == 's') { + snprintf(command, OS_SIZE_1024, "%s/%s \"use_su\" \"%s\" %s 2>&1", + AGENTLESSDIRPATH, entry->type, entry->server[i] + 1, + entry->options); + } else if (entry->server[i][0] == 'o') { + snprintf(command, OS_SIZE_1024, "%s/%s \"use_sudo\" \"%s\" %s 2>&1", + AGENTLESSDIRPATH, entry->type, entry->server[i] + 1, + entry->options); + } else { + snprintf(command, OS_SIZE_1024, "%s/%s \"%s\" %s 2>&1", + AGENTLESSDIRPATH, entry->type, entry->server[i] + 1, + entry->options); + } + + fp = popen(command, "r"); + if (fp) { + while (fgets(buf, OS_SIZE_2048, fp) != NULL) { + /* Remove newlines and carriage returns */ + tmp_str = strchr(buf, '\r'); + if (tmp_str) { + *tmp_str = '\0'; + } + tmp_str = strchr(buf, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + if (strncmp(buf, "ERROR: ", 7) == 0) { + merror("%s: ERROR: %s: %s: %s", ARGV0, + entry->type, entry->server[i] + 1, buf + 7); + entry->error_flag++; + break; + } else if (strncmp(buf, "INFO: ", 6) == 0) { + verbose("%s: INFO: %s: %s: %s", ARGV0, + entry->type, entry->server[i] + 1, buf + 6); + } else if (strncmp(buf, "FWD: ", 4) == 0) { + tmp_str = buf + 5; + send_intcheck_msg(entry->type, entry->server[i] + 1, + tmp_str); + } else if (strncmp(buf, "LOG: ", 4) == 0) { + tmp_str = buf + 5; + send_log_msg(entry->type, entry->server[i] + 1, + tmp_str); + } else if ((entry->state & LESSD_STATE_DIFF) && + (strncmp(buf, "STORE: ", 7) == 0)) { + if (fp_store) { + fclose(fp_store); + } + fp_store = open_diff_file(entry->server[i] + 1, + entry->type); + } else if (fp_store) { + fprintf(fp_store, "%s\n", buf); + } else { + debug1("%s: DEBUG: buffer: %s", ARGV0, buf); + } + } + + if (fp_store) { + fclose(fp_store); + fp_store = NULL; + + check_diff_file(entry->server[i] + 1, entry->type); + } else { + save_agentless_entry(entry->server[i] + 1, + entry->type, "syscheck"); + } + pclose(fp); + } else { + merror("%s: ERROR: popen failed on '%s' for '%s'.", ARGV0, + entry->type, entry->server[i] + 1); + entry->error_flag++; + } + + i++; + } + + if (fp_store) { + fclose(fp_store); + } + + return (0); +} + +/* Main agentlessd */ +void Agentlessd() +{ + time_t tm; + struct tm *p; + + int today = 0; + int test_it = 1; + + char str[OS_SIZE_1024 + 1]; + + /* Wait a few seconds to settle */ + sleep(2); + memset(str, '\0', OS_SIZE_1024 + 1); + + /* Get current time before starting */ + tm = time(NULL); + p = localtime(&tm); + + today = p->tm_mday; + + /* Connect to the message queue. Exit if it fails. */ + if ((lessdc.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + + /* Main monitor loop */ + while (1) { + unsigned int i = 0; + tm = time(NULL); + p = localtime(&tm); + + /* Day changed, deal with log files */ + if (today != p->tm_mday) { + today = p->tm_mday; + } + + while (lessdc.entries[i]) { + if (lessdc.entries[i]->error_flag >= 10) { + if (lessdc.entries[i]->error_flag != 99) { + merror("%s: ERROR: Too many failures for '%s'. Ignoring it.", + ARGV0, lessdc.entries[i]->type); + lessdc.entries[i]->error_flag = 99; + } + + i++; + sleep(i); + continue; + } + + /* Run the check again if the frequency has elapsed */ + if ((lessdc.entries[i]->state & LESSD_STATE_PERIODIC) && + ((lessdc.entries[i]->current_state + + lessdc.entries[i]->frequency) < tm)) { + run_periodic_cmd(lessdc.entries[i], test_it); + if (!test_it) { + lessdc.entries[i]->current_state = tm; + } + } + + i++; + + sleep(i); + } + + /* We only check every minute */ + test_it = 0; + sleep(60); + } +} + diff --git a/src/agentlessd/agentlessd.h b/src/agentlessd/agentlessd.h new file mode 100644 index 000000000..e35f673db --- /dev/null +++ b/src/agentlessd/agentlessd.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _AGENTLESSD_H +#define _AGENTLESSD_H + +#include "config/agentlessd-config.h" + +#ifndef ARGV0 +#define ARGV0 "openarmor-agentlessd" +#endif + +/** Prototypes **/ + +/* Main monitord */ +void Agentlessd(void) __attribute__((noreturn)); + +/* Global variables */ +extern agentlessd_config lessdc; + +#endif + diff --git a/src/agentlessd/main.c b/src/agentlessd/main.c new file mode 100644 index 000000000..0c020e8e5 --- /dev/null +++ b/src/agentlessd/main.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentlessd.h" +#include "config/config.h" + +/* Prototypes */ +static void help_agentlessd(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_agentlessd() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", USER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, test_config = 0, run_foreground = 0; + uid_t uid; + gid_t gid; + const char *dir = DEFAULTDIR; + const char *user = USER; + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_agentlessd(); + break; + case 'd': + nowDebug(); + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_agentlessd(); + break; + } + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Read config */ + c = 0; + c |= CAGENTLESS; + lessdc.entries = NULL; + lessdc.queue = 0; + + if (ReadConfig(c, cfg, &lessdc, NULL) < 0) { + ErrorExit(XML_INV_AGENTLESS, ARGV0); + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + /* Continue in daemon mode */ + if (!run_foreground) { + nowDaemon(); + goDaemonLight(); + } + + if (chdir(dir) == -1) { + ErrorExit(CHDIR_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + /* Exit if not configured */ + if (!lessdc.entries) { + verbose("%s: INFO: Not configured. Exiting.", ARGV0); + exit(0); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Change user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + debug1(CHROOT_MSG, ARGV0, dir); + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real daemon now */ + Agentlessd(); +} + diff --git a/src/agentlessd/scripts/main.exp b/src/agentlessd/scripts/main.exp new file mode 100644 index 000000000..6a38e12b7 --- /dev/null +++ b/src/agentlessd/scripts/main.exp @@ -0,0 +1,96 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +if {$argc <= 1} { + send_user "\nERROR: ssh_integrity_check \n"; + exit 1; +} + +# NOTE: this script must be called from within /var/openarmor for it to work +set passlist "agentless/.passlist" +set sshsrc "agentless/ssh.exp" +set susrc "agentless/su.exp" +set sshloginsrc "agentless/sshlogin.exp" +set sshnopasssrc "agentless/ssh_nopass.exp" +set hostname [lindex $argv 0] +set args [lrange $argv 1 end] +set pass "x" +set use_su " " +set use_sudo " " +set addpass "x" +set timeout 20 + +# Do script test +if {[string compare $hostname "test"] == 0} { + if {[string compare $args "test"] == 0} { + exit 0; + } +} + +# Check if the hostname (first argument) is an option +if {[string compare $hostname "use_su"] == 0} { + set use_su "su;" + set hostname [lindex $argv 1] + set args [lrange $argv 2 end] +} +# Check if the hostname (first argument) is an option +if {[string compare $hostname "use_sudo"] == 0} { + set use_sudo "sudo sh;" + set hostname [lindex $argv 1] + set args [lrange $argv 2 end] +} + +# Read the password list +if [catch { + set in [open "$passlist" r] +} loc_error] { + send_user "\nERROR: Password list not present (use \"register_host\" first).\n" + exit 1; +} + +while {[gets $in line] != -1} { + set me [string first "|" $line] + set me2 [string last "|" $line] + set length [string length $line] + + if {$me == -1} { + continue; + } + if {$me2 == -1} { + continue; + } + if {$me == $me2} { + continue; + } + + set me [expr $me-1] + set me2 [expr $me2-1] + + set host_list [string range $line 0 $me] + set me [expr $me+2] + set pass_list [string range $line $me $me2] + set me2 [expr $me2+2] + set addpass_list [string range $line $me2 $length] + + if {[string compare $host_list $hostname] == 0} { + set pass "$pass_list" + set addpass "$addpass_list" + break + } +} +close $in + + +if {[string compare $pass "x"] == 0} { + send_user "\nERROR: Password for '$hostname' not found.\n" + exit 1; +} diff --git a/src/agentlessd/scripts/register_host.sh b/src/agentlessd/scripts/register_host.sh new file mode 100644 index 000000000..4a14c2b1f --- /dev/null +++ b/src/agentlessd/scripts/register_host.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +MYNAME="register_host.sh" +MYPASS=".passlist" + +# Check the location +ls -la $MYNAME > /dev/null 2>&1 +if [ ! $? = 0 ]; then + LOCALDIR=`dirname $0`; + cd ${LOCALDIR} + + ls -la $MYNAME > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: You must run this script from the same directory." + exit 1; + fi +fi + +# Arguments +if [ "x$1" = "x" -o "x$1" = "xhelp" -o "x$1" = "x-h" ]; then + echo "$0 options:" + echo " add [] ()" + echo " list (passwords)" + exit 0; +fi + +if [ "x$1" = "xlist" ]; then + echo "*Available hosts: " + if [ "x$2" = "xpasswords" ]; then + cat $MYPASS | sort | uniq; + else + cat $MYPASS | cut -d "|" -f 1 | sort | uniq; + fi + exit 0; + +elif [ "x$1" = "xadd" ]; then + if [ "x$2" = "x" ]; then + echo "ERROR: Missing hostname name."; + echo "ex: $0 add [] ()"; + exit 1; + fi + + grep "$2|" $MYPASS > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "ERROR: Host '$2' already added."; + exit 1; + fi + + # Check if the password was supplied + if [ "x$3" = "x" ]; then + echo "Please provide password for host $2." + echo -n "Password: "; + stty -echo + read INPASS + stty echo + + echo "Please provide additional password for host $2 ( for empty)." + echo -n "Password: "; + stty -echo + read ADDPASS + stty echo + else + INPASS=$3 + ADDPASS=$4 + fi + + echo "$2|$INPASS|$ADDPASS" >> $MYPASS; + if [ ! $? = 0 ]; then + echo "ERROR: Unable to creating entry (echo failed)." + exit 1; + fi + chmod 744 $MYPASS + echo "*Host $2 added." + +else + echo "ERROR: Invalid argument."; + exit 1; + +fi + diff --git a/src/agentlessd/scripts/ssh.exp b/src/agentlessd/scripts/ssh.exp new file mode 100644 index 000000000..a99fa973e --- /dev/null +++ b/src/agentlessd/scripts/ssh.exp @@ -0,0 +1,54 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +if {[string compare $pass "NOPASS"] == 0} { + source $sshnopasssrc + return +} + +expect { + "WARNING: REMOTE HOST" { + send_user "\nERROR: RSA host key for '$hostname' has changed. Unable to access.\n" + exit 1; + } + "*sure you want to continue connecting*" { + send "yes\r" + expect "*assword:*" { + send "$pass\r" + source $sshloginsrc + } + } + "ssh: connect to host*" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "no address associated with name" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection refused*" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection closed by remote host*" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*assword:*" { + send "$pass\r" + source $sshloginsrc + } + timeout { + send_user "\nERROR: Timeout while connecting to host: $hostname . \n" + exit 1; + } +} diff --git a/src/agentlessd/scripts/ssh_asa-fwsmconfig_diff b/src/agentlessd/scripts/ssh_asa-fwsmconfig_diff new file mode 100644 index 000000000..bb6b38253 --- /dev/null +++ b/src/agentlessd/scripts/ssh_asa-fwsmconfig_diff @@ -0,0 +1,207 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +if {$argc < 1} { + send_user "ERROR: ssh_asa-fwsmconfig_diff \n"; + send_user "ERROR: Must be run from /var/openarmor\n"; + exit 1; +} + +# NOTE: this script must be called from within /var/openarmor for it to work +set passlist "agentless/.passlist" +set hostname [lindex $argv 0] +set commands [lrange $argv 1 end] +set pass "x" +set addpass "x" +set timeout 20 + +if {[string compare $hostname "test"] == 0} { + if {[string compare $commands "test"] == 0} { + exit 0; + } +} + +# Read the password list +if [catch { + set in [open "$passlist" r] +} loc_error] { + send_user "ERROR: Password list not present (use \"register_host\" first).\n" + exit 1; +} + +while {[gets $in line] != -1} { + set me [string first "|" $line] + set me2 [string last "|" $line] + set length [string length $line] + + if {$me == -1} { + continue; + } + if {$me2 == -1} { + continue; + } + if {$me == $me2} { + continue; + } + + set me [expr $me-1] + set me2 [expr $me2-1] + + set host_list [string range $line 0 $me] + set me [expr $me+2] + set pass_list [string range $line $me $me2] + set me2 [expr $me2+2] + set addpass_list [string range $line $me2 $length] + + if {[string compare $host_list $hostname] == 0} { + set pass "$pass_list" + set addpass "$addpass_list" + break + } +} +close $in + +if {[string compare $pass "x"] == 0} { + send_user "ERROR: Password for '$hostname' not found.\n" + exit 1; +} + +# SSH to the box and pass the directories to check +if [catch { + spawn ssh -c des $hostname +} loc_error] { + send_user "ERROR: Opening connection: $loc_error.\n" + exit 1; +} + +expect { + "WARNING: REMOTE HOST" { + send_user "ERROR: RSA host key for '$hostname' has changed. Unable to access.\n" + exit 1; + } + "*sure you want to continue connecting*" { + send "yes\r" + expect "* password:*" { + send "$pass\r" + + expect { + "Permission denied" { + send_user "ERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n" + exit 1; + } + "*>" { + send_user "\nINFO: Starting.\n" + } + } + } + } + "ssh: connect to host*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "no address associated with name" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection refused*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection closed by remote host*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "* password:*" { + send "$pass\r" + + expect { + "Permission denied" { + send_user "ERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n" + exit 1; + } + "*>" { + send_user "INFO: Starting.\n" + } + } + } + timeout { + send_user "ERROR: Timeout while connecting to host: $hostname . \n" + exit 1; + } +} + +# Go into enable mode +send "enable\r" +expect { + "Password:" { + send "$addpass\r" + + expect { + "*asswor*" { + send_user "ERROR: Incorrect enable password to remote host: $hostname .\n" + exit 1; + } + "*rror in authenticatio*" { + send_user "ERROR: Incorrect enable password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while going to enable mode on host: $hostname .\n" + exit 1; + } + "*#" { + send_user "ok on enable pass\n" + } + } + } + "ERROR*Invalid input detected at" { + send_user "No enable requires\n" + } + timeout { + send_user "ERROR: Timeout while running enable on host: $hostname .\n" + exit 1; + } +} + +# Send commands +set timeout 60 +send_user "\nSTORE: now\n" + +send "term pager 0\r" + +# Exclude uptime from the output +send "show version | grep -v Configuration last| up\r" +send "show running-config\r" +send "$commands\r" +send "exit\r" + +expect { + timeout { + send_user "ERROR: Timeout while running commands on host: $hostname .\n" + exit 1; + } + eof { + send_user "\nINFO: Finished.\n" + exit 0; + } +} + +send_user "ERROR: Unable to finish properly.\n" +exit 1; diff --git a/src/agentlessd/scripts/ssh_foundry_diff b/src/agentlessd/scripts/ssh_foundry_diff new file mode 100644 index 000000000..e7d8f7878 --- /dev/null +++ b/src/agentlessd/scripts/ssh_foundry_diff @@ -0,0 +1,204 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +if {$argc < 1} { + send_user "ERROR: ssh_pixconfig_diff \n"; + exit 1; +} + +# NOTE: this script must be called from within /var/openarmor for it to work +set passlist "agentless/.passlist" +set hostname [lindex $argv 0] +set commands [lrange $argv 1 end] +set pass "x" +set addpass "x" +set timeout 20 + +if {[string compare $hostname "test"] == 0} { + if {[string compare $commands "test"] == 0} { + exit 0; + } +} + +# Read the password list +if [catch { + set in [open "$passlist" r] +} loc_error] { + send_user "ERROR: Password list not present (use \"register_host\" first).\n" + exit 1; +} + +while {[gets $in line] != -1} { + set me [string first "|" $line] + set me2 [string last "|" $line] + set length [string length $line] + + if {$me == -1} { + continue; + } + if {$me2 == -1} { + continue; + } + if {$me == $me2} { + continue; + } + + set me [expr $me-1] + set me2 [expr $me2-1] + + set host_list [string range $line 0 $me] + set me [expr $me+2] + set pass_list [string range $line $me $me2] + set me2 [expr $me2+2] + set addpass_list [string range $line $me2 $length] + + if {[string compare $host_list $hostname] == 0} { + set pass "$pass_list" + set addpass "$addpass_list" + break + } +} +close $in + +if {[string compare $pass "x"] == 0} { + send_user "ERROR: Password for '$hostname' not found.\n" + exit 1; +} + +# SSH to the box and pass the directories to check +if [catch { + spawn ssh $hostname +} loc_error] { + send_user "ERROR: Opening connection: $loc_error.\n" + exit 1; +} + +expect { + "WARNING: REMOTE HOST" { + send_user "ERROR: RSA host key for '$hostname' has changed. Unable to access.\n" + exit 1; + } + "*sure you want to continue connecting*" { + send "yes\r" + expect "* password:*" { + send "$pass\r" + + expect { + "Permission denied" { + send_user "ERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n" + exit 1; + } + "*>" { + send_user "\nINFO: Starting.\n" + } + } + } + } + "ssh: connect to host*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "no address associated with name" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection refused*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection closed by remote host*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "* password:*" { + send "$pass\r" + + expect { + "Permission denied" { + send_user "ERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n" + exit 1; + } + "*>" { + send_user "INFO: Starting.\n" + } + } + } + timeout { + send_user "ERROR: Timeout while connecting to host: $hostname . \n" + exit 1; + } +} + +if {[string compare $addpass ""] != 0} { + # Go into enable mode + send "enable\r" + expect { + "Password:" { + send "$addpass\r" + + expect { + "*asswor*" { + send_user "ERROR: Incorrect enable password to remote host: $hostname .\n" + exit 1; + } + "*rror - incorrect password*" { + send_user "ERROR: Incorrect enable password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while going to enable mode on host: $hostname .\n" + exit 1; + } + "*#" { + send_user "ok on enable pass\n" + } + } + } + timeout { + send_user "ERROR: Timeout while running enable on host: $hostname .\n" + exit 1; + } + } +} + +# Send commands +set timeout 60 +send_user "\nSTORE: now\n" + +send "skip-page-display\r" + +# Exclude uptime from the output +send "sh run\r" +send "$commands\r" +send "exit\rexit\r" + +expect { + timeout { + send_user "ERROR: Timeout while running commands on host: $hostname .\n" + exit 1; + } + eof { + send_user "\nINFO: Finished.\n" + exit 0; + } +} + +send_user "ERROR: Unable to finish properly.\n" +exit 1; diff --git a/src/agentlessd/scripts/ssh_generic_diff b/src/agentlessd/scripts/ssh_generic_diff new file mode 100644 index 000000000..cc984ffa6 --- /dev/null +++ b/src/agentlessd/scripts/ssh_generic_diff @@ -0,0 +1,44 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +# Main script +source "agentless/main.exp" + +# SSH to the box and pass the directories to check +if [catch { + spawn ssh $hostname +} loc_error] { + send_user "ERROR: Opening connection: $loc_error.\n" + exit 1; +} + +source $sshsrc +source $susrc + +set timeout 600 +send_user "INFO: Starting.\n" +send_user "\nSTORE: now\n" +send "$args\r" +send "exit\r" + +expect { + timeout { + send_user "ERROR: Timeout while running commands on host: $hostname .\n" + exit 1; + } + eof { + send_user "\nINFO: Finished.\n" + exit 0; + } +} + +exit 0; diff --git a/src/agentlessd/scripts/ssh_integrity_check_bsd b/src/agentlessd/scripts/ssh_integrity_check_bsd new file mode 100644 index 000000000..658d1a5a0 --- /dev/null +++ b/src/agentlessd/scripts/ssh_integrity_check_bsd @@ -0,0 +1,42 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +# Main script +source "agentless/main.exp" + +# SSH to the box and pass the directories to check +if [catch { + spawn ssh $hostname +} loc_error] { + send_user "\nERROR: Opening connection: $loc_error.\n" + exit 1; +} + +source $sshsrc +source $susrc + +set timeout 600 +send "for i in `find $args 2>/dev/null`;do tail \$i >/dev/null 2>&1 && md5=`md5 \$i | cut -d \"=\" -f 2|cut -d \" \" -f 2` && sha1=`sha1 \$i | cut -d \"=\" -f 2|cut -d \" \" -f 2` && echo FWD: `stat -f \"%Dz:%Dp:%Du:%Dg\" \$i`:\$md5:\$sha1 \$i; done; exit\r" +send "exit\r" + +expect { + timeout { + send_user "\nERROR: Timeout while running commands on host: $hostname .\n" + exit 1; + } + eof { + send_user "\nINFO: Finished.\n" + exit 0; + } +} + +exit 0; diff --git a/src/agentlessd/scripts/ssh_integrity_check_linux b/src/agentlessd/scripts/ssh_integrity_check_linux new file mode 100644 index 000000000..51b5796f3 --- /dev/null +++ b/src/agentlessd/scripts/ssh_integrity_check_linux @@ -0,0 +1,42 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +# Main script +source "agentless/main.exp" + +# SSH to the box and pass the directories to check +if [catch { + spawn ssh $hostname +} loc_error] { + send_user "ERROR: Opening connection: $loc_error.\n" + exit 1; +} + +source $sshsrc +source $susrc + +set timeout 600 +send "unset HISTFILE echo \"INFO: Starting.\"; for i in `find $args 2>/dev/null`;do tail \$i >/dev/null 2>&1 && md5=`md5sum \$i | cut -d \" \" -f 1` && sha1=`sha1sum \$i | cut -d \" \" -f 1` && echo FWD: `stat --printf \"%s:%a:%u:%g\" \$i`:\$md5:\$sha1 \$i; done; exit\r" +send "exit\r" + +expect { + timeout { + send_user "ERROR: Timeout while running commands on host: $hostname .\n" + exit 1; + } + eof { + send_user "\nINFO: Finished.\n" + exit 0; + } +} + +exit 0; diff --git a/src/agentlessd/scripts/ssh_nopass.exp b/src/agentlessd/scripts/ssh_nopass.exp new file mode 100644 index 000000000..d4eb3d93c --- /dev/null +++ b/src/agentlessd/scripts/ssh_nopass.exp @@ -0,0 +1,53 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +expect { + "WARNING: REMOTE HOST" { + send_user "\nERROR: RSA host key for '$hostname' has changed. Unable to access.\n" + exit 1; + } + "*sure you want to continue connecting*" { + send "yes\r" + source $sshnopasssrc + return + } + "ssh: connect to host*" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "no address associated with name" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection refused*" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection closed by remote host*" { + send_user "\nERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "* password:*" { + send_user "\nERROR: Public key authentication failed to host: $hostname .\n" + exit 1 + } + "*\\\$" { + send_user "\nINFO: Started.\n" + } + "*#" { + send_user "\nINFO: Started.\n" + } + timeout { + send_user "\nERROR: Timeout while connecting to host: $hostname . \n" + exit 1; + } +} diff --git a/src/agentlessd/scripts/ssh_pixconfig_diff b/src/agentlessd/scripts/ssh_pixconfig_diff new file mode 100644 index 000000000..38c110c5a --- /dev/null +++ b/src/agentlessd/scripts/ssh_pixconfig_diff @@ -0,0 +1,205 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +if {$argc < 1} { + send_user "ERROR: ssh_pixconfig_diff \n"; + exit 1; +} + +# NOTE: this script must be called from within /var/openarmor for it to work +set passlist "agentless/.passlist" +set hostname [lindex $argv 0] +set commands [lrange $argv 1 end] +set pass "x" +set addpass "x" +set timeout 20 + +if {[string compare $hostname "test"] == 0} { + if {[string compare $commands "test"] == 0} { + exit 0; + } +} + +# Read the password list +if [catch { + set in [open "$passlist" r] +} loc_error] { + send_user "ERROR: Password list not present (use \"register_host\" first).\n" + exit 1; +} + +while {[gets $in line] != -1} { + set me [string first "|" $line] + set me2 [string last "|" $line] + set length [string length $line] + + if {$me == -1} { + continue; + } + if {$me2 == -1} { + continue; + } + if {$me == $me2} { + continue; + } + + set me [expr $me-1] + set me2 [expr $me2-1] + + set host_list [string range $line 0 $me] + set me [expr $me+2] + set pass_list [string range $line $me $me2] + set me2 [expr $me2+2] + set addpass_list [string range $line $me2 $length] + + if {[string compare $host_list $hostname] == 0} { + set pass "$pass_list" + set addpass "$addpass_list" + break + } +} +close $in + +if {[string compare $pass "x"] == 0} { + send_user "ERROR: Password for '$hostname' not found.\n" + exit 1; +} + +# SSH to the box and pass the directories to check +if [catch { + spawn ssh -c des $hostname +} loc_error] { + send_user "ERROR: Opening connection: $loc_error.\n" + exit 1; +} + +expect { + "WARNING: REMOTE HOST" { + send_user "ERROR: RSA host key for '$hostname' has changed. Unable to access.\n" + exit 1; + } + "*sure you want to continue connecting*" { + send "yes\r" + expect "* password:*" { + send "$pass\r" + + expect { + "Permission denied" { + send_user "ERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n" + exit 1; + } + "*>" { + send_user "\nINFO: Starting.\n" + } + } + } + } + "ssh: connect to host*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "no address associated with name" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection refused*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Connection closed by remote host*" { + send_user "ERROR: Unable to connect to remote host: $hostname .\n" + exit 1; + } + "*Password:*" { + send "$pass\r" + + expect { + "Permission denied" { + send_user "ERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n" + exit 1; + } + "*>" { + send_user "INFO: Starting.\n" + } + } + } + timeout { + send_user "ERROR: Timeout while connecting to host: $hostname . \n" + exit 1; + } +} + +# Go into enable mode +send "enable\r" +expect { + "Password:" { + send "$addpass\r" + + expect { + "*asswor*" { + send_user "ERROR: Incorrect enable password to remote host: $hostname .\n" + exit 1; + } + "*rror in authenticatio*" { + send_user "ERROR: Incorrect enable password to remote host: $hostname .\n" + exit 1; + } + timeout { + send_user "ERROR: Timeout while going to enable mode on host: $hostname .\n" + exit 1; + } + "*#" { + send_user "ok on enable pass\n" + } + } + } + timeout { + send_user "ERROR: Timeout while running enable on host: $hostname .\n" + exit 1; + } +} + +# Send commands +set timeout 60 +send_user "\nSTORE: now\n" + +send "no pager\r" +send "term len 0\r" +send "terminal pager 0\r" + +# Exclude uptime from the output +send "show version | grep -v Configuration last| up\r" +send "show running-config\r" +send "$commands\r" +send "exit\r" + +expect { + timeout { + send_user "ERROR: Timeout while running commands on host: $hostname .\n" + exit 1; + } + eof { + send_user "\nINFO: Finished.\n" + exit 0; + } +} + +send_user "ERROR: Unable to finish properly.\n" +exit 1; diff --git a/src/agentlessd/scripts/sshlogin.exp b/src/agentlessd/scripts/sshlogin.exp new file mode 100644 index 000000000..4d4121c41 --- /dev/null +++ b/src/agentlessd/scripts/sshlogin.exp @@ -0,0 +1,32 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +expect { + "Permission denied" { + send_user "\nERROR: Incorrect password to remote host: $hostname .\n" + exit 1; + } + eof { + send_user "\nERROR: EOF while logging to host: $hostname .\n" + exit 0; + } + timeout { + send_user "\nERROR: Timeout while running on host: $hostname .\n" + exit 1; + } + "*\\\$" { + send_user "\nINFO: Started.\n" + } + "*#" { + send_user "\nINFO: Started.\n" + } +} diff --git a/src/agentlessd/scripts/su.exp b/src/agentlessd/scripts/su.exp new file mode 100644 index 000000000..923c629d5 --- /dev/null +++ b/src/agentlessd/scripts/su.exp @@ -0,0 +1,55 @@ +#!/usr/bin/env expect + +# Agentless monitoring +# +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + +# If su was chosen +set timeout 10 +if {[string compare $use_su "su;"] == 0} { + + # Run su command + send "\rsu\r" + + expect { + "Password:" { + send "$addpass\r" + } + timeout { + send_user "\nERROR: Unable to run su.\n" + exit 1; + } + } + + expect { + "Permission denied" { + send_user "\nERROR: Incorrect su password to host: $hostname .\n" + exit 1; + } + "Password:" { + send_user "\nERROR: Incorrect su password to host: $hostname .\n" + exit 1; + } + "Sorry" { + send_user "\nERROR: Incorrect su password to remote host: $hostname .\n" + exit 1; + } + eof { + send_user "\nERROR: EOF while running su on host: $hostname .\n" + exit 1; + } + timeout { + send_user "\nERROR: Timeout while running on host: $hostname .\n" + exit 1; + } + "*#" { + send_user "\nINFO: su accepted.\n" + } + } +} diff --git a/src/analysisd/accumulator.c b/src/analysisd/accumulator.c new file mode 100644 index 000000000..e35d9bbb5 --- /dev/null +++ b/src/analysisd/accumulator.c @@ -0,0 +1,339 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Accumulator Functions which accumulate objects based on an ID */ + +#include + +#include "shared.h" +#include "accumulator.h" +#include "eventinfo.h" + +/* Local variables */ +static OSHash *acm_store = NULL; + +/* Counters for Purging */ +static int acm_lookups = 0; +static time_t acm_purge_ts = 0; + +/* Accumulator Constants */ +#define OS_ACM_EXPIRE_ELM 120 +#define OS_ACM_PURGE_INTERVAL 300 +#define OS_ACM_PURGE_COUNT 200 + +/* Accumulator Max Values */ +#define OS_ACM_MAXKEY 256 +#define OS_ACM_MAXELM 81 + +typedef struct _OS_ACM_Store { + time_t timestamp; + char *dstuser; + char *srcuser; + char *dstip; + char *srcip; + char *dstport; + char *srcport; + char *data; +} OS_ACM_Store; + +/* Internal Functions */ +static int acm_str_replace(char **dst, const char *src); +static OS_ACM_Store *InitACMStore(void); +static void FreeACMStore(OS_ACM_Store *obj); + +/* Start the Accumulator module */ +int Accumulate_Init() +{ + struct timeval tp; + + /* Create store data */ + acm_store = OSHash_Create(); + if (!acm_store) { + merror(LIST_ERROR, ARGV0); + return (0); + } + if (!OSHash_setSize(acm_store, 2048)) { + merror(LIST_ERROR, ARGV0); + return (0); + } + + /* Default Expiry */ + gettimeofday(&tp, NULL); + acm_purge_ts = tp.tv_sec; + + debug1("%s: DEBUG: Accumulator Init completed.", ARGV0); + return (1); +} + +/* Accumulate data from events sharing the same ID */ +Eventinfo *Accumulate(Eventinfo *lf) +{ + int result; + int do_update = 0; + + char _key[OS_ACM_MAXKEY]; + OS_ACM_Store *stored_data = 0; + + time_t current_ts; + struct timeval tp; + + if ( lf == NULL ) { + debug1("accumulator: DEBUG: Received NULL EventInfo"); + return lf; + } + if ( lf->id == NULL ) { + debug2("accumulator: DEBUG: No id available"); + return lf; + } + if ( lf->decoder_info == NULL ) { + debug1("accumulator: DEBUG: No decoder_info available"); + return lf; + } + if ( lf->decoder_info->name == NULL ) { + debug1("accumulator: DEBUG: No decoder name available"); + return lf; + } + + /* Purge the cache as needed */ + Accumulate_CleanUp(); + + gettimeofday(&tp, NULL); + current_ts = tp.tv_sec; + + /* Accumulator Key */ + result = snprintf(_key, OS_FLSIZE, "%s %s %s", + lf->hostname, + lf->decoder_info->name, + lf->id + ); + if ( result < 0 || (unsigned) result >= sizeof(_key) ) { + debug1("accumulator: DEBUG: error setting accumulator key, id:%s,name:%s", lf->id, lf->decoder_info->name); + return lf; + } + + /* Check if acm is already present */ + if ((stored_data = (OS_ACM_Store *)OSHash_Get(acm_store, _key)) != NULL) { + debug2("accumulator: DEBUG: Lookup for '%s' found a stored value!", _key); + + if ( stored_data->timestamp > 0 && stored_data->timestamp < current_ts - OS_ACM_EXPIRE_ELM ) { + if ( OSHash_Delete(acm_store, _key) != NULL ) { + debug1("accumulator: DEBUG: Deleted expired hash entry for '%s'", _key); + /* Clear this memory */ + FreeACMStore(stored_data); + /* Reallocate what we need */ + stored_data = InitACMStore(); + } + } else { + /* Update the event */ + do_update = 1; + if (acm_str_replace(&lf->dstuser, stored_data->dstuser) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->dstuser to %s", _key, lf->dstuser); + } + + if (acm_str_replace(&lf->srcuser, stored_data->srcuser) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->srcuser to %s", _key, lf->srcuser); + } + + if (acm_str_replace(&lf->dstip, stored_data->dstip) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->dstip to %s", _key, lf->dstip); + } + + if (acm_str_replace(&lf->srcip, stored_data->srcip) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->srcip to %s", _key, lf->srcip); + } + + if (acm_str_replace(&lf->dstport, stored_data->dstport) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->dstport to %s", _key, lf->dstport); + } + + if (acm_str_replace(&lf->srcport, stored_data->srcport) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->srcport to %s", _key, lf->srcport); + } + + if (acm_str_replace(&lf->data, stored_data->data) == 0) { + debug2("accumulator: DEBUG: (%s) updated lf->data to %s", _key, lf->data); + } + } + } else { + stored_data = InitACMStore(); + } + + /* Store the object in the cache */ + stored_data->timestamp = current_ts; + if (acm_str_replace(&stored_data->dstuser, lf->dstuser) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->dstuser to %s", _key, stored_data->dstuser); + } + + if (acm_str_replace(&stored_data->srcuser, lf->srcuser) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->srcuser to %s", _key, stored_data->srcuser); + } + + if (acm_str_replace(&stored_data->dstip, lf->dstip) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->dstip to %s", _key, stored_data->dstip); + } + + if (acm_str_replace(&stored_data->srcip, lf->srcip) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->srcip to %s", _key, stored_data->srcip); + } + + if (acm_str_replace(&stored_data->dstport, lf->dstport) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->dstport to %s", _key, stored_data->dstport); + } + + if (acm_str_replace(&stored_data->srcport, lf->srcport) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->srcport to %s", _key, stored_data->srcport); + } + + if (acm_str_replace(&stored_data->data, lf->data) == 0) { + debug2("accumulator: DEBUG: (%s) updated stored_data->data to %s", _key, stored_data->data); + } + + /* Update or Add to the hash */ + if ( do_update == 1 ) { + /* Update the hash entry */ + if ( (result = OSHash_Update(acm_store, _key, stored_data)) != 1) { + verbose("accumulator: ERROR: Update of stored data for %s failed (%d).", _key, result); + } else { + debug1("accumulator: DEBUG: Updated stored data for %s", _key); + } + } else { + if ((result = OSHash_Add(acm_store, _key, stored_data)) != 2 ) { + verbose("accumulator: ERROR: Addition of stored data for %s failed (%d).", _key, result); + } else { + debug1("accumulator: DEBUG: Added stored data for %s", _key); + } + } + + return lf; +} + +void Accumulate_CleanUp() +{ + struct timeval tp; + time_t current_ts = 0; + int expired = 0; + + OSHashNode *curr; + OS_ACM_Store *stored_data; + char *key; + unsigned int ti; + + /* Keep track of how many times we're called */ + acm_lookups++; + + gettimeofday(&tp, NULL); + current_ts = tp.tv_sec; + + /* Do we really need to purge? */ + if ( acm_lookups < OS_ACM_PURGE_COUNT && acm_purge_ts < current_ts + OS_ACM_PURGE_INTERVAL ) { + return; + } + debug1("accumulator: DEBUG: Accumulator_CleanUp() running .. "); + + /* Yes, we do */ + acm_lookups = 0; + acm_purge_ts = current_ts; + + /* Loop through the hash */ + for ( ti = 0; ti < acm_store->rows; ti++ ) { + curr = acm_store->table[ti]; + while ( curr != NULL ) { + /* Get the Key and Data */ + key = (char *) curr->key; + stored_data = (OS_ACM_Store *) curr->data; + /* Increment to the next element */ + curr = curr->next; + + debug2("accumulator: DEBUG: CleanUp() evaluating cached key: %s ", key); + /* Check for a valid element */ + if ( stored_data != NULL ) { + /* Check for expiration */ + debug2("accumulator: DEBUG: CleanUp() elm:%ld, curr:%ld", (long int)stored_data->timestamp, (long int)current_ts); + if ( stored_data->timestamp < current_ts - OS_ACM_EXPIRE_ELM ) { + debug2("accumulator: DEBUG: CleanUp() Expiring '%s'", key); + if ( OSHash_Delete(acm_store, key) != NULL ) { + FreeACMStore(stored_data); + expired++; + } else { + debug1("accumulator: DEBUG: CleanUp() failed to find key '%s'", key); + } + } + } + } + } + debug1("accumulator: DEBUG: Expired %d elements", expired); +} + +/* Initialize a storage object */ +OS_ACM_Store *InitACMStore() +{ + OS_ACM_Store *obj; + os_calloc(1, sizeof(OS_ACM_Store), obj); + + obj->timestamp = 0; + obj->srcuser = NULL; + obj->dstuser = NULL; + obj->srcip = NULL; + obj->dstip = NULL; + obj->srcport = NULL; + obj->dstport = NULL; + obj->data = NULL; + + return obj; +} + +/* Free an accumulation store struct */ +void FreeACMStore(OS_ACM_Store *obj) +{ + if ( obj != NULL ) { + debug2("accumulator: DEBUG: Freeing an accumulator struct."); + free(obj->dstuser); + free(obj->srcuser); + free(obj->dstip); + free(obj->srcip); + free(obj->dstport); + free(obj->srcport); + free(obj->data); + free(obj); + } +} + +int acm_str_replace(char **dst, const char *src) +{ + int result = 0; + + /* Don't overwrite with a null str */ + if ( src == NULL ) { + return -1; + } + + /* Don't overwrite something we already know */ + if (*dst != NULL && **dst != '\0') { + return -1; + } + + /* Make sure we have data to write */ + size_t slen = strlen(src); + if ( slen <= 0 || slen > OS_ACM_MAXELM - 1 ) { + return -1; + } + + /* Free dst, and malloc the memory we need! */ + if ( *dst != NULL ) { + free(*dst); + } + os_malloc(slen + 1, *dst); + + result = strcpy(*dst, src) == NULL ? -1 : 0; + if (result < 0) { + debug1("accumulator: DEBUG: error in acm_str_replace()"); + } + return result; +} + diff --git a/src/analysisd/accumulator.h b/src/analysisd/accumulator.h new file mode 100644 index 000000000..8c0cc34a5 --- /dev/null +++ b/src/analysisd/accumulator.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __ACCUMULATOR_H +#define __ACCUMULATOR_H + +#include "eventinfo.h" + +/* Accumulator Functions */ +int Accumulate_Init(void); +Eventinfo *Accumulate(Eventinfo *lf); +void Accumulate_CleanUp(void); + +#endif /* __ACCUMULATOR_H */ + diff --git a/src/analysisd/active-response.c b/src/analysisd/active-response.c new file mode 100644 index 000000000..fc8e908ae --- /dev/null +++ b/src/analysisd/active-response.c @@ -0,0 +1,62 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "active-response.h" + +/* Active response commands */ +static OSList *ar_commands; +OSList *active_responses; + +/* Initialize active response */ +void AR_Init() +{ + ar_commands = OSList_Create(); + active_responses = OSList_Create(); + ar_flag = 0; + + if (!ar_commands || !active_responses) { + ErrorExit(LIST_ERROR, ARGV0); + } +} + +/* Read active response configuration and write it + * to the appropriate lists. + */ +int AR_ReadConfig(const char *cfgfile) +{ + FILE *fp; + int modules = 0; + + modules |= CAR; + + /* Clean ar file */ + fp = fopen(DEFAULTARPATH, "w"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH, errno, strerror(errno)); + return (OS_INVALID); + } + fprintf(fp, "restart-openarmor0 - restart-openarmor.sh - 0\n"); + fprintf(fp, "restart-openarmor0 - restart-openarmor.cmd - 0\n"); + fclose(fp); + + /* Set right permission */ + if (chmod(DEFAULTARPATH, 0440) == -1) { + merror(CHMOD_ERROR, ARGV0, DEFAULTARPATH, errno, strerror(errno)); + return (OS_INVALID); + } + + /* Read configuration */ + if (ReadConfig(modules, cfgfile, ar_commands, active_responses) < 0) { + return (OS_INVALID); + } + + return (0); +} + diff --git a/src/analysisd/active-response.h b/src/analysisd/active-response.h new file mode 100644 index 000000000..6fb51a2be --- /dev/null +++ b/src/analysisd/active-response.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _AR__H +#define _AR__H + +#include "config/active-response.h" +#include "config/config.h" +#include "list_op.h" + +/* Initialize active response */ +void AR_Init(void); + +/* Read active response configuration and write it + * to the appropriate lists. + */ +int AR_ReadConfig(const char *cfgfile); + +/* Active response information */ +extern OSList *active_responses; + +#endif /* _AR__H */ + diff --git a/src/analysisd/alerts/alerts.h b/src/analysisd/alerts/alerts.h new file mode 100644 index 000000000..f5644a5a5 --- /dev/null +++ b/src/analysisd/alerts/alerts.h @@ -0,0 +1,20 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Global alert header */ + +#ifndef _ALERT__H +#define _ALERT__H + +#include "log.h" +#include "exec.h" +#include "getloglocation.h" + +#endif + diff --git a/src/analysisd/alerts/exec.c b/src/analysisd/alerts/exec.c new file mode 100644 index 000000000..1c2021314 --- /dev/null +++ b/src/analysisd/alerts/exec.c @@ -0,0 +1,159 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rules.h" +#include "alerts.h" +#include "config.h" +#include "active-response.h" +#include "os_net/os_net.h" +#include "os_regex/os_regex.h" +#include "os_execd/execd.h" +#include "eventinfo.h" + + +void OS_Exec(int execq, int arq, const Eventinfo *lf, const active_response *ar) +{ + char exec_msg[OS_SIZE_1024 + 1]; + const char *ip; + const char *user; + char *filename = NULL; + + ip = user = "-"; + + /* Clean the IP */ + if (lf->srcip && (ar->ar_cmd->expect & SRCIP)) { + if (strncmp(lf->srcip, "::ffff:", 7) == 0) { + ip = lf->srcip + 7; + } else { + ip = lf->srcip; + } + + /* Check if IP is to be ignored */ + if (Config.allow_list) { + if (OS_IPFoundList(ip, Config.allow_list)) { + return; + } + } + + /* Check if it is a hostname */ + if (Config.hostname_allow_list) { + size_t srcip_size; + char **wl; + + srcip_size = strlen(ip); + + wl = Config.hostname_allow_list; + while (*wl) { + if (strncmp(*wl, ip, srcip_size) == 0) { + return; + } + wl++; + } + } + } + + /* Get username */ + if (lf->dstuser && (ar->ar_cmd->expect & USERNAME)) { + user = lf->dstuser; + } + + /* Get filename */ + if (lf->filename && (ar->ar_cmd->expect & FILENAME)) { + filename = os_shell_escape(lf->filename); + } + + /* Active Response on the server + * The response must be here if the ar->location is set to AS + * or the ar->location is set to local (REMOTE_AGENT) and the + * event location is from here. + */ + if ((ar->location & AS_ONLY) || + ((ar->location & REMOTE_AGENT) && (lf->location[0] != '(')) ) { + if (!(Config.ar & LOCAL_AR)) { + goto cleanup; + } + + snprintf(exec_msg, OS_SIZE_1024, + "%s %s %s %ld.%ld %d %s %s", + ar->name, + user, + ip, + (long int)lf->time, + __crt_ftell, + lf->generated_rule->sigid, + lf->location, + filename ? filename : "-"); + if (execq < 1) { + merror("%s: Error communicating with execd (q < 1).", ARGV0); + } + + if (OS_SendUnix(execq, exec_msg, 0) < 0) { + merror("%s: Error communicating with execd.", ARGV0); + } + } + + /* Active Response to the forwarder */ + else if ((Config.ar & REMOTE_AR)) { + int rc; + /* If lf->location start with a ( was generated by remote agent and its + * ID is included in lf->location if missing then it must have been + * generated by the local analysisd, so prepend a false id tag */ + if (lf->location[0] == '(') { + snprintf(exec_msg, OS_SIZE_1024, + "%s %c%c%c %s %s %s %s %ld.%ld %d %s %s", + lf->location, + (ar->location & ALL_AGENTS) ? ALL_AGENTS_C : NONE_C, + (ar->location & REMOTE_AGENT) ? REMOTE_AGENT_C : NONE_C, + (ar->location & SPECIFIC_AGENT) ? SPECIFIC_AGENT_C : NONE_C, + ar->agent_id != NULL ? ar->agent_id : "(null)", + ar->name, + user, + ip, + (long int)lf->time, + __crt_ftell, + lf->generated_rule->sigid, + lf->location, + filename); + } else { + snprintf(exec_msg, OS_SIZE_1024, + "(local_source) %s %c%c%c %s %s %s %s %ld.%ld %d %s %s", + lf->location, + (ar->location & ALL_AGENTS) ? ALL_AGENTS_C : NONE_C, + (ar->location & REMOTE_AGENT) ? REMOTE_AGENT_C : NONE_C, + (ar->location & SPECIFIC_AGENT) ? SPECIFIC_AGENT_C : NONE_C, + ar->agent_id != NULL ? ar->agent_id : "(null)", + ar->name, + user, + ip, + (long int)lf->time, + __crt_ftell, + lf->generated_rule->sigid, + lf->location, + filename); + } + + if ((rc = OS_SendUnix(arq, exec_msg, 0)) < 0) { + if (rc == OS_SOCKBUSY) { + merror("%s: AR socket busy.", ARGV0); + } else { + merror("%s: AR socket error (shutdown?).", ARGV0); + } + merror("%s: Error communicating with ar queue (%d).", ARGV0, rc); + } + } + + cleanup: + + /* Clean up Memory */ + free(filename); + + return; +} + diff --git a/src/analysisd/alerts/exec.h b/src/analysisd/alerts/exec.h new file mode 100644 index 000000000..3b8aa02e9 --- /dev/null +++ b/src/analysisd/alerts/exec.h @@ -0,0 +1,19 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _EXEC__H +#define _EXEC__H + +#include "eventinfo.h" +#include "active-response.h" + +void OS_Exec(int execq, int arq, const Eventinfo *lf, const active_response *ar); + +#endif + diff --git a/src/analysisd/alerts/getloglocation.c b/src/analysisd/alerts/getloglocation.c new file mode 100644 index 000000000..014f60c07 --- /dev/null +++ b/src/analysisd/alerts/getloglocation.c @@ -0,0 +1,308 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Get the log directory/file based on the day/month/year */ + +#include "getloglocation.h" +#include "config.h" + +/* Global definitions */ +FILE *_eflog; +FILE *_aflog; +FILE *_fflog; +FILE *_jflog; +FILE *_ejflog; + +/* Global variables */ +static int __crt_day; +static char __elogfile[OS_FLSIZE + 1]; +static char __alogfile[OS_FLSIZE + 1]; +static char __flogfile[OS_FLSIZE + 1]; +static char __jlogfile[OS_FLSIZE + 1]; +static char __ejlogfile[OS_FLSIZE + 1]; + +void OS_InitLog() +{ + OS_InitFwLog(); + + __crt_day = 0; + + /* Alerts and events log file */ + memset(__alogfile, '\0', OS_FLSIZE + 1); + memset(__elogfile, '\0', OS_FLSIZE + 1); + memset(__flogfile, '\0', OS_FLSIZE + 1); + memset(__jlogfile, '\0', OS_FLSIZE + 1); + memset(__ejlogfile, '\0', OS_FLSIZE + 1); + + _eflog = NULL; + _aflog = NULL; + _fflog = NULL; + _jflog = NULL; + _ejflog = NULL; + + /* Set the umask */ + umask(0027); +} + +int OS_GetLogLocation(const Eventinfo *lf) +{ + /* Check what directories to create + * Check if the year directory is there + * If not, create it. Same for the month directory. + */ + + + /* For the events */ + if (_eflog) { + if (ftell(_eflog) == 0) { + if ((unlink(__elogfile)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", ARGV0, __elogfile, strerror(errno)); + } + } + fclose(_eflog); + _eflog = NULL; + } + + snprintf(__elogfile, OS_FLSIZE, "%s/%d/", EVENTS, lf->year); + if (IsDir(__elogfile) == -1) + if (mkdir(__elogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __elogfile, errno, strerror(errno)); + } + + snprintf(__elogfile, OS_FLSIZE, "%s/%d/%s", EVENTS, lf->year, lf->mon); + + if (IsDir(__elogfile) == -1) + if (mkdir(__elogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __elogfile, errno, strerror(errno)); + } + + /* Create the logfile name */ + snprintf(__elogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + EVENTS, + lf->year, + lf->mon, + "archive", + lf->day); + + _eflog = fopen(__elogfile, "a"); + if (!_eflog) { + ErrorExit("%s: Error opening logfile: '%s'", ARGV0, __elogfile); + } + + /* Create a symlink */ + if ((unlink(EVENTS_DAILY)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, EVENTS_DAILY, strerror(errno)); + } + + if (link(__elogfile, EVENTS_DAILY) == -1) { + ErrorExit(LINK_ERROR, ARGV0, __elogfile, EVENTS_DAILY, errno, strerror(errno)); + } + /* For the events in JSON */ + if (Config.logall_json) { + /* Create the json archives logfile name */ + + if (_ejflog) { + if (ftell(_ejflog) == 0) { + if ((unlink(__ejlogfile)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, __ejlogfile, strerror(errno)); + } + } + fclose(_ejflog); + _ejflog = NULL; + } + + snprintf(__ejlogfile, OS_FLSIZE, "%s/%d/", EVENTS, lf->year); + if (IsDir(__ejlogfile) == -1) + if (mkdir(__ejlogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __ejlogfile, errno, strerror(errno)); + } + + snprintf(__ejlogfile, OS_FLSIZE, "%s/%d/%s", EVENTS, lf->year, lf->mon); + + if (IsDir(__ejlogfile) == -1) + if (mkdir(__ejlogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __ejlogfile, errno, strerror(errno)); + } + + + snprintf(__ejlogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.json", + EVENTS, + lf->year, + lf->mon, + "archive", + lf->day); + + _ejflog = fopen(__ejlogfile, "a"); + + if (!_ejflog) { + ErrorExit("%s: Error opening logfile: '%s'", ARGV0, __ejlogfile); + } + + /* Create a symlink */ + if ((unlink(EVENTSJSON_DAILY)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, EVENTSJSON_DAILY, strerror(errno)); + } + + if (link(__ejlogfile, EVENTSJSON_DAILY) == -1) { + ErrorExit(LINK_ERROR, ARGV0, __ejlogfile, EVENTSJSON_DAILY, errno, strerror(errno)); + } + } + + /* For the alerts logs */ + if (_aflog) { + if (ftell(_aflog) == 0) { + if ((unlink(__alogfile)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, __alogfile, strerror(errno)); + } + } + fclose(_aflog); + _aflog = NULL; + } + + snprintf(__alogfile, OS_FLSIZE, "%s/%d/", ALERTS, lf->year); + if (IsDir(__alogfile) == -1) + if (mkdir(__alogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __alogfile, errno, strerror(errno)); + } + + snprintf(__alogfile, OS_FLSIZE, "%s/%d/%s", ALERTS, lf->year, lf->mon); + + if (IsDir(__alogfile) == -1) + if (mkdir(__alogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __alogfile, errno, strerror(errno)); + } + + /* Create the logfile name */ + snprintf(__alogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + ALERTS, + lf->year, + lf->mon, + "alerts", + lf->day); + + _aflog = fopen(__alogfile, "a"); + + if (!_aflog) { + ErrorExit("%s: Error opening logfile: '%s'", ARGV0, __alogfile); + } + + /* Create a symlink */ + if ((unlink(ALERTS_DAILY)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, ALERTS_DAILY, strerror(errno)); + } + + if (link(__alogfile, ALERTS_DAILY) == -1) { + ErrorExit(LINK_ERROR, ARGV0, __alogfile, ALERTS_DAILY, errno, strerror(errno)); + } + + if (Config.jsonout_output) { + + if (_jflog) { + if (ftell(_jflog) == 0) { + if ((unlink(__jlogfile)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, __jlogfile, strerror(errno)); + } + } + fclose(_jflog); + _jflog = NULL; + } + + snprintf(__jlogfile, OS_FLSIZE, "%s/%d/", ALERTS, lf->year); + if (IsDir(__jlogfile) == -1) + if (mkdir(__jlogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __jlogfile, errno, strerror(errno)); + } + + snprintf(__jlogfile, OS_FLSIZE, "%s/%d/%s", ALERTS, lf->year, lf->mon); + + if (IsDir(__jlogfile) == -1) + if (mkdir(__jlogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __jlogfile, errno, strerror(errno)); + } + + + + /* Create the json logfile name */ + snprintf(__jlogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.json", + ALERTS, + lf->year, + lf->mon, + "alerts", + lf->day); + + _jflog = fopen(__jlogfile, "a"); + + if (!_jflog) { + ErrorExit("%s: Error opening logfile: '%s'", ARGV0, __jlogfile); + } + + /* Create a symlink */ + if ((unlink(ALERTSJSON_DAILY)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, ALERTSJSON_DAILY, strerror(errno)); + } + + if (link(__jlogfile, ALERTSJSON_DAILY) == -1) { + ErrorExit(LINK_ERROR, ARGV0, __jlogfile, ALERTSJSON_DAILY, errno, strerror(errno)); + } + + } + + /* For the firewall events */ + if (_fflog) { + if (ftell(_fflog) == 0) { + if ((unlink(__flogfile)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, __flogfile, strerror(errno)); + } + } + fclose(_fflog); + _fflog = NULL; + } + + snprintf(__flogfile, OS_FLSIZE, "%s/%d/", FWLOGS, lf->year); + if (IsDir(__flogfile) == -1) + if (mkdir(__flogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __flogfile, errno, strerror(errno)); + } + + snprintf(__flogfile, OS_FLSIZE, "%s/%d/%s", FWLOGS, lf->year, lf->mon); + + if (IsDir(__flogfile) == -1) + if (mkdir(__flogfile, 0770) == -1) { + ErrorExit(MKDIR_ERROR, ARGV0, __flogfile, errno, strerror(errno)); + } + + /* Create the logfile name */ + snprintf(__flogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + FWLOGS, + lf->year, + lf->mon, + "firewall", + lf->day); + + _fflog = fopen(__flogfile, "a"); + + if (!_fflog) { + ErrorExit("%s: Error opening logfile: '%s'", ARGV0, __flogfile); + } + + /* Create a symlink */ + if ((unlink(FWLOGS_DAILY)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, FWLOGS_DAILY, strerror(errno)); + } + + if (link(__flogfile, FWLOGS_DAILY) == -1) { + ErrorExit(LINK_ERROR, ARGV0, __flogfile, FWLOGS_DAILY, errno, strerror(errno)); + } + + /* Setting the new day */ + __crt_day = lf->day; + + return (0); +} + diff --git a/src/analysisd/alerts/getloglocation.h b/src/analysisd/alerts/getloglocation.h new file mode 100644 index 000000000..8d2f47ded --- /dev/null +++ b/src/analysisd/alerts/getloglocation.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __GETLL_H +#define __GETLL_H + +#include "eventinfo.h" + +/* Start the log location (need to be called before getlog) */ +void OS_InitLog(void); +void OS_InitFwLog(void); + +/* Get the log file based on the date/logtype + * Returns 0 on success or -1 on error + */ +int OS_GetLogLocation(const Eventinfo *lf); + +/* Global declarations */ +extern FILE *_eflog; +extern FILE *_ejflog; +extern FILE *_aflog; +extern FILE *_fflog; +extern FILE *_jflog; + +#endif /* __GETLL_H */ + diff --git a/src/analysisd/alerts/log.c b/src/analysisd/alerts/log.c new file mode 100644 index 000000000..95b6b929d --- /dev/null +++ b/src/analysisd/alerts/log.c @@ -0,0 +1,460 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "log.h" +#include "alerts.h" +#include "getloglocation.h" +#include "rules.h" +#include "eventinfo.h" +#include "config.h" + + +/* Drop/allow patterns */ +static OSMatch FWDROPpm; +static OSMatch FWALLOWpm; + +/* Allow custom alert output tokens */ +typedef enum e_custom_alert_tokens_id { + CUSTOM_ALERT_TOKEN_TIMESTAMP = 0, + CUSTOM_ALERT_TOKEN_FTELL, + CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS, + CUSTOM_ALERT_TOKEN_HOSTNAME, + CUSTOM_ALERT_TOKEN_LOCATION, + CUSTOM_ALERT_TOKEN_RULE_ID, + CUSTOM_ALERT_TOKEN_RULE_LEVEL, + CUSTOM_ALERT_TOKEN_RULE_COMMENT, + CUSTOM_ALERT_TOKEN_SRC_IP, + CUSTOM_ALERT_TOKEN_DST_USER, + CUSTOM_ALERT_TOKEN_FULL_LOG, + CUSTOM_ALERT_TOKEN_RULE_GROUP, + CUSTOM_ALERT_TOKEN_LAST +} CustomAlertTokenID; + +static const char CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LAST][15] = { + { "$TIMESTAMP" }, + { "$FTELL" }, + { "$RULEALERT" }, + { "$HOSTNAME" }, + { "$LOCATION" }, + { "$RULEID" }, + { "$RULELEVEL" }, + { "$RULECOMMENT" }, + { "$SRCIP" }, + { "$DSTUSER" }, + { "$FULLLOG" }, + { "$RULEGROUP" }, +}; + +/* Store the events in a file + * The string must be null terminated and contain + * any necessary new lines, tabs, etc. + */ +void OS_Store(const Eventinfo *lf) +{ + if (strcmp(lf->location, "openarmor-keepalive") == 0) { + return; + } + if (strstr(lf->location, "->openarmor-keepalive") != NULL) { + return; + } + + fprintf(_eflog, + "%d %s %02d %s %s%s%s %s\n", + lf->year, + lf->mon, + lf->day, + lf->hour, + lf->hostname != lf->location ? lf->hostname : "", + lf->hostname != lf->location ? "->" : "", + lf->location, + lf->full_log); + + fflush(_eflog); + return; +} + +void OS_LogOutput(Eventinfo *lf) +{ +#ifdef LIBGEOIP_ENABLED + if (Config.geoipdb_file) { + if (lf->srcip && !lf->srcgeoip) { + lf->srcgeoip = GetGeoInfobyIP(lf->srcip); + } + if (lf->dstip && !lf->dstgeoip) { + lf->dstgeoip = GetGeoInfobyIP(lf->dstip); + } + } +#endif + + printf( + "** Alert %ld.%ld:%s - %s\n" + "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'" + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n", + (long int)lf->time, + __crt_ftell, + lf->generated_rule->alert_opts & DO_MAILALERT ? " mail " : "", + lf->generated_rule->group, + lf->year, + lf->mon, + lf->day, + lf->hour, + lf->hostname != lf->location ? lf->hostname : "", + lf->hostname != lf->location ? "->" : "", + lf->location, + lf->generated_rule->sigid, + lf->generated_rule->level, + lf->generated_rule->comment, + + lf->srcip == NULL ? "" : "\nSrc IP: ", + lf->srcip == NULL ? "" : lf->srcip, + +#ifdef LIBGEOIP_ENABLED + lf->srcgeoip == NULL ? "" : "\nSrc Location: ", + lf->srcgeoip == NULL ? "" : lf->srcgeoip, +#else + "", + "", +#endif + + + + lf->srcport == NULL ? "" : "\nSrc Port: ", + lf->srcport == NULL ? "" : lf->srcport, + + lf->dstip == NULL ? "" : "\nDst IP: ", + lf->dstip == NULL ? "" : lf->dstip, + +#ifdef LIBGEOIP_ENABLED + lf->dstgeoip == NULL ? "" : "\nDst Location: ", + lf->dstgeoip == NULL ? "" : lf->dstgeoip, +#else + "", + "", +#endif + + + + lf->dstport == NULL ? "" : "\nDst Port: ", + lf->dstport == NULL ? "" : lf->dstport, + + lf->dstuser == NULL ? "" : "\nUser: ", + lf->dstuser == NULL ? "" : lf->dstuser, + + lf->full_log); + + /* Print the last events if present */ + if (lf->generated_rule->last_events) { + char **lasts = lf->generated_rule->last_events; + while (*lasts) { + printf("%.1256s\n", *lasts); + lasts++; + } + lf->generated_rule->last_events[0] = NULL; + } + + printf("\n"); + + fflush(stdout); + return; +} + +void OS_Log(Eventinfo *lf) +{ +#ifdef LIBGEOIP_ENABLED + if (Config.geoipdb_file) { + if (lf->srcip && !lf->srcgeoip) { + lf->srcgeoip = GetGeoInfobyIP(lf->srcip); + } + if (lf->dstip && !lf->dstgeoip) { + lf->dstgeoip = GetGeoInfobyIP(lf->dstip); + } + } +#endif + + /* Writing to the alert log file */ + fprintf(_aflog, + "** Alert %ld.%ld:%s - %s\n" + "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'" + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n", + (long int)lf->time, + __crt_ftell, + lf->generated_rule->alert_opts & DO_MAILALERT ? " mail " : "", + lf->generated_rule->group, + lf->year, + lf->mon, + lf->day, + lf->hour, + lf->hostname != lf->location ? lf->hostname : "", + lf->hostname != lf->location ? "->" : "", + lf->location, + lf->generated_rule->sigid, + lf->generated_rule->level, + lf->generated_rule->comment, + + lf->srcip == NULL ? "" : "\nSrc IP: ", + lf->srcip == NULL ? "" : lf->srcip, + +#ifdef LIBGEOIP_ENABLED + lf->srcgeoip == NULL ? "" : "\nSrc Location: ", + lf->srcgeoip == NULL ? "" : lf->srcgeoip, +#else + "", + "", +#endif + + + lf->srcport == NULL ? "" : "\nSrc Port: ", + lf->srcport == NULL ? "" : lf->srcport, + + lf->dstip == NULL ? "" : "\nDst IP: ", + lf->dstip == NULL ? "" : lf->dstip, + +#ifdef LIBGEOIP_ENABLED + lf->dstgeoip == NULL ? "" : "\nDst Location: ", + lf->dstgeoip == NULL ? "" : lf->dstgeoip, +#else + "", + "", +#endif + + + + lf->dstport == NULL ? "" : "\nDst Port: ", + lf->dstport == NULL ? "" : lf->dstport, + + lf->dstuser == NULL ? "" : "\nUser: ", + lf->dstuser == NULL ? "" : lf->dstuser, + + lf->full_log); + + /* Print the last events if present */ + if (lf->generated_rule->last_events) { + char **lasts = lf->generated_rule->last_events; + while (*lasts) { + fprintf(_aflog, "%.1256s\n", *lasts); + lasts++; + } + lf->generated_rule->last_events[0] = NULL; + } + + fprintf(_aflog, "\n"); + fflush(_aflog); + + return; +} + +void OS_CustomLog(const Eventinfo *lf, const char *format) +{ + char *log; + char *tmp_log; + char tmp_buffer[1024]; + + /* Replace all the tokens */ + os_strdup(format, log); + + snprintf(tmp_buffer, 1024, "%ld", (long int)lf->time); + tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_TIMESTAMP], tmp_buffer); + if (log) { + os_free(log); + log = NULL; + } + snprintf(tmp_buffer, 1024, "%ld", __crt_ftell); + log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FTELL], tmp_buffer); + if (tmp_log) { + os_free(tmp_log); + tmp_log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", (lf->generated_rule->alert_opts & DO_MAILALERT) ? "mail " : ""); + tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS], tmp_buffer); + if (log) { + os_free(log); + log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", lf->hostname ? lf->hostname : "None"); + log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_HOSTNAME], tmp_buffer); + if (tmp_log) { + os_free(tmp_log); + tmp_log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", lf->location ? lf->location : "None"); + tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LOCATION], tmp_buffer); + if (log) { + os_free(log); + log = NULL; + } + + snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->sigid); + log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ID], tmp_buffer); + if (tmp_log) { + os_free(tmp_log); + tmp_log = NULL; + } + + snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->level); + tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_LEVEL], tmp_buffer); + if (log) { + os_free(log); + log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", lf->srcip ? lf->srcip : "None"); + log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_SRC_IP], tmp_buffer); + if (tmp_log) { + os_free(tmp_log); + tmp_log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", lf->dstuser ? lf->dstuser : "None"); + + tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_DST_USER], tmp_buffer); + if (log) { + os_free(log); + log = NULL; + } + char *escaped_log; + escaped_log = escape_newlines(lf->full_log); + + log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FULL_LOG], escaped_log ); + if (tmp_log) { + os_free(tmp_log); + tmp_log = NULL; + } + + if (escaped_log) { + os_free(escaped_log); + escaped_log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", lf->generated_rule->comment ? lf->generated_rule->comment : ""); + tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_COMMENT], tmp_buffer); + if (log) { + os_free(log); + log = NULL; + } + + snprintf(tmp_buffer, 1024, "%s", lf->generated_rule->group ? lf->generated_rule->group : ""); + log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_GROUP], tmp_buffer); + if (tmp_log) { + os_free(tmp_log); + tmp_log = NULL; + } + + fprintf(_aflog, "%s", log); + fprintf(_aflog, "\n"); + fflush(_aflog); + + if (log) { + os_free(log); + log = NULL; + } + + return; +} + +void OS_InitFwLog() +{ + /* Initialize fw log regexes */ + if (!OSMatch_Compile(FWDROP, &FWDROPpm, 0)) { + ErrorExit(REGEX_COMPILE, ARGV0, FWDROP, + FWDROPpm.error); + } + + if (!OSMatch_Compile(FWALLOW, &FWALLOWpm, 0)) { + ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW, + FWALLOWpm.error); + } +} + +int FW_Log(Eventinfo *lf) +{ + /* If we don't have the srcip or the + * action, there is no point in going + * forward over here + */ + if (!lf->action || !lf->srcip || !lf->dstip || !lf->srcport || + !lf->dstport || !lf->protocol) { + return (0); + } + + /* Set the actions */ + switch (*lf->action) { + /* discard, drop, deny, */ + case 'd': + case 'D': + /* reject, */ + case 'r': + case 'R': + /* block */ + case 'b': + case 'B': + os_free(lf->action); + os_strdup("DROP", lf->action); + break; + /* Closed */ + case 'c': + case 'C': + /* Teardown */ + case 't': + case 'T': + os_free(lf->action); + os_strdup("CLOSED", lf->action); + break; + /* allow, accept, */ + case 'a': + case 'A': + /* pass/permitted */ + case 'p': + case 'P': + /* open */ + case 'o': + case 'O': + os_free(lf->action); + os_strdup("ALLOW", lf->action); + break; + default: + if (OSMatch_Execute(lf->action, strlen(lf->action), &FWDROPpm)) { + os_free(lf->action); + os_strdup("DROP", lf->action); + } + if (OSMatch_Execute(lf->action, strlen(lf->action), &FWALLOWpm)) { + os_free(lf->action); + os_strdup("ALLOW", lf->action); + } else { + os_free(lf->action); + os_strdup("UNKNOWN", lf->action); + } + break; + } + + /* Log to file */ + fprintf(_fflog, + "%d %s %02d %s %s%s%s %s %s %s:%s->%s:%s\n", + lf->year, + lf->mon, + lf->day, + lf->hour, + lf->hostname != lf->location ? lf->hostname : "", + lf->hostname != lf->location ? "->" : "", + lf->location, + lf->action, + lf->protocol, + lf->srcip, + lf->srcport, + lf->dstip, + lf->dstport); + + fflush(_fflog); + + return (1); +} + diff --git a/src/analysisd/alerts/log.h b/src/analysisd/alerts/log.h new file mode 100644 index 000000000..057633700 --- /dev/null +++ b/src/analysisd/alerts/log.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Basic logging operations */ + +#ifndef __LOG_H +#define __LOG_H + +#include "eventinfo.h" + +#define FWDROP "drop" +#define FWALLOW "accept" + +void OS_LogOutput(Eventinfo *lf); +void OS_Log(Eventinfo *lf); +void OS_CustomLog(const Eventinfo *lf, const char *format); +void OS_Store(const Eventinfo *lf); +int FW_Log(Eventinfo *lf); + +#endif + diff --git a/src/analysisd/analysisd.c b/src/analysisd/analysisd.c new file mode 100644 index 000000000..b47640d06 --- /dev/null +++ b/src/analysisd/analysisd.c @@ -0,0 +1,1729 @@ +/* Copyright (C) 2010-2012 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* openarmor-analysisd + * Responsible for correlation and log decoding + */ + +#ifndef ARGV0 +#define ARGV0 "openarmor-analysisd" +#endif + +#include "shared.h" +#include "alerts/alerts.h" +#include "alerts/getloglocation.h" +#include "os_execd/execd.h" +#include "os_regex/os_regex.h" +#include "os_net/os_net.h" +#include "active-response.h" +#include "config.h" +#include "rules.h" +#include "stats.h" +#include "eventinfo.h" +#include "accumulator.h" +#include "analysisd.h" +#include "fts.h" +#include "cleanevent.h" +#include "dodiff.h" +#include "output/jsonout.h" + +#ifdef PRELUDE_OUTPUT_ENABLED +#include "output/prelude.h" +#endif + +#ifdef ZEROMQ_OUTPUT_ENABLED +#include "output/zeromq.h" +#endif + +#ifdef SQLITE_ENABLED +#include +sqlite3 *conn; +#endif + +#ifdef LIBGEOIP_ENABLED +GeoIP *geoipdb; +#endif + +/** Prototypes **/ +void OS_ReadMSG(int m_queue); +RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node); +static void LoopRule(RuleNode *curr_node, FILE *flog); + +/* For decoders */ +void DecodeEvent(Eventinfo *lf); +int DecodeSyscheck(Eventinfo *lf); +int DecodeRootcheck(Eventinfo *lf); +int DecodeHostinfo(Eventinfo *lf); + +/* For stats */ +static void DumpLogstats(void); + +/** Global definitions **/ +int today; +int thishour; +int prev_year; +char prev_month[4]; +int __crt_hour; +int __crt_wday; +time_t c_time; +char __shost[512]; +OSDecoderInfo *NULL_Decoder; + +/* execd queue */ +static int execdq = 0; + +/* Active response queue */ +static int arq = 0; + +static int hourly_alerts; +static int hourly_events; +static int hourly_syscheck; +static int hourly_firewall; + + +/* Print help statement */ +__attribute__((noreturn)) +static void help_analysisd(void) +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", USER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +#ifndef TESTRULE +int main(int argc, char **argv) +#else +__attribute__((noreturn)) +int main_analysisd(int argc, char **argv) +#endif +{ + int c = 0, m_queue = 0, test_config = 0, run_foreground = 0; + int debug_level = 0; + const char *dir = DEFAULTDIR; + const char *user = USER; + const char *group = GROUPGLOBAL; + uid_t uid; + gid_t gid; + + const char *cfg = DEFAULTCPATH; + + /* Set the name */ + OS_SetName(ARGV0); + + thishour = 0; + today = 0; + prev_year = 0; + memset(prev_month, '\0', 4); + hourly_alerts = 0; + hourly_events = 0; + hourly_syscheck = 0; + hourly_firewall = 0; + +#ifdef LIBGEOIP_ENABLED + geoipdb = NULL; +#endif + + + while ((c = getopt(argc, argv, "Vtdhfu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_analysisd(); + break; + case 'd': + nowDebug(); + debug_level = 1; + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_analysisd(); + break; + } + + } + + /* Check current debug_level + * Command line setting takes precedence + */ + if (debug_level == 0) { + /* Get debug level */ + debug_level = getDefine_Int("analysisd", "debug", 0, 2); + while (debug_level != 0) { + nowDebug(); + debug_level--; + } + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + DEBUG_MSG("%s: DEBUG: Starting on debug mode - %d ", ARGV0, (int)time(0)); + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Found user */ + debug1(FOUND_USER, ARGV0); + + /* Initialize Active response */ + AR_Init(); + if (AR_ReadConfig(cfg) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + debug1(ASINIT, ARGV0); + + /* Read configuration file */ + if (GlobalConf(cfg) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + debug1(READ_CONFIG, ARGV0); + + +#ifdef LIBGEOIP_ENABLED + Config.geoip_jsonout = getDefine_Int("analysisd", "geoip_jsonout", 0, 1); + + /* Opening GeoIP DB */ + if(Config.geoipdb_file) { + geoipdb = GeoIP_open(Config.geoipdb_file, GEOIP_INDEX_CACHE); + if (geoipdb == NULL) + { + merror("%s: ERROR: Unable to open GeoIP database from: %s (disabling GeoIP).", ARGV0, Config.geoipdb_file); + } + } +#endif + + + + /* Fix Config.ar */ + Config.ar = ar_flag; + if (Config.ar == -1) { + Config.ar = 0; + } + + /* Get server's hostname */ + memset(__shost, '\0', 512); + if (gethostname(__shost, 512 - 1) != 0) { + strncpy(__shost, openarmor_SERVER, 512 - 1); + } else { + char *_ltmp; + + /* Remove domain part if available */ + _ltmp = strchr(__shost, '.'); + if (_ltmp) { + *_ltmp = '\0'; + } + } + + /* Continuing in Daemon mode */ + if (!test_config && !run_foreground) { + nowDaemon(); + goDaemon(); + } + +#ifdef PRELUDE_OUTPUT_ENABLED + /* Start prelude */ + if (Config.prelude) { + prelude_start(Config.prelude_profile, argc, argv); + } +#endif + +#ifdef ZEROMQ_OUTPUT_ENABLED + /* Start zeromq */ + if (Config.zeromq_output) { +#if CZMQ_VERSION_MAJOR == 2 + zeromq_output_start(Config.zeromq_output_uri); +#elif CZMQ_VERSION_MAJOR >= 3 + zeromq_output_start(Config.zeromq_output_uri, Config.zeromq_output_client_cert, Config.zeromq_output_server_cert); +#endif + } +#endif + + /* Set the group */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + + Config.decoder_order_size = (size_t)getDefine_Int("analysisd", "decoder_order_size", 8, MAX_DECODER_ORDER_SIZE); + + + /* + * Anonymous Section: Load rules, decoders, and lists + * + * As lists require two-pass loading of rules that makes use of lists, lookups + * are created with blank database structs, and need to be filled in after + * completion of all rules and lists. + */ + { + { + /* Initialize the decoders list */ + OS_CreateOSDecoderList(); + + if (!Config.decoders) { + /* Legacy loading */ + /* Read decoders */ + if (!ReadDecodeXML(XML_DECODER)) { + ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER); + } + + /* Read local ones */ + c = ReadDecodeXML(XML_LDECODER); + if (!c) { + if ((c != -2)) { + ErrorExit(CONFIG_ERROR, ARGV0, XML_LDECODER); + } + } else { + if (!test_config) { + verbose("%s: INFO: Reading local decoder file.", ARGV0); + } + } + } else { + /* New loaded based on file speified in openarmor.conf */ + char **decodersfiles; + decodersfiles = Config.decoders; + while ( decodersfiles && *decodersfiles) { + if (!test_config) { + verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles); + } + if (!ReadDecodeXML(*decodersfiles)) { + ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles); + } + + free(*decodersfiles); + decodersfiles++; + } + } + + /* Load decoders */ + SetDecodeXML(); + } + { + /* Load Lists */ + /* Initialize the lists of list struct */ + Lists_OP_CreateLists(); + /* Load each list into list struct */ + { + char **listfiles; + listfiles = Config.lists; + while (listfiles && *listfiles) { + if (!test_config) { + verbose("%s: INFO: Reading loading the lists file: '%s'", ARGV0, *listfiles); + } + if (Lists_OP_LoadList(*listfiles) < 0) { + ErrorExit(LISTS_ERROR, ARGV0, *listfiles); + } + free(*listfiles); + listfiles++; + } + free(Config.lists); + Config.lists = NULL; + } + } + + { + /* Load Rules */ + /* Create the rules list */ + Rules_OP_CreateRules(); + + /* Read the rules */ + { + char **rulesfiles; + rulesfiles = Config.includes; + while (rulesfiles && *rulesfiles) { + if (!test_config) { + verbose("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles); + } + if (Rules_OP_ReadRules(*rulesfiles) < 0) { + ErrorExit(RULES_ERROR, ARGV0, *rulesfiles); + } + + free(*rulesfiles); + rulesfiles++; + } + + free(Config.includes); + Config.includes = NULL; + } + + /* Find all rules that require list lookups and attache the the + * correct list struct to the rule. This keeps rules from having to + * search thought the list of lists for the correct file during + * rule evaluation. + */ + OS_ListLoadRules(); + } + } + + /* Fix the levels/accuracy */ + { + int total_rules; + RuleNode *tmp_node = OS_GetFirstRule(); + + total_rules = _setlevels(tmp_node, 0); + if (!test_config) { + verbose("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules); + } + } + + /* Create a rules hash (for reading alerts from other servers) */ + { + RuleNode *tmp_node = OS_GetFirstRule(); + Config.g_rules_hash = OSHash_Create(); + if (!Config.g_rules_hash) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + AddHash_Rule(tmp_node); + } + + /* Ignored files on syscheck */ + { + char **files; + files = Config.syscheck_ignore; + while (files && *files) { + if (!test_config) { + verbose("%s: INFO: Ignoring file: '%s'", ARGV0, *files); + } + files++; + } + } + + /* Check if log_fw is enabled */ + Config.logfw = (u_int8_t) getDefine_Int("analysisd", + "log_fw", + 0, 1); + + /* Success on the configuration test */ + if (test_config) { + exit(0); + } + + /* Verbose message */ + debug1(CHROOT_MSG, ARGV0, dir); + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Set the user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + /* Create the PID file */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Set the queue */ + if ((m_queue = StartMQ(DEFAULTQUEUE, READ)) < 0) { + ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); + } + + /* allowlist */ + if (Config.allow_list == NULL) { + if (Config.ar) { + verbose("%s: INFO: No IP in the allow list for active response.", ARGV0); + } + } else { + if (Config.ar) { + os_ip **wl; + int wlc = 0; + wl = Config.allow_list; + while (*wl) { + verbose("%s: INFO: Allow listing IP: '%s'", ARGV0, (*wl)->ip); + wl++; + wlc++; + } + verbose("%s: INFO: %d IPs in the allow list for active response.", + ARGV0, wlc); + } + } + + /* Hostname allowlist */ + if (Config.hostname_allow_list == NULL) { + if (Config.ar) + verbose("%s: INFO: No Hostname in the allow list for active response.", + ARGV0); + } else { + if (Config.ar) { + int wlc = 0; + char **wl; + + wl = Config.hostname_allow_list; + while (*wl) { + verbose("%s: INFO: Allow listing Hostname: '%s'", ARGV0, *wl); + wlc++; + wl++; + } + verbose("%s: INFO: %d Hostname(s) in the allow list for active response.", + ARGV0, wlc); + } + } + + /* Startup message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* Going to main loop */ + OS_ReadMSG(m_queue); + + exit(0); +} + +/* Main function. Receives the messages(events) and analyze them all */ +#ifndef TESTRULE +__attribute__((noreturn)) +void OS_ReadMSG(int m_queue) +#else +__attribute__((noreturn)) +void OS_ReadMSG_analysisd(int m_queue) +#endif +{ + int i; + char msg[OS_MAXSTR + 1]; + Eventinfo *lf; + + RuleInfo *stats_rule = NULL; + + /* Null to global currently pointers */ + currently_rule = NULL; + + /* Initialize the logs */ + OS_InitLog(); + + /* Initialize the integrity database */ + SyscheckInit(); + + /* Initialize Rootcheck */ + RootcheckInit(); + + /* Initialize host info */ + HostinfoInit(); + + /* Create the event list */ + OS_CreateEventList(Config.memorysize); + + /* Initiate the FTS list */ + if (!FTS_Init()) { + ErrorExit(FTS_LIST_ERROR, ARGV0); + } + + /* Initialize the Accumulator */ + if (!Accumulate_Init()) { + merror("accumulator: ERROR: Initialization failed"); + exit(1); + } + + /* Start the active response queues */ + if (Config.ar) { + /* Waiting the ARQ to settle */ + sleep(3); + +#ifndef LOCAL + if (Config.ar & REMOTE_AR) { + if ((arq = StartMQ(ARQUEUE, WRITE)) < 0) { + merror(ARQ_ERROR, ARGV0); + + /* If LOCAL_AR is set, keep it there */ + if (Config.ar & LOCAL_AR) { + Config.ar = 0; + Config.ar |= LOCAL_AR; + } else { + Config.ar = 0; + } + } else { + verbose(CONN_TO, ARGV0, ARQUEUE, "active-response"); + } + } +#else + /* Only for LOCAL_ONLY installs */ + if (Config.ar & REMOTE_AR) { + if (Config.ar & LOCAL_AR) { + Config.ar = 0; + Config.ar |= LOCAL_AR; + } else { + Config.ar = 0; + } + } +#endif + + if (Config.ar & LOCAL_AR) { + if ((execdq = StartMQ(EXECQUEUE, WRITE)) < 0) { + merror(ARQ_ERROR, ARGV0); + + /* If REMOTE_AR is set, keep it there */ + if (Config.ar & REMOTE_AR) { + Config.ar = 0; + Config.ar |= REMOTE_AR; + } else { + Config.ar = 0; + } + } else { + verbose(CONN_TO, ARGV0, EXECQUEUE, "exec"); + } + } + } + debug1("%s: DEBUG: Active response Init completed.", ARGV0); + + /* Get current time before starting */ + c_time = time(NULL); + + /* Start the hourly/weekly stats */ + if (Start_Hour() < 0) { + Config.stats = 0; + } else { + /* Initialize stats rules */ + stats_rule = zerorulemember( + STATS_MODULE, + Config.stats, + 0, 0, 0, 0, 0, 0); + + if (!stats_rule) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + stats_rule->group = "stats,"; + stats_rule->comment = "Excessive number of events (above normal)."; + } + + /* Do some cleanup */ + memset(msg, '\0', OS_MAXSTR + 1); + + /* Initialize the logs */ + { + lf = (Eventinfo *)calloc(1, sizeof(Eventinfo)); + if (!lf) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + os_calloc(Config.decoder_order_size, sizeof(char*), lf->fields); + lf->year = prev_year; + strncpy(lf->mon, prev_month, 3); + lf->day = today; + + if (OS_GetLogLocation(lf) < 0) { + ErrorExit("%s: Error allocating log files", ARGV0); + } + + Free_Eventinfo(lf); + } + +#ifdef SQLITE_ENABLED + /* Open the sqlite db */ + extern sqlite3 *conn; + int s_error = 0; + if (Config.md5_allowlist) { + debug2("Opening md5_allowlist: %s", Config.md5_allowlist); + if((s_error = sqlite3_open(Config.md5_allowlist, &conn))) { + merror(INVALID_IGNORE_MD5DB, ARGV0, Config.md5_allowlist); + } + + } +#endif + + debug1("%s: DEBUG: Startup completed. Waiting for new messages..", ARGV0); + + if (Config.custom_alert_output) { + debug1("%s: INFO: Custom output found.!", ARGV0); + } + + /* Daemon loop */ + while (1) { + lf = (Eventinfo *)calloc(1, sizeof(Eventinfo)); + os_calloc(Config.decoder_order_size, sizeof(char*), lf->fields); + + /* This shouldn't happen */ + if (lf == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + DEBUG_MSG("%s: DEBUG: Waiting for msgs - %d ", ARGV0, (int)time(0)); + + /* Receive message from queue */ + if ((i = OS_RecvUnix(m_queue, OS_MAXSTR, msg))) { + RuleNode *rulenode_pt; + + /* Get the time we received the event */ + c_time = time(NULL); + + /* Default values for the log info */ + Zero_Eventinfo(lf); + + /* Check for a valid message */ + if (i < 4) { + merror(IMSG_ERROR, ARGV0, msg); + Free_Eventinfo(lf); + continue; + } + + /* Message before extracting header */ + DEBUG_MSG("%s: DEBUG: Received msg: %s ", ARGV0, msg); + + /* Clean the msg appropriately */ + if (OS_CleanMSG(msg, lf) < 0) { + merror(IMSG_ERROR, ARGV0, msg); + Free_Eventinfo(lf); + continue; + } + + /* Msg cleaned */ + DEBUG_MSG("%s: DEBUG: Msg cleanup: %s ", ARGV0, lf->log); + + /* Current rule must be null in here */ + currently_rule = NULL; + + /** Check the date/hour changes **/ + + /* Update the hour */ + if (thishour != __crt_hour) { + /* Search all the rules and print the number + * of alerts that each one fired + */ + DumpLogstats(); + thishour = __crt_hour; + + /* Check if the date has changed */ + if (today != lf->day) { + if (Config.stats) { + /* Update the hourly stats (done daily) */ + Update_Hour(); + } + + if (OS_GetLogLocation(lf) < 0) { + ErrorExit("%s: Error allocating log files", ARGV0); + } + + today = lf->day; + strncpy(prev_month, lf->mon, 3); + prev_year = lf->year; + } + } + + + /* Increment number of events received */ + hourly_events++; + + /*** Run decoders ***/ + + /* Integrity check from syscheck */ + if (msg[0] == SYSCHECK_MQ) { + hourly_syscheck++; + + if (!DecodeSyscheck(lf)) { + /* We don't process syscheck events further */ + goto CLMEM; + } + + /* Get log size */ + lf->size = strlen(lf->log); + } + + /* Rootcheck decoding */ + else if (msg[0] == ROOTCHECK_MQ) { + if (!DecodeRootcheck(lf)) { + /* We don't process rootcheck events further */ + goto CLMEM; + } + lf->size = strlen(lf->log); + } + + /* Host information special decoder */ + else if (msg[0] == HOSTINFO_MQ) { + if (!DecodeHostinfo(lf)) { + /* We don't process hostinfo events further */ + goto CLMEM; + } + lf->size = strlen(lf->log); + } + + /* Run the general Decoders */ + else { + /* Get log size */ + lf->size = strlen(lf->log); + + DecodeEvent(lf); + } + + /* Run accumulator */ + if ( lf->decoder_info->accumulate == 1 ) { + lf = Accumulate(lf); + } + + /* Firewall event */ + if (lf->decoder_info->type == FIREWALL) { + /* If we could not get any information from + * the log, just ignore it + */ + hourly_firewall++; + if (Config.logfw) { + if (!FW_Log(lf)) { + goto CLMEM; + } + } + } + + /* We only check if the last message is + * duplicated on syslog + */ + else if (lf->decoder_info->type == SYSLOG) { + /* Check if the message is duplicated */ + if (LastMsg_Stats(lf->full_log) == 1) { + goto CLMEM; + } else { + LastMsg_Change(lf->full_log); + } + } + + /* Stats checking */ + if (Config.stats) { + if (Check_Hour() == 1) { + RuleInfo *saved_rule = lf->generated_rule; + char *saved_log; + + /* Save previous log */ + saved_log = lf->full_log; + + lf->generated_rule = stats_rule; + lf->full_log = __stats_comment; + + /* Alert for statistical analysis */ + if (stats_rule->alert_opts & DO_LOGALERT) { + __crt_ftell = ftell(_aflog); + if (Config.custom_alert_output) { + OS_CustomLog(lf, Config.custom_alert_output_format); + } else { + OS_Log(lf); + } + /* Log to json file */ + if (Config.jsonout_output) { + jsonout_output_event(lf); + } + + } + + /* Set lf to the old values */ + lf->generated_rule = saved_rule; + lf->full_log = saved_log; + } + } + + /* Check the rules */ + DEBUG_MSG("%s: DEBUG: Checking the rules - %d ", + ARGV0, lf->decoder_info->type); + + /* Loop over all the rules */ + rulenode_pt = OS_GetFirstRule(); + if (!rulenode_pt) { + ErrorExit("%s: Rules in an inconsistent state. Exiting.", + ARGV0); + } + + do { + if (lf->decoder_info->type == openarmor_ALERT) { + if (!lf->generated_rule) { + goto CLMEM; + } + + /* Process the alert */ + currently_rule = lf->generated_rule; + } + + /* Categories must match */ + else if (rulenode_pt->ruleinfo->category != + lf->decoder_info->type) { + continue; + } + + /* Check each rule */ + else if ((currently_rule = OS_CheckIfRuleMatch(lf, rulenode_pt)) + == NULL) { + continue; + } + + /* Ignore level 0 */ + if (currently_rule->level == 0) { + break; + } + + /* Check ignore time */ + if (currently_rule->ignore_time) { + if (currently_rule->time_ignored == 0) { + currently_rule->time_ignored = lf->time; + } + /* If the current time - the time the rule was ignored + * is less than the time it should be ignored, + * leave (do not alert again) + */ + else if ((lf->time - currently_rule->time_ignored) + < currently_rule->ignore_time) { + break; + } else { + currently_rule->time_ignored = lf->time; + } + } + + /* Pointer to the rule that generated it */ + lf->generated_rule = currently_rule; + + /* Check if we should ignore it */ + if (currently_rule->ckignore && IGnore(lf)) { + /* Ignore rule */ + lf->generated_rule = NULL; + break; + } + + /* Check if we need to add to ignore list */ + if (currently_rule->ignore) { + AddtoIGnore(lf); + } + + /* Log the alert if configured to */ + if (currently_rule->alert_opts & DO_LOGALERT) { + __crt_ftell = ftell(_aflog); + + if (Config.custom_alert_output) { + OS_CustomLog(lf, Config.custom_alert_output_format); + } else { + OS_Log(lf); + } + /* Log to json file */ + if (Config.jsonout_output) { + jsonout_output_event(lf); + } + } + +#ifdef PRELUDE_OUTPUT_ENABLED + /* Log to prelude */ + if (Config.prelude) { + if (Config.prelude_log_level <= currently_rule->level) { + OS_PreludeLog(lf); + } + } +#endif + +#ifdef ZEROMQ_OUTPUT_ENABLED + /* Log to zeromq */ + if (Config.zeromq_output) { + zeromq_output_event(lf); + } +#endif + + + /* Execute an active response */ + if (currently_rule->ar) { + int do_ar; + active_response **rule_ar; + + rule_ar = currently_rule->ar; + + while (*rule_ar) { + do_ar = 1; + if ((*rule_ar)->ar_cmd->expect & USERNAME) { + if (!lf->dstuser || + !OS_PRegex(lf->dstuser, "^[a-zA-Z._0-9@?-]*$")) { + if (lf->dstuser) { + merror(CRAFTED_USER, ARGV0, lf->dstuser); + } + do_ar = 0; + } + } + if ((*rule_ar)->ar_cmd->expect & SRCIP) { + if (!lf->srcip || + !OS_PRegex(lf->srcip, "^[a-zA-Z.:_0-9-]*$")) { + if (lf->srcip) { + merror(CRAFTED_IP, ARGV0, lf->srcip); + } + do_ar = 0; + } + } + if ((*rule_ar)->ar_cmd->expect & FILENAME) { + if (!lf->filename) { + do_ar = 0; + } + } + + if (do_ar && execdq > 0) { + OS_Exec(execdq, arq, lf, *rule_ar); + } + rule_ar++; + } + } + + /* Copy the structure to the state memory of if_matched_sid */ + if (currently_rule->sid_prev_matched) { + if (!OSList_AddData(currently_rule->sid_prev_matched, lf)) { + merror("%s: Unable to add data to sig list.", ARGV0); + } else { + lf->sid_node_to_delete = + currently_rule->sid_prev_matched->last_node; + } + } + /* Group list */ + else if (currently_rule->group_prev_matched) { + unsigned int j = 0; + + while (j < currently_rule->group_prev_matched_sz) { + if (!OSList_AddData( + currently_rule->group_prev_matched[j], + lf)) { + merror("%s: Unable to add data to grp list.", ARGV0); + } + j++; + } + } + + OS_AddEvent(lf); + + break; + + } while ((rulenode_pt = rulenode_pt->next) != NULL); + + /* If configured to log all, do it */ + if (Config.logall) + OS_Store(lf); + if (Config.logall_json) + jsonout_output_archive(lf); + +CLMEM: + /** Cleaning the memory **/ + + /* Only clear the memory if the eventinfo was not + * added to the stateful memory + * -- message is free inside clean event -- + */ + if (lf->generated_rule == NULL) { + Free_Eventinfo(lf); + } + } else { + free(lf); + } + } +} + +/* Checks if the current_rule matches the event information */ +RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node) +{ + /* We check for: + * decoded_as, + * fts, + * word match (fast regex), + * regex, + * url, + * id, + * user, + * maxsize, + * protocol, + * srcip, + * dstip, + * srcport, + * dstport, + * time, + * weekday, + * status, + */ + RuleInfo *rule = curr_node->ruleinfo; + int i; + + /* Can't be null */ + if (!rule) { + merror("%s: Inconsistent state. currently rule NULL", ARGV0); + return (NULL); + } + +#ifdef TESTRULE + if (full_output && !alert_only) + print_out(" Trying rule: %d - %s", rule->sigid, + rule->comment); +#endif + + /* Check if any decoder pre-matched here */ + if (rule->decoded_as && + rule->decoded_as != lf->decoder_info->id) { + return (NULL); + } + + /* Check program name */ + if (rule->program_name) { + if (!lf->program_name) { + return (NULL); + } + + if (!OSMatch_Execute(lf->program_name, + lf->p_name_size, + rule->program_name)) { + return (NULL); + } + } + else if (rule->program_name_pcre2) { + if (!lf->program_name) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->program_name, + rule->program_name_pcre2)) { + return (NULL); + } + } + + /* Check for the ID */ + if (rule->id) { + if (!lf->id) { + return (NULL); + } + + if (!OSMatch_Execute(lf->id, + strlen(lf->id), + rule->id)) { + return (NULL); + } + } + else if (rule->id_pcre2) { + if (!lf->id) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->id, + rule->id_pcre2)) { + return (NULL); + } + } + + /* Check if any word to match exists */ + if (rule->match) { + if (!OSMatch_Execute(lf->log, lf->size, rule->match)) { + return (NULL); + } + } + else if (rule->match_pcre2) { + if (!OSPcre2_Execute(lf->log, rule->match_pcre2)) { + return (NULL); + } + } + + /* Check if exist any regex for this rule */ + if (rule->regex) { + if (!OSRegex_Execute(lf->log, rule->regex)) { + return (NULL); + } + } + else if (rule->pcre2) { + if (!OSPcre2_Execute(lf->log, rule->pcre2)) { + return (NULL); + } + } + + /* Check for actions */ + if (rule->action) { + if (!lf->action) { + return (NULL); + } + + if (strcmp(rule->action, lf->action) != 0) { + return (NULL); + } + } + + /* Checking for the URL */ + if (rule->url) { + if (!lf->url) { + return (NULL); + } + + if (!OSMatch_Execute(lf->url, strlen(lf->url), rule->url)) { + return (NULL); + } + } + if (rule->url_pcre2) { + if (!lf->url) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->url, rule->url_pcre2)) { + return (NULL); + } + } + + /* Check for dynamic fields */ + + for (i = 0; i < Config.decoder_order_size && rule->fields[i]; i++) { + int j; + + for (j = 0; j < Config.decoder_order_size; j++) + if (lf->decoder_info->fields[j]) + if (strcasecmp(lf->decoder_info->fields[j], rule->fields[i]->name) == 0) + break; + + if (j == Config.decoder_order_size) + + return NULL; + + if (!OSRegex_Execute(lf->fields[j], rule->fields[i]->regex)) + return NULL; + } + + + /* Get TCP/IP packet information */ + if (rule->alert_opts & DO_PACKETINFO) { + /* Check for the srcip */ + if (rule->srcip) { + if (!lf->srcip) { + return (NULL); + } + + if (!OS_IPFoundList(lf->srcip, rule->srcip)) { + return (NULL); + } + } + + /* Check for the dstip */ + if (rule->dstip) { + if (!lf->dstip) { + return (NULL); + } + + if (!OS_IPFoundList(lf->dstip, rule->dstip)) { + return (NULL); + } + } + + if (rule->srcport) { + if (!lf->srcport) { + return (NULL); + } + + if (!OSMatch_Execute(lf->srcport, + strlen(lf->srcport), + rule->srcport)) { + return (NULL); + } + } + else if (rule->srcport_pcre2) { + if (!lf->srcport) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->srcport, + rule->srcport_pcre2)) { + return (NULL); + } + } + if (rule->dstport) { + if (!lf->dstport) { + return (NULL); + } + + if (!OSMatch_Execute(lf->dstport, + strlen(lf->dstport), + rule->dstport)) { + return (NULL); + } + } + else if (rule->dstport_pcre2) { + if (!lf->dstport) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->dstport, + rule->dstport_pcre2)) { + return (NULL); + } + } + } /* END PACKET_INFO */ + + /* Extra information from event */ + if (rule->alert_opts & DO_EXTRAINFO) { + /* Check compiled rule */ + if (rule->compiled_rule) { + if (!rule->compiled_rule(lf)) { + return (NULL); + } + } + + /* Checking if exist any user to match */ + if (rule->user) { + if (lf->dstuser) { + if (!OSMatch_Execute(lf->dstuser, + strlen(lf->dstuser), + rule->user)) { + return (NULL); + } + } else if (lf->srcuser) { + if (!OSMatch_Execute(lf->srcuser, + strlen(lf->srcuser), + rule->user)) { + return (NULL); + } + } else { + /* no user set */ + return (NULL); + } + } + else if (rule->user_pcre2) { + if (lf->dstuser) { + if (!OSPcre2_Execute(lf->dstuser, + rule->user_pcre2)) { + return (NULL); + } + } else if (lf->srcuser) { + if (!OSPcre2_Execute(lf->srcuser, + rule->user_pcre2)) { + return (NULL); + } + } else { + /* no user set */ + return (NULL); + } + } + + /* Adding checks for geoip. */ + if(rule->srcgeoip) { + if(lf->srcgeoip) { + if(!OSMatch_Execute(lf->srcgeoip, + strlen(lf->srcgeoip), + rule->srcgeoip)) + return(NULL); + } else { + return(NULL); + } + } + else if(rule->srcgeoip_pcre2) { + if(lf->srcgeoip) { + if(!OSPcre2_Execute(lf->srcgeoip, + rule->srcgeoip_pcre2)) + return(NULL); + } else { + return(NULL); + } + } + + + if(rule->dstgeoip) { + if(lf->dstgeoip) { + if(!OSMatch_Execute(lf->dstgeoip, + strlen(lf->dstgeoip), + rule->dstgeoip)) + return(NULL); + } else { + return(NULL); + } + } + else if(rule->dstgeoip_pcre2) { + if(lf->dstgeoip) { + if(!OSPcre2_Execute(lf->dstgeoip, + rule->dstgeoip_pcre2)) + return(NULL); + } else { + return(NULL); + } + } + + + /* Check if any rule related to the size exist */ + if (rule->maxsize) { + if (lf->size < rule->maxsize) { + return (NULL); + } + } + + /* Check if we are in the right time */ + if (rule->day_time) { + if (!OS_IsonTime(lf->hour, rule->day_time)) { + return (NULL); + } + } + + /* Check week day */ + if (rule->week_day) { + if (!OS_IsonDay(__crt_wday, rule->week_day)) { + return (NULL); + } + } + + /* Get extra data */ + if (rule->extra_data) { + if (!lf->data) { + return (NULL); + } + + if (!OSMatch_Execute(lf->data, + strlen(lf->data), + rule->extra_data)) { + return (NULL); + } + } + else if (rule->extra_data_pcre2) { + if (!lf->data) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->data, + rule->extra_data_pcre2)) { + return (NULL); + } + } + + /* Check hostname */ + if (rule->hostname) { + if (!lf->hostname) { + return (NULL); + } + + if (!OSMatch_Execute(lf->hostname, + strlen(lf->hostname), + rule->hostname)) { + return (NULL); + } + } + else if (rule->hostname_pcre2) { + if (!lf->hostname) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->hostname, + rule->hostname_pcre2)) { + return (NULL); + } + } + + /* Check for status */ + if (rule->status) { + if (!lf->status) { + return (NULL); + } + + if (!OSMatch_Execute(lf->status, + strlen(lf->status), + rule->status)) { + return (NULL); + } + } + else if (rule->status_pcre2) { + if (!lf->status) { + return (NULL); + } + + if (!OSPcre2_Execute(lf->status, + rule->status_pcre2)) { + return (NULL); + } + } + + + /* Do diff check */ + if (rule->context_opts & SAME_DODIFF) { + if (!doDiff(rule, lf)) { + return (NULL); + } + } + } + + /* Check for the FTS flag */ + if (rule->alert_opts & DO_FTS) { + /** FTS CHECKS **/ + if (lf->decoder_info->fts) { + if (lf->decoder_info->fts & FTS_DONE) { + /* We already did the fts in here */ + } else if (!FTS(lf)) { + return (NULL); + } + } else { + return (NULL); + } + } + + /* List lookups */ + if (rule->lists != NULL) { + ListRule *list_holder = rule->lists; + while (list_holder) { + switch (list_holder->field) { + case RULE_SRCIP: + if (!lf->srcip) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->srcip)) { + return (NULL); + } + break; + case RULE_SRCPORT: + if (!lf->srcport) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->srcport)) { + return (NULL); + } + break; + case RULE_DSTIP: + if (!lf->dstip) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->dstip)) { + return (NULL); + } + break; + case RULE_DSTPORT: + if (!lf->dstport) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->dstport)) { + return (NULL); + } + break; + case RULE_USER: + if (lf->srcuser) { + if (!OS_DBSearch(list_holder, lf->srcuser)) { + return (NULL); + } + } else if (lf->dstuser) { + if (!OS_DBSearch(list_holder, lf->dstuser)) { + return (NULL); + } + } else { + return (NULL); + } + break; + case RULE_URL: + if (!lf->url) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->url)) { + return (NULL); + } + break; + case RULE_ID: + if (!lf->id) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->id)) { + return (NULL); + } + break; + case RULE_HOSTNAME: + if (!lf->hostname) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->hostname)) { + return (NULL); + } + break; + case RULE_PROGRAM_NAME: + if (!lf->program_name) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->program_name)) { + return (NULL); + } + break; + case RULE_STATUS: + if (!lf->status) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->status)) { + return (NULL); + } + break; + case RULE_ACTION: + if (!lf->action) { + return (NULL); + } + if (!OS_DBSearch(list_holder, lf->action)) { + return (NULL); + } + break; + default: + return (NULL); + } + + list_holder = list_holder->next; + } + } + + /* If it is a context rule, search for it */ + if (rule->context == 1) { + if (!(rule->context_opts & SAME_DODIFF)) { + if (rule->event_search) { + if (!rule->event_search(lf, rule)) { + return (NULL); + } + } + } + } + +#ifdef TESTRULE + if (full_output && !alert_only) { + print_out(" *Rule %d matched.", rule->sigid); + } +#endif + + /* Search for dependent rules */ + if (curr_node->child) { + RuleNode *child_node = curr_node->child; + RuleInfo *child_rule = NULL; + +#ifdef TESTRULE + if (full_output && !alert_only) { + print_out(" *Trying child rules."); + } +#endif + + while (child_node) { + child_rule = OS_CheckIfRuleMatch(lf, child_node); + if (child_rule != NULL) { + return (child_rule); + } + + child_node = child_node->next; + } + } + + /* If we are set to no alert, keep going */ + if (rule->alert_opts & NO_ALERT) { + return (NULL); + } + + hourly_alerts++; + rule->firedtimes++; + + return (rule); /* Matched */ +} + +/* Update each rule and print it to the logs */ +static void LoopRule(RuleNode *curr_node, FILE *flog) +{ + if (curr_node->ruleinfo->firedtimes) { + fprintf(flog, "%d-%d-%d-%d\n", + thishour, + curr_node->ruleinfo->sigid, + curr_node->ruleinfo->level, + curr_node->ruleinfo->firedtimes); + curr_node->ruleinfo->firedtimes = 0; + } + + if (curr_node->child) { + RuleNode *child_node = curr_node->child; + + while (child_node) { + LoopRule(child_node, flog); + child_node = child_node->next; + } + } + return; +} + +/* Dump the hourly stats about each rule */ +static void DumpLogstats() +{ + RuleNode *rulenode_pt; + char logfile[OS_FLSIZE + 1]; + FILE *flog; + + /* Open log file */ + snprintf(logfile, OS_FLSIZE, "%s/%d/", STATSAVED, prev_year); + if (IsDir(logfile) == -1) + if (mkdir(logfile, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, logfile, errno, strerror(errno)); + return; + } + + snprintf(logfile, OS_FLSIZE, "%s/%d/%s", STATSAVED, prev_year, prev_month); + + if (IsDir(logfile) == -1) + if (mkdir(logfile, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, logfile, errno, strerror(errno)); + return; + } + + + /* Creat the logfile name */ + snprintf(logfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + STATSAVED, + prev_year, + prev_month, + "totals", + today); + + flog = fopen(logfile, "a"); + if (!flog) { + merror(FOPEN_ERROR, ARGV0, logfile, errno, strerror(errno)); + return; + } + + rulenode_pt = OS_GetFirstRule(); + + if (!rulenode_pt) { + ErrorExit("%s: Rules in an inconsistent state. Exiting.", + ARGV0); + } + + /* Loop over all the rules and print their stats */ + do { + LoopRule(rulenode_pt, flog); + } while ((rulenode_pt = rulenode_pt->next) != NULL); + + + /* Print total for the hour */ + fprintf(flog, "%d--%d--%d--%d--%d\n\n", + thishour, + hourly_alerts, hourly_events, hourly_syscheck, hourly_firewall); + hourly_alerts = 0; + hourly_events = 0; + hourly_syscheck = 0; + hourly_firewall = 0; + + fclose(flog); +} + diff --git a/src/analysisd/analysisd.h b/src/analysisd/analysisd.h new file mode 100644 index 000000000..62b1ba2a9 --- /dev/null +++ b/src/analysisd/analysisd.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _LOGAUDIT__H +#define _LOGAUDIT__H + +#include + +#include "decoders/decoder.h" + +/* Time structures */ +extern int today; +extern int thishour; +extern int prev_year; +extern char prev_month[4]; + +extern int __crt_hour; +extern int __crt_wday; + +extern time_t c_time; /* Current time of event. Used everywhere */ + +/* Local host name */ +extern char __shost[512]; + +extern OSDecoderInfo *NULL_Decoder; + +#define openarmor_SERVER "openarmor-server" +#define MAX_DECODER_ORDER_SIZE 20 + + +#endif /* _LOGAUDIT__H */ + diff --git a/src/analysisd/cdb/cdb.c b/src/analysisd/cdb/cdb.c new file mode 100644 index 000000000..6e9ff71d4 --- /dev/null +++ b/src/analysisd/cdb/cdb.c @@ -0,0 +1,167 @@ +/* Public domain */ +/* Adapted from DJB's original cdb-0.75 package */ + +#include +#include +#include +#include +#include +#include +#include "cdb.h" + +#ifndef EPROTO +#define EPROTO -15 /* cdb 0.75's default for PROTOless systems */ +#endif + + +void cdb_free(struct cdb *c) +{ + if (c->map) { + munmap(c->map, c->size); + c->map = 0; + } +} + +void cdb_findstart(struct cdb *c) +{ + c->loop = 0; +} + +void cdb_init(struct cdb *c, int fd) +{ + struct stat st; + char *x; + + cdb_free(c); + cdb_findstart(c); + c->fd = fd; + + if (fstat(fd, &st) == 0) + if ((size_t) st.st_size <= 0xffffffff) { + x = (char *) mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (x + 1) { + c->size = st.st_size; + c->map = x; + } + } +} + +int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos) +{ + if (c->map) { + if ((pos > c->size) || (c->size - pos < len)) { + goto FORMAT; + } + memcpy(buf, c->map + pos, len); + } else { + if (lseek(c->fd, pos, SEEK_SET) == -1) { + return -1; + } + /* if (seek_set(c->fd,pos) == -1) return -1; */ + while (len > 0) { + int r; + do { + r = read(c->fd, buf, len); + } while ((r == -1) && (errno == EINTR)); + if (r == -1) { + return -1; + } + if (r == 0) { + goto FORMAT; + } + buf += r; + len -= r; + } + } + return 0; + +FORMAT: + errno = EPROTO; + return -1; +} + +static int match(struct cdb *c, char *key, unsigned int len, uint32 pos) +{ + char buf[32]; + unsigned int n; + + while (len > 0) { + n = sizeof buf; + if (n > len) { + n = len; + } + if (cdb_read(c, buf, n, pos) == -1) { + return -1; + } + if (memcmp(buf, key, n)) { + return 0; + } + pos += n; + key += n; + len -= n; + } + return 1; +} + +int cdb_findnext(struct cdb *c, char *key, unsigned int len) +{ + char buf[8]; + uint32 pos; + uint32 u; + + if (!c->loop) { + u = cdb_hash(key, len); + if (cdb_read(c, buf, 8, (u << 3) & 2047) == -1) { + return -1; + } + uint32_unpack(buf + 4, &c->hslots); + if (!c->hslots) { + return 0; + } + uint32_unpack(buf, &c->hpos); + c->khash = u; + u >>= 8; + u %= c->hslots; + u <<= 3; + c->kpos = c->hpos + u; + } + + while (c->loop < c->hslots) { + if (cdb_read(c, buf, 8, c->kpos) == -1) { + return -1; + } + uint32_unpack(buf + 4, &pos); + if (!pos) { + return 0; + } + c->loop += 1; + c->kpos += 8; + if (c->kpos == c->hpos + (c->hslots << 3)) { + c->kpos = c->hpos; + } + uint32_unpack(buf, &u); + if (u == c->khash) { + if (cdb_read(c, buf, 8, pos) == -1) { + return -1; + } + uint32_unpack(buf, &u); + if (u == len) + switch (match(c, key, len, pos + 8)) { + case -1: + return -1; + case 1: + uint32_unpack(buf + 4, &c->dlen); + c->dpos = pos + 8 + len; + return 1; + } + } + } + + return 0; +} + +int cdb_find(struct cdb *c, char *key, unsigned int len) +{ + cdb_findstart(c); + return cdb_findnext(c, key, len); +} diff --git a/src/analysisd/cdb/cdb.h b/src/analysisd/cdb/cdb.h new file mode 100644 index 000000000..a8f7be17b --- /dev/null +++ b/src/analysisd/cdb/cdb.h @@ -0,0 +1,38 @@ +/* Public domain */ +/* Adapted from DJB's original cdb-0.75 package */ + +#ifndef CDB_H +#define CDB_H + +#include "uint32.h" + +#define CDB_HASHSTART 5381 +extern uint32 cdb_hashadd(uint32, unsigned char); +extern uint32 cdb_hash(char *, unsigned int); + +struct cdb { + char *map; /* 0 if no map is available */ + int fd; + uint32 size; /* initialized if map is nonzero */ + uint32 loop; /* number of hash slots searched under this key */ + uint32 khash; /* initialized if loop is nonzero */ + uint32 kpos; /* initialized if loop is nonzero */ + uint32 hpos; /* initialized if loop is nonzero */ + uint32 hslots; /* initialized if loop is nonzero */ + uint32 dpos; /* initialized if cdb_findnext() returns 1 */ + uint32 dlen; /* initialized if cdb_findnext() returns 1 */ +} ; + +extern void cdb_free(struct cdb *); +extern void cdb_init(struct cdb *, int fd); + +extern int cdb_read(struct cdb *, char *, unsigned int, uint32); + +extern void cdb_findstart(struct cdb *); +extern int cdb_findnext(struct cdb *, char *, unsigned int); +extern int cdb_find(struct cdb *, char *, unsigned int); + +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) + +#endif diff --git a/src/analysisd/cdb/cdb_hash.c b/src/analysisd/cdb/cdb_hash.c new file mode 100644 index 000000000..f0fc8eb47 --- /dev/null +++ b/src/analysisd/cdb/cdb_hash.c @@ -0,0 +1,23 @@ +/* Public domain */ +/* Adapted from DJB's original cdb-0.75 package */ + +#include "cdb.h" + + +uint32 cdb_hashadd(uint32 h, unsigned char c) +{ + h += (h << 5); + return h ^ c; +} + +uint32 cdb_hash(char *buf, unsigned int len) +{ + uint32 h; + + h = CDB_HASHSTART; + while (len) { + h = cdb_hashadd(h, *buf++); + --len; + } + return h; +} diff --git a/src/analysisd/cdb/cdb_make.c b/src/analysisd/cdb/cdb_make.c new file mode 100644 index 000000000..eb5fe27b3 --- /dev/null +++ b/src/analysisd/cdb/cdb_make.c @@ -0,0 +1,230 @@ +/* Public domain */ +/* Adapted from DJB's original cdb-0.75 package */ + +#include +#include +#include +#include +#include +#include "cdb.h" +#include "cdb_make.h" +#include "uint32.h" + + +static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz) +{ + fwrite(buf, sz, 1, c->fp); + return ferror(c->fp); +} + +int cdb_make_start(struct cdb_make *c, FILE *f) +{ + c->head = 0; + c->split = 0; + c->hash = 0; + c->numentries = 0; + c->fp = f; + c->pos = sizeof c->final; + if (fseek(f, c->pos, SEEK_SET) == -1) { + perror("fseek failed"); + return -1; + } + return ftell(c->fp); +} + +static int posplus(struct cdb_make *c, uint32 len) +{ + uint32 newpos = c->pos + len; + if (newpos < len) { + errno = ENOMEM; + return -1; + } + c->pos = newpos; + return 0; +} + +int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h) +{ + struct cdb_hplist *head; + + head = c->head; + if (!head || (head->num >= CDB_HPLIST)) { + head = (struct cdb_hplist *) malloc(sizeof(struct cdb_hplist)); + if (!head) { + return -1; + } + head->num = 0; + head->next = c->head; + c->head = head; + } + head->hp[head->num].h = h; + head->hp[head->num].p = c->pos; + ++head->num; + ++c->numentries; + if (posplus(c, 8) == -1) { + return -1; + } + if (posplus(c, keylen) == -1) { + return -1; + } + if (posplus(c, datalen) == -1) { + return -1; + } + return 0; +} + +int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen) +{ + char buf[8]; + + /*if (keylen > 0xffffffff) { + errno = ENOMEM; + return -1; + } + if (datalen > 0xffffffff) { + errno = ENOMEM; + return -1; + }*/ + + uint32_pack(buf, keylen); + uint32_pack(buf + 4, datalen); + if (cdb_make_write(c, buf, 8) != 0) { + return -1; + } + /* if (buffer_putalign(&c->b,buf,8) == -1) return -1; */ + return 0; +} + +int cdb_make_add(struct cdb_make *c, char *key, unsigned int keylen, char *data, unsigned int datalen) +{ + if (cdb_make_addbegin(c, keylen, datalen) == -1) { + return -1; + } + if (cdb_make_write(c, key, keylen) != 0) { + return -1; + } + if (cdb_make_write(c, data, datalen) != 0) { + return -1; + } + /* if (buffer_putalign(&c->b,key,keylen) == -1) return -1; */ + /* if (buffer_putalign(&c->b,data,datalen) == -1) return -1; */ + return cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen)); +} + +int cdb_make_finish(struct cdb_make *c) +{ + char buf[8]; + int i; + uint32 len; + uint32 u; + uint32 memsize; + uint32 count; + uint32 where; + struct cdb_hplist *x; + struct cdb_hp *hp; + + for (i = 0; i < 256; ++i) { + c->count[i] = 0; + } + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) { + ++c->count[255 & x->hp[i].h]; + } + } + + memsize = 1; + for (i = 0; i < 256; ++i) { + u = c->count[i] * 2; + if (u > memsize) { + memsize = u; + } + } + + memsize += c->numentries; /* no overflow possible up to now */ + u = (uint32) 0 - (uint32) 1; + u /= sizeof(struct cdb_hp); + if (memsize > u) { + errno = ENOMEM; + return -1; + } + + c->split = (struct cdb_hp *) malloc(memsize * sizeof(struct cdb_hp)); + if (!c->split) { + return -1; + } + + c->hash = c->split + c->numentries; + + u = 0; + for (i = 0; i < 256; ++i) { + u += c->count[i]; /* bounded by numentries, so no overflow */ + c->start[i] = u; + } + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) { + c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; + } + } + + for (i = 0; i < 256; ++i) { + count = c->count[i]; + + len = count + count; /* no overflow possible */ + uint32_pack(c->final + 8 * i, c->pos); + uint32_pack(c->final + 8 * i + 4, len); + + for (u = 0; u < len; ++u) { + c->hash[u].h = c->hash[u].p = 0; + } + + hp = c->split + c->start[i]; + for (u = 0; u < count; ++u) { + where = (hp->h >> 8) % len; + while (c->hash[where].p) + if (++where == len) { + where = 0; + } + c->hash[where] = *hp++; + } + + for (u = 0; u < len; ++u) { + uint32_pack(buf, c->hash[u].h); + uint32_pack(buf + 4, c->hash[u].p); + if (cdb_make_write(c, buf, 8) != 0) { + return -1; + } + /* if (buffer_putalign(&c->b,buf,8) == -1) return -1; */ + if (posplus(c, 8) == -1) { + return -1; + } + } + } + + if (c->split) { + free(c->split); + } + + for (x = c->head; x; c->head = x) { + x = x->next; + free(c->head); + } + + if (fflush(c->fp) != 0) { + return -1; + } + /* if (buffer_flush(&c->b) == -1) return -1; */ + rewind(c->fp); + if (ftell(c->fp) != 0) { + return -1; + } + /* if (seek_begin(c->fd) == -1) return -1; */ + if (cdb_make_write(c, c->final, sizeof c->final) != 0) { + return -1; + } + return fflush(c->fp); + /* return buffer_putflush(&c->b,c->final,sizeof c->final); */ +} diff --git a/src/analysisd/cdb/cdb_make.h b/src/analysisd/cdb/cdb_make.h new file mode 100644 index 000000000..017aa1a98 --- /dev/null +++ b/src/analysisd/cdb/cdb_make.h @@ -0,0 +1,44 @@ +/* Public domain */ +/* Adapted from DJB's original cdb-0.75 package */ + +#ifndef CDB_MAKE_H +#define CDB_MAKE_H + +#include +#include "uint32.h" + +#define CDB_HPLIST 1000 + +struct cdb_hp { + uint32 h; + uint32 p; +} ; + +struct cdb_hplist { + struct cdb_hp hp[CDB_HPLIST]; + struct cdb_hplist *next; + int num; +} ; + +struct cdb_make { + /* char bspace[8192]; */ + char final[2048]; + uint32 count[256]; + uint32 start[256]; + struct cdb_hplist *head; + struct cdb_hp *split; /* includes space for hash */ + struct cdb_hp *hash; + uint32 numentries; + /* buffer b; */ + uint32 pos; + /* int fd; */ + FILE *fp; +} ; + +extern int cdb_make_start(struct cdb_make *, FILE *); +extern int cdb_make_addbegin(struct cdb_make *, unsigned int, unsigned int); +extern int cdb_make_addend(struct cdb_make *, unsigned int, unsigned int, uint32); +extern int cdb_make_add(struct cdb_make *, char *, unsigned int, char *, unsigned int); +extern int cdb_make_finish(struct cdb_make *); + +#endif diff --git a/src/analysisd/cdb/uint32.h b/src/analysisd/cdb/uint32.h new file mode 100644 index 000000000..af0928faa --- /dev/null +++ b/src/analysisd/cdb/uint32.h @@ -0,0 +1,11 @@ +/* adopted from libowfat 0.9 (GPL) */ + +#ifndef UINT32_H +#define UINT32_H + +typedef unsigned int uint32; + +extern void uint32_pack(char *out, uint32 in); +extern void uint32_unpack(const char *in, uint32 *out); + +#endif diff --git a/src/analysisd/cdb/uint32_pack.c b/src/analysisd/cdb/uint32_pack.c new file mode 100644 index 000000000..2645ac128 --- /dev/null +++ b/src/analysisd/cdb/uint32_pack.c @@ -0,0 +1,16 @@ +/* adopted from libowfat 0.9 (GPL) */ + +#define NO_UINT32_MACROS +#include "uint32.h" + + +void uint32_pack(char *out, uint32 in) +{ + *out = in & 0xff; + in >>= 8; + *++out = in & 0xff; + in >>= 8; + *++out = in & 0xff; + in >>= 8; + *++out = in & 0xff; +} diff --git a/src/analysisd/cdb/uint32_unpack.c b/src/analysisd/cdb/uint32_unpack.c new file mode 100644 index 000000000..8cf576d29 --- /dev/null +++ b/src/analysisd/cdb/uint32_unpack.c @@ -0,0 +1,13 @@ +/* adopted from libowfat 0.9 (GPL) */ + +#define NO_UINT32_MACROS +#include "uint32.h" + + +void uint32_unpack(const char *in, uint32 *out) +{ + *out = (((uint32)(unsigned char)in[3]) << 24) | + (((uint32)(unsigned char)in[2]) << 16) | + (((uint32)(unsigned char)in[1]) << 8) | + (uint32)(unsigned char)in[0]; +} diff --git a/src/analysisd/cleanevent.c b/src/analysisd/cleanevent.c new file mode 100644 index 000000000..833a5f175 --- /dev/null +++ b/src/analysisd/cleanevent.c @@ -0,0 +1,581 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "cleanevent.h" + +#include "shared.h" +#include "os_regex/os_regex.h" +#include "analysisd.h" +#include "fts.h" +#include "config.h" + +/* To translate between month (int) to month (char) */ +static const char *(month[]) = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + +/* Format a received message in the Eventinfo structure */ +int OS_CleanMSG(char *msg, Eventinfo *lf) +{ + size_t loglen; + char *pieces; + struct tm *p; + + /* The message is formatted in the following way: + * id:location:message. + */ + + /* Ignore the id of the message in here */ + msg += 2; + + /* Set pieces as the message */ + pieces = strchr(msg, ':'); + if (!pieces) { + merror(FORMAT_ERROR, ARGV0); + return (-1); + } + + /* Is this from an agent? */ + if ( *msg == '(' ) + { /* look past '->' for the first ':' */ + pieces = strstr(msg, "->"); + if(!pieces) { + merror(FORMAT_ERROR, ARGV0); + return(-1); + } + pieces = strchr(pieces, ':'); + if(!pieces) + { + merror(FORMAT_ERROR, ARGV0); + return(-1); + } + } + + *pieces = '\0'; + pieces++; + + /* Proposed fix for CVE-2020-8664 */ + if (w_ref_parent_folder(msg) == 1) + { + merror(FORMAT_ERROR, ARGV0); + return(-1); + } + + os_strdup(msg, lf->location); + + /*CVE-2020-8445 fix*/ + remove_control_characters(pieces); + + /* Get the log length */ + loglen = strlen(pieces) + 1; + + /* Assign the values in the structure (lf->full_log) */ + os_malloc((2 * loglen) + 1, lf->full_log); + + /* Set the whole message at full_log */ + strncpy(lf->full_log, pieces, loglen); + + /* Log is the one used for parsing in the decoders and rules */ + lf->log = lf->full_log + loglen; + strncpy(lf->log, pieces, loglen); + + /* check if month contains an umlaut and repair + * umlauts are non-ASCII and use 2 slots in the char array + * repair to only one slot so we can detect the correct date format in the next step + * ex: Mär 02 17:30:52 + */ + if (pieces[1] == (char) 195) { + if (pieces[2] == (char) 164) { + pieces[0] = '\0'; + pieces[1] = 'M'; + pieces[2] = 'a'; + pieces++; + } + } + + /* Check for the syslog date format + * ( ex: Dec 29 10:00:01 + * or 2015-04-16 21:51:02,805 for proftpd 1.3.5 + * or 2007-06-14T15:48:55-04:00 for syslog-ng isodate + * or 2007-06-14T15:48:55.3352-04:00 for syslog-ng isodate with up to 6 optional fraction of a second + * or 2009-05-22T09:36:46.214994-07:00 for rsyslog + * or 2015 Dec 29 10:00:01 ) + */ + if ( + ( /* ex: Dec 29 10:00:01 */ + (loglen > 17) && + (pieces[3] == ' ') && + (pieces[6] == ' ') && + (pieces[9] == ':') && + (pieces[12] == ':') && + (pieces[15] == ' ') && (lf->log += 16) + ) + || + ( /* ex: 2015-04-16 21:51:02,805 */ + (loglen > 24) && + (pieces[4] == '-') && + (pieces[7] == '-') && + (pieces[10] == ' ') && + (pieces[13] == ':') && + (pieces[16] == ':') && + (pieces[19] == ',') && + (lf->log += 23) + ) + || + ( + (loglen > 33) && + (pieces[4] == '-') && + (pieces[7] == '-') && + (pieces[10] == 'T') && + (pieces[13] == ':') && + (pieces[16] == ':') && + ( /* ex: 2007-06-14T15:48:55-04:00 */ + ( + (pieces[22] == ':') && + (pieces[25] == ' ') && (lf->log += 26) + ) + || + /* ex: 2007-06-14T15:48:55.3-04:00 or 2009-05-22T09:36:46,214994-07:00 */ + ( + ( + (pieces[19] == '.') || (pieces[19] == ',') + ) + && + ( + ( (pieces[24] == ':') && (lf->log += 27) ) || + ( (pieces[25] == ':') && (lf->log += 28) ) || + ( (pieces[26] == ':') && (lf->log += 29) ) || + ( (pieces[27] == ':') && (lf->log += 30) ) || + ( (pieces[28] == ':') && (lf->log += 31) ) || + ( (pieces[29] == ':') && (lf->log += 32) ) + ) + ) + ) + ) + || + ( /* ex: 2015 Dec 29 10:00:01 */ + (loglen > 21) && + (isdigit(pieces[0])) && + (pieces[4] == ' ') && + (pieces[8] == ' ') && + (pieces[11] == ' ') && + (pieces[14] == ':') && + (pieces[17] == ':') && + (pieces[20] == ' ') && (lf->log += 21) + ) + || + ( + /* ex: 2019:11:06-00:08:03 */ + (loglen > 20) && + (isdigit(pieces[0])) && + (pieces[4] == ':') && + (pieces[7] == ':') && + (pieces[10] == '-') && + (pieces[13] == ':') && + (pieces[16] == ':') && (lf->log += 20) + ) + ) { + /* Check for an extra space in here */ + if (*lf->log == ' ') { + lf->log++; + } + + + /* Hostname */ + pieces = lf->hostname = lf->log; + + + /* Check for a valid hostname */ + while (isValidChar(*pieces) == 1) { + pieces++; + } + + /* Check if it is a syslog without hostname (common on Solaris) */ + if (*pieces == ':' && pieces[1] == ' ') { + /* Getting solaris 8/9 messages without hostname. + * In these cases, the process_name should be there. + * http://www.theopenarmor.org/wiki/index.php/Log_Samples_Solaris + */ + lf->program_name = lf->hostname; + lf->hostname = NULL; + + /* End the program name string */ + *pieces = '\0'; + + pieces += 2; + lf->log = pieces; + } + + /* Extract the hostname */ + else if (*pieces != ' ') { + /* Invalid hostname */ + lf->hostname = NULL; + pieces = NULL; + } else { + /* End the hostname string */ + *pieces = '\0'; + + /* Move pieces to the beginning of the log message */ + pieces++; + lf->log = pieces; + + /* Get program_name */ + lf->program_name = pieces; + + /* Extract program_name */ + /* Valid names: + * p_name: + * p_name[pid]: + * p_name[pid]: [ID xx facility.severity] + * auth|security:info p_name: + */ + while (isValidChar(*pieces) == 1) { + pieces++; + } + + /* Check for the first format: p_name: */ + if ((*pieces == ':') && (pieces[1] == ' ')) { + *pieces = '\0'; + pieces += 2; + } + + /* Check for the second format: p_name[pid]: */ + else if ((*pieces == '[') && (isdigit((int)pieces[1]))) { + *pieces = '\0'; + pieces += 2; + while (isdigit((int)*pieces)) { + pieces++; + } + + if ((*pieces == ']') && (pieces[1] == ':') && (pieces[2] == ' ')) { + pieces += 3; + } + /* Some systems are not terminating the program name with + * a ':'. Working around this in here... + */ + else if ((*pieces == ']') && (pieces[1] == ' ')) { + pieces += 2; + } else { + /* Fix for some weird log formats */ + pieces--; + while (isdigit((int)*pieces)) { + pieces--; + } + + if (*pieces == '\0') { + *pieces = '['; + } + pieces = NULL; + lf->program_name = NULL; + } + } + /* AIX syslog */ + else if ((*pieces == '|') && islower((int)pieces[1])) { + pieces += 2; + + /* Remove facility */ + while (isalnum((int)*pieces)) { + pieces++; + } + + if (*pieces == ':') { + /* Remove severity */ + pieces++; + while (isalnum((int)*pieces)) { + pieces++; + } + + if (*pieces == ' ') { + pieces++; + lf->program_name = pieces; + + + /* Get program name again */ + while (isValidChar(*pieces) == 1) { + pieces++; + } + + /* Check for the first format: p_name: */ + if ((*pieces == ':') && (pieces[1] == ' ')) { + *pieces = '\0'; + pieces += 2; + } + + /* Check for the second format: p_name[pid]: */ + else if ((*pieces == '[') && (isdigit((int)pieces[1]))) { + *pieces = '\0'; + pieces += 2; + while (isdigit((int)*pieces)) { + pieces++; + } + + if ((*pieces == ']') && (pieces[1] == ':') && + (pieces[2] == ' ')) { + pieces += 3; + } else { + pieces = NULL; + } + } + } else { + pieces = NULL; + lf->program_name = NULL; + } + } + /* Invalid AIX */ + else { + pieces = NULL; + lf->program_name = NULL; + } + } else { + pieces = NULL; + lf->program_name = NULL; + } + } + + /* Remove [ID xx facility.severity] */ + if (pieces) { + /* Set log after program name */ + lf->log = pieces; + + if ((pieces[0] == '[') && + (pieces[1] == 'I') && + (pieces[2] == 'D') && + (pieces[3] == ' ')) { + pieces += 4; + + /* Going after the "] " */ + pieces = strstr(pieces, "] "); + if (pieces) { + pieces += 2; + lf->log = pieces; + } + } + } + + /* Get program name size */ + if (lf->program_name) { + lf->p_name_size = strlen(lf->program_name); + } + } + + /* xferlog date format + * Mon Apr 17 18:27:14 2006 1 64.160.42.130 + */ + else if ((loglen > 28) && + (pieces[3] == ' ') && + (pieces[7] == ' ') && + (pieces[10] == ' ') && + (pieces[13] == ':') && + (pieces[16] == ':') && + (pieces[19] == ' ') && + (pieces[24] == ' ') && + (pieces[26] == ' ')) { + /* Move log to the beginning of the message */ + lf->log += 24; + } + + /* Check for snort date format + * ex: 01/28-09:13:16.240702 [**] + */ + else if ( (loglen > 24) && + (pieces[2] == '/') && + (pieces[5] == '-') && + (pieces[8] == ':') && + (pieces[11] == ':') && + (pieces[14] == '.') && + (pieces[21] == ' ') ) { + lf->log += 23; + } + + /* Check for suricata (new) date format + * ex: 01/28/1979-09:13:16.240702 [**] + */ + else if ( (loglen > 26) && + (pieces[2] == '/') && + (pieces[5] == '/') && + (pieces[10] == '-') && + (pieces[13] == ':') && + (pieces[16] == ':') && + (pieces[19] == '.') && + (pieces[26] == ' ') ) { + lf->log += 28; + } + + + /* Check for apache log format */ + /* [Fri Feb 11 18:06:35 2004] [warn] */ + else if ( (loglen > 27) && + (pieces[0] == '[') && + (pieces[4] == ' ') && + (pieces[8] == ' ') && + (pieces[11] == ' ') && + (pieces[14] == ':') && + (pieces[17] == ':') && + (pieces[20] == ' ') && + (pieces[25] == ']') ) { + lf->log += 27; + } + + /* Check for the osx asl log format. + * Examples: + * [Time 2006.12.28 15:53:55 UTC] [Facility auth] [Sender sshd] [PID 483] [Message error: PAM: Authentication failure for username from 192.168.0.2] [Level 3] [UID -2] [GID -2] [Host Hostname] + * [Time 2006.11.02 14:02:11 UTC] [Facility auth] [Sender sshd] [PID 856] + [Message refused connect from 59.124.44.34] [Level 4] [UID -2] [GID -2] + [Host robert-wyatts-emac] + */ + else if ((loglen > 26) && + (pieces[0] == '[') && + (pieces[1] == 'T') && + (pieces[5] == ' ') && + (pieces[10] == '.') && + (pieces[13] == '.') && + (pieces[16] == ' ') && + (pieces[19] == ':')) { + /* Do not read more than 1 message entry -> log tampering */ + short unsigned int done_message = 0; + + /* Remove the date */ + lf->log += 25; + + /* Get the desired values */ + pieces = strchr(lf->log, '['); + while (pieces) { + pieces++; + + /* Get the sender (set to program name) */ + if ((strncmp(pieces, "Sender ", 7) == 0) && + (lf->program_name == NULL)) { + pieces += 7; + lf->program_name = pieces; + + /* Get the closing brackets */ + pieces = strchr(pieces, ']'); + if (pieces) { + *pieces = '\0'; + + /* Set program_name size */ + lf->p_name_size = strlen(lf->program_name); + + pieces++; + } + /* Invalid program name */ + else { + lf->program_name = NULL; + break; + } + } + + /* Get message */ + else if ((strncmp(pieces, "Message ", 8) == 0) && + (done_message == 0)) { + pieces += 8; + done_message = 1; + + lf->log = pieces; + + /* Get the closing brackets */ + pieces = strchr(pieces, ']'); + if (pieces) { + *pieces = '\0'; + pieces++; + } + /* Invalid log closure */ + else { + break; + } + } + + /* Get hostname */ + else if (strncmp(pieces, "Host ", 5) == 0) { + pieces += 5; + lf->hostname = pieces; + + /* Get the closing brackets */ + pieces = strchr(pieces, ']'); + if (pieces) { + *pieces = '\0'; + pieces++; + } + + /* Invalid hostname */ + else { + lf->hostname = NULL; + } + break; + } + + /* Get next entry */ + pieces = strchr(pieces, '['); + } + } + + /* Check for squid date format + * 1140804070.368 11623 + * seconds from 00:00:00 1970-01-01 UTC + */ + else if ((loglen > 32) && + (pieces[0] == '1') && + (isdigit((int)pieces[1])) && + (isdigit((int)pieces[2])) && + (isdigit((int)pieces[3])) && + (pieces[10] == '.') && + (isdigit((int)pieces[13])) && + (pieces[14] == ' ') && + ((pieces[21] == ' ') || (pieces[22] == ' '))) { + lf->log += 14; + + /* We need to start at the size of the event */ + while (*lf->log == ' ') { + lf->log++; + } + } + + /* Every message must be in the format + * hostname->location or + * (agent) ip->location. + */ + + /* Set hostname for local messages */ + if (lf->location[0] == '(') { + /* Messages from an agent */ + lf->hostname = lf->location; + } else if (lf->hostname == NULL) { + lf->hostname = __shost; + } + + /* Set up the event data */ + lf->time = c_time; + p = localtime(&c_time); + + /* Assign hour, day, year and month values */ + lf->day = p->tm_mday; + lf->year = p->tm_year + 1900; + strncpy(lf->mon, month[p->tm_mon], 3); + snprintf(lf->hour, 9, "%02d:%02d:%02d", + p->tm_hour, + p->tm_min, + p->tm_sec); + + /* Set the global hour/weekday */ + __crt_hour = p->tm_hour; + __crt_wday = p->tm_wday; + +#ifdef TESTRULE + if (!alert_only) { + print_out("**Phase 1: Completed pre-decoding."); + print_out(" full event: '%s'", lf->full_log); + print_out(" hostname: '%s'", lf->hostname); + print_out(" program_name: '%s'", lf->program_name); + print_out(" log: '%s'", lf->log); + } +#endif + return (0); +} + diff --git a/src/analysisd/cleanevent.h b/src/analysisd/cleanevent.h new file mode 100644 index 000000000..b93ddcc02 --- /dev/null +++ b/src/analysisd/cleanevent.h @@ -0,0 +1,18 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _CLEANEVENT_H_ +#define _CLEANEVENT_H_ + +#include "eventinfo.h" + +int OS_CleanMSG(char *msg, Eventinfo *lf); + + +#endif /* _CLEANEVENT_H_ */ diff --git a/src/analysisd/compiled_rules/.function_list b/src/analysisd/compiled_rules/.function_list new file mode 100644 index 000000000..e25c103c6 --- /dev/null +++ b/src/analysisd/compiled_rules/.function_list @@ -0,0 +1,5 @@ +check_id_size +comp_srcuser_dstuser +comp_mswin_targetuser_calleruser_diff +is_simple_http_request +is_valid_crawler diff --git a/src/analysisd/compiled_rules/generic_samples.c b/src/analysisd/compiled_rules/generic_samples.c new file mode 100644 index 000000000..d87167e4e --- /dev/null +++ b/src/analysisd/compiled_rules/generic_samples.c @@ -0,0 +1,189 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "eventinfo.h" +#include "shared.h" +#include "config.h" + +#include +#include +#include + +/* Note: If the rule fails to match it should return NULL. + * If you want processing to continue, return lf (the eventinfo structure). + */ + +/* Example 1: Comparing if the srcuser and dstuser are the same + * If they are the same, return true + * If any of them is not set, return true too + */ +void *comp_srcuser_dstuser(Eventinfo *lf) +{ + if (!lf->srcuser || !lf->dstuser) { + return (lf); + } + + if (strcmp(lf->srcuser, lf->dstuser) == 0) { + return (lf); + } + + /* In here, srcuser and dstuser are present and are different */ + return (NULL); +} + +/* Example 2: Checking if the size of the id field is larger than 10 */ +void *check_id_size(Eventinfo *lf) +{ + if (!lf->id) { + return (NULL); + } + + if (strlen(lf->id) >= 10) { + return (lf); + } + + return (NULL); +} + +/* Example 3: Comparing the Target Account Name and Caller User Name on Windows logs + * It will return NULL (not match) if any of these values + * are not present or if they are the same. + * This function will return TRUE if they are NOT the same. + */ +void *comp_mswin_targetuser_calleruser_diff(Eventinfo *lf) +{ + char *target_user; + char *caller_user; + + target_user = strstr(lf->log, "Target Account Name"); + caller_user = strstr(lf->log, "Caller User Name"); + + if (!target_user || !caller_user) { + return (NULL); + } + + /* We need to clear each user type and finish the string. + * It looks like: + * Target Account Name: account\t + * Caller User Name: account\t + */ + target_user = strchr(target_user, ':'); + caller_user = strchr(caller_user, ':'); + + if (!target_user || !caller_user) { + return (NULL); + } + + target_user++; + caller_user++; + + while (*target_user != '\0') { + if (*target_user != *caller_user) { + return (lf); + } + + if (*target_user == '\t' || + (*target_user == ' ' && target_user[1] == ' ')) { + break; + } + + target_user++; + caller_user++; + } + + /* If we got in here, the accounts are the same. + * So, we return NULL since we only want to alert if they are different. + */ + return (NULL); +} + +/* Example 4: Checking if a HTTP request is a simple GET/POST without a query + * This avoid that we call the attack rules for no reason. + */ +void *is_simple_http_request(Eventinfo *lf) +{ + + if (!lf->url) { + return (NULL); + } + + /* Simple GET / request */ + if (strcmp(lf->url, "/") == 0) { + return (lf); + } + + /* Simple request, no query */ + if (!strchr(lf->url, '?')) { + return (lf); + } + + /* In here, we have an additional query to be checked */ + return (NULL); +} + +/* Example 5: Checking if the source IP is from a valid bot */ +void *is_valid_crawler(Eventinfo *lf) +{ + if((strncmp(lf->log, "72.14.",6) == 0)|| /* Feedfetcher-Google */ + (strncmp(lf->log, "209.85.", 7) == 0) || /* Feedfetcher-Google */ + (strncmp(lf->log, "65.55.", 6) == 0) || /* MSN/Bing */ + (strncmp(lf->log, "207.46.", 7) == 0) || /* MSN/Bing */ + (strncmp(lf->log, "74.6.", 5) == 0) || /* Yahoo */ + (strncmp(lf->log, "72.30.", 6) == 0) || /* Yahoo */ + (strncmp(lf->log, "67.195.", 7) == 0) /* Yahoo */ + ) { + return (lf); + } + + // In order to verify a googlebot crawler, Google recommends doing a + // reverse DNS lookup, and then a forward DNS lookup to verify that + // + // 1. The host is in the googlebot.com domain + // 2. The forward and reverse lookups match. + // + // https://support.google.com/webmasters/answer/80553 + + struct sockaddr_in sa; + char hostname[NI_MAXHOST]; + + sa.sin_family = AF_INET; + inet_aton(lf->log, &sa.sin_addr); + + // Do the reverse DNS lookup + if (getnameinfo((struct sockaddr*)&sa, sizeof sa, hostname, sizeof hostname, NULL, 0, 0) == 0) { + + // verify that the host is in the googlebot.com domain. + char *start = strstr(hostname, "googlebot.com"); + if (start != NULL) { + struct addrinfo hints, *res, *p; + char ipstr[INET6_ADDRSTRLEN]; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + // Do the forward DNS lookup + if (getaddrinfo(hostname, NULL, &hints, &res) == 0) { + for (p = res; p != NULL; p = p->ai_next) { + struct sockaddr_in *ipv4 = (struct sockaddr_in*)p->ai_addr; + void *addr = &(ipv4->sin_addr); + inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr); + // Make sure the forward & reverse lookups match + if (strcmp(ipstr, lf->log) == 0) { + return(lf); + } + } + freeaddrinfo(res); + } + } + } + + return (NULL); +} + diff --git a/src/analysisd/compiled_rules/register_rule.sh b/src/analysisd/compiled_rules/register_rule.sh new file mode 100644 index 000000000..88b74ad3b --- /dev/null +++ b/src/analysisd/compiled_rules/register_rule.sh @@ -0,0 +1,175 @@ +#!/bin/sh + +# Variables - do not modify them +CHF="compiled_rules.h" + +# Checking the location. +ls -la register_rule.sh > /dev/null 2>&1 +if [ ! $? = 0 ]; then + LOCALDIR=`dirname $0`; + cd ${LOCALDIR} + + ls -la register_rule.sh > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: You must run this script from the same directory." + exit 1; + fi +fi + +# Arguments +if [ "x$1" = "x" -o "x$1" = "xhelp" -o "x$1" = "x-h" ]; then + echo "$0 add " + echo "$0 list" + echo "$0 build" + echo "$0 save" + echo "$0 restore" + exit 0; +fi + +if [ "x$1" = "xlist" ]; then + echo "*Available functions: " + cat .function_list | sort | uniq; + exit 0; + +elif [ "x$1" = "xsave" ]; then + ls -la /etc/openarmor-init.conf > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to save rules. You must have openarmor installed to do so." + exit 1; + fi + + cat /etc/openarmor-init.conf > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to save rules. You must be root to do so." + exit 1; + fi + + . /etc/openarmor-init.conf + + ls ${DIRECTORY}/compiled_rules > /dev/null 2>&1 + if [ ! $? = 0 ]; then + mkdir ${DIRECTORY}/compiled_rules > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to save rules. You must be root to do so." + exit 1; + fi + fi + + cp .function_list ${DIRECTORY}/compiled_rules/function_list > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to save rules. You must be root to do so." + exit 1; + fi + + for i in `ls *.c`; do + if [ ! "x$i" = "xgeneric_samples.c" ]; then + cp $i ${DIRECTORY}/compiled_rules/ > /dev/null 2>&1 + fi + done + echo "*Save completed at ${DIRECTORY}/compiled_rules/"; + exit 0; + +elif [ "x$1" = "xrestore" ]; then + + ls -la /etc/openarmor-init.conf > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to restore rules. You must have openarmor installed to do so." + exit 1; + fi + + cat /etc/openarmor-init.conf > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to restore rules. You must be root to do so." + exit 1; + fi + + . /etc/openarmor-init.conf + + ls ${DIRECTORY}/compiled_rules/function_list > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "*No local compiled rules available to restore." + exit 0; + fi + + cat ${DIRECTORY}/compiled_rules/function_list >> .function_list + if [ ! $? = 0 ]; then + echo "ERROR: Unable to restore rules. Function list not present." + exit 1; + fi + + for i in `ls ${DIRECTORY}/compiled_rules/*.c`; do + if [ ! "x$i" = "xgeneric_samples.c" ]; then + cp $i ./ > /dev/null 2>&1 + fi + done + echo "*Restore completed from ${DIRECTORY}/compiled_rules/"; + exit 0; + +elif [ "x$1" = "xbuild" ]; then + ls -la .function_list > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Unable to build. No function is registered." + exit 1; + fi + + # Auto generating the file. + echo "/* This file is auto generated by $0. Do not touch it. */" > ${CHF} + echo "" >> ${CHF}; + + echo "/* Adding the function definitions. */" >> ${CHF}; + for i in `cat .function_list | sort| uniq`; do + echo "void *$i(Eventinfo *lf);" >> ${CHF}; + done + echo "" >> ${CHF}; + + echo "/* Adding the rules list. */" >> ${CHF}; + echo "void *(compiled_rules_list[]) = " >> ${CHF}; + echo "{" >> ${CHF}; + for i in `cat .function_list | sort| uniq`; do + echo " $i," >> ${CHF}; + done + echo " NULL" >> ${CHF}; + echo "};" >> ${CHF}; + echo "" >> ${CHF}; + + echo "/* Adding the rules list names. */" >> ${CHF}; + echo "const char *(compiled_rules_name[]) = " >> ${CHF}; + echo "{" >> ${CHF}; + for i in `cat .function_list |sort | uniq`; do + echo " \"$i\"," >> ${CHF}; + done + echo " NULL" >> ${CHF}; + echo "};" >> ${CHF}; + echo "" >> ${CHF}; + echo "/* EOF */" >> ${CHF}; + + echo "*Build completed." + +elif [ "x$1" = "xadd" ]; then + if [ "x$2" = "x" ]; then + echo "ERROR: Missing function name."; + echo "ex: $0 add "; + exit 1; + fi + + grep $2 ./*.c > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "ERROR: Function '$2' not found."; + exit 1; + fi + + grep $2 .function_list > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "ERROR: Function '$2' already added."; + exit 1; + fi + + echo $2 >> .function_list; + echo "*Function $2 added." + +else + echo "ERROR: Invalid argument."; + exit 1; + +fi + diff --git a/src/analysisd/config.c b/src/analysisd/config.c new file mode 100644 index 000000000..e16f63e8d --- /dev/null +++ b/src/analysisd/config.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Functions to handle the configuration files */ + +#include "shared.h" +#include "os_xml/os_xml.h" +#include "os_regex/os_regex.h" +#include "analysisd.h" +#include "config.h" + +long int __crt_ftell; /* Global ftell pointer */ +_Config Config; /* Global Config structure */ + +int GlobalConf(const char *cfgfile) +{ + int modules = 0; + + /* Default values */ + Config.logall = 0; + Config.logall_json = 0; + Config.stats = 4; + Config.integrity = 8; + Config.rootcheck = 8; + Config.hostinfo = 8; + Config.prelude = 0; + Config.zeromq_output = 0; + Config.zeromq_output_uri = NULL; + Config.zeromq_output_server_cert = NULL; + Config.zeromq_output_client_cert = NULL; + Config.jsonout_output = 0; + Config.memorysize = 8192; + Config.mailnotify = -1; + Config.keeplogdate = 0; + Config.syscheck_alert_new = 0; + Config.syscheck_auto_ignore = 1; + Config.ar = 0; + + Config.syscheck_ignore = NULL; + Config.allow_list = NULL; + Config.hostname_allow_list = NULL; + + /* Default actions -- only log above level 1 */ + Config.mailbylevel = 7; + Config.logbylevel = 1; + + Config.custom_alert_output = 0; + Config.custom_alert_output_format = NULL; + + Config.includes = NULL; + Config.lists = NULL; + Config.decoders = NULL; + + modules |= CGLOBAL; + modules |= CRULES; + modules |= CALERTS; + + /* Read config */ + if (ReadConfig(modules, cfgfile, &Config, NULL) < 0) { + return (OS_INVALID); + } + + /* Minimum memory size */ + if (Config.memorysize < 2048) { + Config.memorysize = 2048; + } + + return (0); +} diff --git a/src/analysisd/config.h b/src/analysisd/config.h new file mode 100644 index 000000000..976d1942e --- /dev/null +++ b/src/analysisd/config.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _CONFIG__H +#define _CONFIG__H + +#include "config/config.h" +#include "config/global-config.h" + +#ifdef LIBGEOIP_ENABLED +#include "GeoIP.h" +#endif + + +extern long int __crt_ftell; /* Global ftell pointer */ +extern _Config Config; /* Global Config structure */ + +/* +#ifdef LIBGEOIP_ENABLED +GeoIP *geoipdb; +#endif +*/ + +int GlobalConf(const char *cfgfile); + +#endif /* _CONFIG__H */ + diff --git a/src/analysisd/decoders/decode-xml.c b/src/analysisd/decoders/decode-xml.c new file mode 100644 index 000000000..1aa5b4a0f --- /dev/null +++ b/src/analysisd/decoders/decode-xml.c @@ -0,0 +1,873 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "os_regex/os_regex.h" +#include "os_xml/os_xml.h" +#include "analysisd.h" +#include "eventinfo.h" +#include "decoder.h" +#include "plugin_decoders.h" +#include "config.h" + + +#ifdef TESTRULE +#undef XML_LDECODER +#define XML_LDECODER "etc/local_decoder.xml" +#endif + +/* Internal functions */ +static char *_loadmemory(char *at, char *str); +static int addDecoder2list(const char *name); +static int os_setdecoderids(const char *p_name); +static int ReadDecodeAttrs(char *const *names, char *const *values); +static OSStore *os_decoder_store = NULL; + + +int getDecoderfromlist(const char *name) +{ + if (os_decoder_store) { + return (OSStore_GetPosition(os_decoder_store, name)); + } + + return (0); +} + +static int addDecoder2list(const char *name) +{ + if (os_decoder_store == NULL) { + os_decoder_store = OSStore_Create(); + if (os_decoder_store == NULL) { + merror(LIST_ERROR, ARGV0); + return (0); + } + } + + /* Store data */ + if (!OSStore_Put(os_decoder_store, name, NULL)) { + merror(LIST_ADD_ERROR, ARGV0); + return (0); + } + + return (1); +} + +static int os_setdecoderids(const char *p_name) +{ + OSDecoderNode *node; + OSDecoderNode *child_node; + OSDecoderInfo *nnode; + + node = OS_GetFirstOSDecoder(p_name); + + if (!node) { + return (0); + } + + do { + int p_id = 0; + char *tmp_name; + + nnode = node->osdecoder; + nnode->id = getDecoderfromlist(nnode->name); + + /* Id cannot be 0 */ + if (nnode->id == 0) { + return (0); + } + + child_node = node->child; + + if (!child_node) { + continue; + } + + /* Set parent id */ + p_id = nnode->id; + tmp_name = nnode->name; + + /* Also set on the child nodes */ + while (child_node) { + nnode = child_node->osdecoder; + + if (nnode->use_own_name) { + nnode->id = getDecoderfromlist(nnode->name); + } else { + nnode->id = p_id; + + /* Set parent name */ + free(nnode->name); + nnode->name = strdup(tmp_name); + } + + /* Id cannot be 0 */ + if (nnode->id == 0) { + return (0); + } + child_node = child_node->next; + } + } while ((node = node->next) != NULL); + + return (1); +} + +static int ReadDecodeAttrs(char *const *names, char *const *values) +{ + if (!names || !values) { + return (0); + } + + if (!names[0] || !values[0]) { + return (0); + } + + if (strcmp(names[0], "offset") == 0) { + int offset = 0; + + /* Offsets can be: after_parent, after_prematch + * or after_regex. + */ + if (strcmp(values[0], "after_parent") == 0) { + offset |= AFTER_PARENT; + } else if (strcmp(values[0], "after_prematch") == 0) { + offset |= AFTER_PREMATCH; + } else if (strcmp(values[0], "after_regex") == 0) { + offset |= AFTER_PREVREGEX; + } else { + merror(INV_OFFSET, ARGV0, values[0]); + offset |= AFTER_ERROR; + } + + return (offset); + } + + /* Invalid attribute */ + merror(INV_ATTR, ARGV0, names[0]); + return (AFTER_ERROR); +} + +int ReadDecodeXML(const char *file) +{ + OS_XML xml; + XML_NODE node = NULL; + + /* XML variables */ + /* These are the available options for the rule configuration */ + + const char *xml_plugindecoder = "plugin_decoder"; + const char *xml_decoder = "decoder"; + const char *xml_decoder_name = "name"; + const char *xml_decoder_status = "status"; + const char *xml_usename = "use_own_name"; + const char *xml_parent = "parent"; + const char *xml_program_name = "program_name"; + const char *xml_prematch = "prematch"; + const char *xml_regex = "regex"; + const char *xml_program_name_pcre2 = "program_name_pcre2"; + const char *xml_prematch_pcre2 = "prematch_pcre2"; + const char *xml_pcre2 = "pcre2"; + const char *xml_order = "order"; + const char *xml_type = "type"; + const char *xml_fts = "fts"; + const char *xml_ftscomment = "ftscomment"; + const char *xml_accumulate = "accumulate"; + + int i = 0; + OSDecoderInfo *NULL_Decoder_tmp = NULL; + + /* Read the XML */ + if ((i = OS_ReadXML(file, &xml)) < 0) { + if ((i == -2) && (strcmp(file, XML_LDECODER) == 0)) { + return (-2); + } + + merror(XML_ERROR, ARGV0, file, xml.err, xml.err_line); + return (0); + } + + /* Apply any variables found */ + if (OS_ApplyVariables(&xml) != 0) { + merror(XML_ERROR_VAR, ARGV0, file, xml.err); + return (0); + } + + /* Get the root elements */ + node = OS_GetElementsbyNode(&xml, NULL); + if (!node) { + if (strcmp(file, XML_LDECODER) != 0) { + merror(XML_ELEMNULL, ARGV0); + return (0); + } + + return (-2); + } + + /* Zero NULL_decoder */ + if (!NULL_Decoder) { + os_calloc(1, sizeof(OSDecoderInfo), NULL_Decoder_tmp); + NULL_Decoder_tmp->id = 0; + NULL_Decoder_tmp->type = SYSLOG; + NULL_Decoder_tmp->name = NULL; + NULL_Decoder_tmp->fts = 0; + NULL_Decoder = NULL_Decoder_tmp; + } + + i = 0; + while (node[i]) { + XML_NODE elements = NULL; + OSDecoderInfo *pi; + + int j = 0; + char *regex; + char *prematch; + char *p_name; + char *pcre2; + char *prematch_pcre2; + char *p_name_pcre2; + + if (!node[i]->element || + strcasecmp(node[i]->element, xml_decoder) != 0) { + if (node[i]->element != NULL) { + merror(XML_INVELEM, ARGV0, node[i]->element); + } else { + merror(XML_INVELEM, ARGV0, "unknown"); + } + return (0); + } + + /* Get name */ + if ((!node[i]->attributes) || (!node[i]->values) || + (!node[i]->values[0]) || (!node[i]->attributes[0]) || + (strcasecmp(node[i]->attributes[0], xml_decoder_name) != 0)) { + merror(XML_INVELEM, ARGV0, node[i]->element); + return (0); + } + + /* Check for additional entries */ + if (node[i]->attributes[1] && node[i]->values[1]) { + if (strcasecmp(node[i]->attributes[0], xml_decoder_status) != 0) { + merror(XML_INVELEM, ARGV0, node[i]->element); + return (0); + } + + if (node[i]->attributes[2]) { + merror(XML_INVELEM, ARGV0, node[i]->element); + return (0); + } + } + + /* Get decoder options */ + elements = OS_GetElementsbyNode(&xml, node[i]); + if (elements == NULL) { + merror(XML_ELEMNULL, ARGV0); + return (0); + } + + /* Create the OSDecoderInfo */ + pi = (OSDecoderInfo *)calloc(1, sizeof(OSDecoderInfo)); + if (pi == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (0); + } + + /* Default values to the list */ + pi->parent = NULL; + pi->id = 0; + pi->name = strdup(node[i]->values[0]); + pi->order = NULL; + pi->plugindecoder = NULL; + pi->fts = 0; + pi->accumulate = 0; + pi->type = SYSLOG; + pi->prematch = NULL; + pi->program_name = NULL; + pi->regex = NULL; + pi->prematch_pcre2 = NULL; + pi->program_name_pcre2 = NULL; + pi->pcre2 = NULL; + pi->use_own_name = 0; + pi->get_next = 0; + pi->regex_offset = 0; + pi->prematch_offset = 0; + + regex = NULL; + prematch = NULL; + p_name = NULL; + pcre2 = NULL; + prematch_pcre2 = NULL; + p_name_pcre2 = NULL; + + /* Check if strdup worked */ + if (!pi->name) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (0); + } + + /* Add decoder */ + if (!addDecoder2list(pi->name)) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + free(pi->name); + free(pi); + return (0); + } + + /* Loop over all the elements */ + while (elements[j]) { + if (!elements[j]->element) { + merror(XML_ELEMNULL, ARGV0); + return (0); + } else if (!elements[j]->content) { + merror(XML_VALUENULL, ARGV0, elements[j]->element); + return (0); + } + + /* Check if it is a child of a rule */ + else if (strcasecmp(elements[j]->element, xml_parent) == 0) { + pi->parent = _loadmemory(pi->parent, elements[j]->content); + } + + /* Get the regex */ + else if (strcasecmp(elements[j]->element, xml_regex) == 0) { + int r_offset; + r_offset = ReadDecodeAttrs(elements[j]->attributes, + elements[j]->values); + + if (r_offset & AFTER_ERROR) { + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + /* Only the first regex entry may have an offset */ + if (regex && r_offset) { + merror(DUP_REGEX, ARGV0, pi->name); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + /* regex offset */ + if (r_offset) { + pi->regex_offset = r_offset; + } + + /* Assign regex */ + regex = + _loadmemory(regex, + elements[j]->content); + } + + /* Get the PCRE2 */ + else if (strcasecmp(elements[j]->element, xml_pcre2) == 0) { + int r_offset; + r_offset = ReadDecodeAttrs(elements[j]->attributes, + elements[j]->values); + + if (r_offset & AFTER_ERROR) { + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + /* Only the first regex entry may have an offset */ + if (pcre2 && r_offset) { + merror(DUP_REGEX, ARGV0, pi->name); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + /* regex offset */ + if (r_offset) { + pi->regex_offset = r_offset; + } + + /* Assign regex */ + pcre2 = + _loadmemory(pcre2, + elements[j]->content); + } + + /* Get the pre match */ + else if (strcasecmp(elements[j]->element, xml_prematch) == 0) { + int r_offset; + + r_offset = ReadDecodeAttrs( + elements[j]->attributes, + elements[j]->values); + + if (r_offset & AFTER_ERROR) { + ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name); + } + + /* Only the first prematch entry may have an offset */ + if (prematch && r_offset) { + merror(DUP_REGEX, ARGV0, pi->name); + ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name); + } + + if (r_offset) { + pi->prematch_offset = r_offset; + } + + prematch = + _loadmemory(prematch, + elements[j]->content); + } + else if (strcasecmp(elements[j]->element, xml_prematch_pcre2) == 0) { + int r_offset; + + r_offset = ReadDecodeAttrs( + elements[j]->attributes, + elements[j]->values); + + if (r_offset & AFTER_ERROR) { + ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name); + } + + /* Only the first prematch entry may have an offset */ + if (prematch_pcre2 && r_offset) { + merror(DUP_REGEX, ARGV0, pi->name); + ErrorExit(DEC_REGEX_ERROR, ARGV0, pi->name); + } + + if (r_offset) { + pi->prematch_offset = r_offset; + } + + prematch_pcre2 = + _loadmemory(prematch_pcre2, + elements[j]->content); + } + + /* Get program name */ + else if (strcasecmp(elements[j]->element, xml_program_name) == 0) { + p_name = _loadmemory(p_name, elements[j]->content); + } + else if (strcasecmp(elements[j]->element, xml_program_name_pcre2) == 0) { + p_name_pcre2 = _loadmemory(p_name_pcre2, elements[j]->content); + } + + /* Get the FTS comment */ + else if (strcasecmp(elements[j]->element, xml_ftscomment) == 0) { + } + + else if (strcasecmp(elements[j]->element, xml_usename) == 0) { + if (strcmp(elements[j]->content, "true") == 0) { + pi->use_own_name = 1; + } + } + + else if (strcasecmp(elements[j]->element, xml_plugindecoder) == 0) { + int ed_c = 0; + for (ed_c = 0; plugin_decoders[ed_c] != NULL; ed_c++) { + if (strcmp(plugin_decoders[ed_c], + elements[j]->content) == 0) { + /* Initialize plugin */ + void (*dec_init)(void) = (void (*)(void)) plugin_decoders_init[ed_c]; + dec_init(); + pi->plugindecoder = (void (*)(void *)) plugin_decoders_exec[ed_c]; + break; + } + } + + /* Decoder not found */ + if (pi->plugindecoder == NULL) { + merror(INV_DECOPTION, ARGV0, elements[j]->element, + elements[j]->content); + return (0); + } + } + + /* Get the type */ + else if (strcmp(elements[j]->element, xml_type) == 0) { + if (strcmp(elements[j]->content, "firewall") == 0) { + pi->type = FIREWALL; + } else if (strcmp(elements[j]->content, "ids") == 0) { + pi->type = IDS; + } else if (strcmp(elements[j]->content, "web-log") == 0) { + pi->type = WEBLOG; + } else if (strcmp(elements[j]->content, "syslog") == 0) { + pi->type = SYSLOG; + } else if (strcmp(elements[j]->content, "squid") == 0) { + pi->type = SQUID; + } else if (strcmp(elements[j]->content, "windows") == 0) { + pi->type = DECODER_WINDOWS; + } else if (strcmp(elements[j]->content, "host-information") == 0) { + pi->type = HOST_INFO; + } else if (strcmp(elements[j]->content, "openarmor") == 0) { + pi->type = openarmor_RL; + } else { + merror("%s: Invalid decoder type '%s'.", + ARGV0, elements[j]->content); + return (0); + } + } + + /* Get the order */ + else if (strcasecmp(elements[j]->element, xml_order) == 0) { + char **norder, **s_norder; + int order_int = 0; + + /* Maximum number for the order is limited by decoder_order_size */ + norder = OS_StrBreak(',', elements[j]->content, MAX_DECODER_ORDER_SIZE); + s_norder = norder; + os_calloc(Config.decoder_order_size, sizeof(void *), pi->order); + os_calloc(Config.decoder_order_size, sizeof(char *), pi->fields); + + order_int = 0; + + /* Check the values from the order */ + while (*norder) { + if (order_int >= Config.decoder_order_size) { + ErrorExit("%s: ERROR: Order has too many fields.", ARGV0); + } + + char *word = &(*norder)[strspn(*norder, " ")]; + word[strcspn(word, " ")] = '\0'; + + if (strlen(word) == 0) { + ErrorExit("decode-xml: Wrong field '%s' in the order" + " of decoder '%s'", *norder, pi->name); + } + + if (!strcmp(word, "dstuser")) { + pi->order[order_int] = DstUser_FP; + } else if (!strcmp(word, "srcuser")) { + pi->order[order_int] = SrcUser_FP; + } + /* User is an alias to dstuser */ + else if (!strcmp(word, "user")) { + pi->order[order_int] = DstUser_FP; + } else if (!strcmp(word, "srcip")) { + pi->order[order_int] = SrcIP_FP; + } else if (!strcmp(word, "dstip")) { + pi->order[order_int] = DstIP_FP; + } else if (!strcmp(word, "srcport")) { + pi->order[order_int] = SrcPort_FP; + } else if (!strcmp(word, "dstport")) { + pi->order[order_int] = DstPort_FP; + } else if (!strcmp(word, "protocol")) { + pi->order[order_int] = Protocol_FP; + } else if (!strcmp(word, "action")) { + pi->order[order_int] = Action_FP; + } else if (!strcmp(word, "id")) { + pi->order[order_int] = ID_FP; + } else if (!strcmp(word, "url")) { + pi->order[order_int] = Url_FP; + } else if (!strcmp(word, "data")) { + pi->order[order_int] = Data_FP; + } else if (!strcmp(word, "extra_data")) { + pi->order[order_int] = Data_FP; + } else if (!strcmp(word, "status")) { + pi->order[order_int] = Status_FP; + } else if (!strcmp(word, "system_name")) { + pi->order[order_int] = SystemName_FP; + } else if (strstr(*norder, "filename") != NULL) { + pi->order[order_int] = FileName_FP; + } else { + pi->order[order_int] = DynamicField_FP; + pi->fields[order_int] = strdup(*norder); + if (pi->fields[order_int][0] == ' ') { + pi->fields[order_int]++; + } + } + + free(*norder); + norder++; + + order_int++; + } + + free(s_norder); + } + + else if (strcasecmp(elements[j]->element, xml_accumulate) == 0) { + /* Enable Accumulator */ + pi->accumulate = 1; + } + + /* Get the FTS order */ + else if (strcasecmp(elements[j]->element, xml_fts) == 0) { + char **norder; + char **s_norder; + + /* Maximum number is 8 for the FTS */ + norder = OS_StrBreak(',', elements[j]->content, 8); + if (norder == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Save the initial point to free later */ + s_norder = norder; + + /* Check the values from the FTS */ + while (*norder) { + if (strstr(*norder, "dstuser") != NULL) { + pi->fts |= FTS_DSTUSER; + } + if (strstr(*norder, "user") != NULL) { + pi->fts |= FTS_DSTUSER; + } else if (strstr(*norder, "srcuser") != NULL) { + pi->fts |= FTS_SRCUSER; + } else if (strstr(*norder, "srcip") != NULL) { + pi->fts |= FTS_SRCIP; + } else if (strstr(*norder, "dstip") != NULL) { + pi->fts |= FTS_DSTIP; + } else if (strstr(*norder, "id") != NULL) { + pi->fts |= FTS_ID; + } else if (strstr(*norder, "location") != NULL) { + pi->fts |= FTS_LOCATION; + } else if (strstr(*norder, "data") != NULL) { + pi->fts |= FTS_DATA; + } else if (strstr(*norder, "extra_data") != NULL) { + pi->fts |= FTS_DATA; + } else if (strstr(*norder, "system_name") != NULL) { + pi->fts |= FTS_SYSTEMNAME; + } else if (strstr(*norder, "name") != NULL) { + pi->fts |= FTS_NAME; + } else { + ErrorExit("decode-xml: Wrong field '%s' in the fts" + " decoder '%s'", *norder, pi->name); + } + + free(*norder); + norder++; + } + + /* Clear memory here */ + free(s_norder); + } else { + merror("%s: Invalid element '%s' for " + "decoder '%s'", + ARGV0, + elements[j]->element, + node[i]->element); + return (0); + } + + /* NEXT */ + j++; + + } /* while(elements[j]) */ + + OS_ClearNode(elements); + + + /* Prematch must be set */ + if (!(prematch || prematch_pcre2) && !pi->parent && !(p_name || p_name_pcre2)) { + merror(DECODE_NOPRE, ARGV0, pi->name); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + /* If pi->regex is not set, fts must not be set too */ + if ((!(regex || pcre2) && (pi->fts || pi->order)) || ((regex || pcre2) && !pi->order)) { + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + /* For the offsets */ + if ((pi->regex_offset & AFTER_PARENT) && !pi->parent) { + merror(INV_OFFSET, ARGV0, "after_parent"); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + + if (pi->regex_offset & AFTER_PREMATCH) { + /* If after_prematch is set, but rule have + * no parent, set AFTER_PARENT and unset + * pre_match. + */ + if (!pi->parent) { + pi->regex_offset = 0; + pi->regex_offset |= AFTER_PARENT; + } else if (!(prematch || prematch_pcre2)) { + merror(INV_OFFSET, ARGV0, "after_prematch"); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + } + + /* For the after_regex offset */ + if (pi->regex_offset & AFTER_PREVREGEX) { + if (!pi->parent || !(regex || pcre2)) { + merror(INV_OFFSET, ARGV0, "after_regex"); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + } + + /* Check the prematch offset */ + if (pi->prematch_offset) { + /* Only the after parent is allowed */ + if (pi->prematch_offset & AFTER_PARENT) { + if (!pi->parent) { + merror(INV_OFFSET, ARGV0, "after_parent"); + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + } else { + merror(DEC_REGEX_ERROR, ARGV0, pi->name); + return (0); + } + } + + /* Compile the regex/prematch */ + if (prematch) { + os_calloc(1, sizeof(OSRegex), pi->prematch); + if (!OSRegex_Compile(prematch, pi->prematch, 0)) { + merror(REGEX_COMPILE, ARGV0, prematch, pi->prematch->error); + return (0); + } + + free(prematch); + } + else if (prematch_pcre2) { + os_calloc(1, sizeof(OSPcre2), pi->prematch_pcre2); + if (!OSPcre2_Compile(prematch_pcre2, pi->prematch_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, prematch_pcre2, pi->prematch_pcre2->error); + return (0); + } + + free(prematch_pcre2); + } + + /* Compile the p_name */ + if (p_name) { + os_calloc(1, sizeof(OSMatch), pi->program_name); + if (!OSMatch_Compile(p_name, pi->program_name, 0)) { + merror(REGEX_COMPILE, ARGV0, p_name, pi->program_name->error); + return (0); + } + + free(p_name); + } + else if (p_name_pcre2) { + os_calloc(1, sizeof(OSPcre2), pi->program_name_pcre2); + if (!OSPcre2_Compile(p_name_pcre2, pi->program_name_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, p_name_pcre2, pi->program_name_pcre2->error); + return (0); + } + + free(p_name_pcre2); + } + + /* We may not have the pi->regex */ + if (regex) { + os_calloc(1, sizeof(OSRegex), pi->regex); + if (!OSRegex_Compile(regex, pi->regex, OS_RETURN_SUBSTRING)) { + merror(REGEX_COMPILE, ARGV0, regex, pi->regex->error); + return (0); + } + + /* We must have the sub_strings to retrieve the nodes */ + if (!pi->regex->sub_strings) { + merror(REGEX_SUBS, ARGV0, regex); + return (0); + } + + free(regex); + } + else if (pcre2) { + os_calloc(1, sizeof(OSPcre2), pi->pcre2); + if (!OSPcre2_Compile(pcre2, pi->pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, pcre2, pi->pcre2->error); + return (0); + } + + free(pcre2); + } + + /* Validate arguments */ + if (pi->plugindecoder && (pi->regex || pi->order)) { + merror(DECODE_ADD, ARGV0, pi->name); + return (0); + } + + /* Add osdecoder to the list */ + if (!OS_AddOSDecoder(pi)) { + merror(DECODER_ERROR, ARGV0); + return (0); + } + + i++; + } /* while (node[i]) */ + + + /* Clean node and XML structures */ + OS_ClearNode(node); + OS_ClearXML(&xml); + + return (1); +} + +int SetDecodeXML() +{ + /* Add rootcheck decoder to list */ + addDecoder2list(ROOTCHECK_MOD); + addDecoder2list(SYSCHECK_MOD); + addDecoder2list(SYSCHECK_MOD2); + addDecoder2list(SYSCHECK_MOD3); + addDecoder2list(SYSCHECK_NEW); + addDecoder2list(SYSCHECK_DEL); + addDecoder2list(HOSTINFO_NEW); + addDecoder2list(HOSTINFO_MOD); + + /* Set ids - for our two lists */ + if (!os_setdecoderids(NULL)) { + merror(DECODER_ERROR, ARGV0); + return (0); + } + if (!os_setdecoderids(ARGV0)) { + merror(DECODER_ERROR, ARGV0); + return (0); + } + + return (1); +} + +/* Allocate memory at "*at" and copy *str to it + * If *at already exist, realloc the memory and cat str on it + * Returns the new string + */ +char *_loadmemory(char *at, char *str) +{ + if (at == NULL) { + size_t strsize = 0; + if ((strsize = strlen(str)) < OS_SIZE_8192) { + at = (char *) calloc(strsize + 1, sizeof(char)); + if (at == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + strncpy(at, str, strsize); + return (at); + } else { + merror(SIZE_ERROR, ARGV0, str); + return (NULL); + } + } + /* At is not null. Need to reallocate its memory and copy str to it */ + else { + size_t strsize = strlen(str); + size_t atsize = strlen(at); + size_t finalsize = atsize + strsize + 1; + if (finalsize > OS_SIZE_8192) { + merror(SIZE_ERROR, ARGV0, str); + return (NULL); + } + at = (char *) realloc(at, (finalsize + 1) * sizeof(char)); + if (at == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + strncat(at, str, strsize); + at[finalsize - 1] = '\0'; + + return (at); + } + return (NULL); +} diff --git a/src/analysisd/decoders/decoder.c b/src/analysisd/decoders/decoder.c new file mode 100644 index 000000000..cc20b1a80 --- /dev/null +++ b/src/analysisd/decoders/decoder.c @@ -0,0 +1,523 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "os_regex/os_regex.h" +#include "os_xml/os_xml.h" +#include "eventinfo.h" +#include "decoder.h" +#include "config.h" + + + +/* Use the osdecoders to decode the received event */ +void DecodeEvent(Eventinfo *lf) +{ + OSDecoderNode *node; + OSDecoderNode *child_node; + OSDecoderInfo *nnode; + + const char *llog = NULL; + const char *pmatch = NULL; + const char *cmatch = NULL; + const char *regex_prev = NULL; + + node = OS_GetFirstOSDecoder(lf->program_name); + + if (!node) { + return; + } + +#ifdef TESTRULE + if (!alert_only) { + print_out("\n**Phase 2: Completed decoding."); + } +#endif + + do { + nnode = node->osdecoder; + + /* First check program name */ + if (lf->program_name) { + if (nnode->program_name) { + if (!OSMatch_Execute(lf->program_name, lf->p_name_size, + nnode->program_name)) { + continue; + } + pmatch = lf->log; + } else if (nnode->program_name_pcre2) { + if (!OSPcre2_Execute(lf->program_name, nnode->program_name_pcre2)) { + continue; + } + pmatch = lf->log; + } + } + + /* If prematch fails, go to the next osdecoder in the list */ + if (nnode->prematch) { + if (!(pmatch = OSRegex_Execute(lf->log, nnode->prematch))) { + continue; + } + } + else if (nnode->prematch_pcre2) { + if (!(pmatch = OSPcre2_Execute(lf->log, nnode->prematch_pcre2))) { + continue; + } + } + +#ifdef TESTRULE + if (!alert_only) { + print_out(" decoder: '%s'", nnode->name); + } +#endif + + lf->decoder_info = nnode; + child_node = node->child; + + /* If no child node is set, set the child node + * as if it were the child (ugh) + */ + if (!child_node) { + child_node = node; + } + + else { + /* Check if we have any child osdecoder */ + while (child_node) { + nnode = child_node->osdecoder; + + /* If we have a pre match and it matches, keep + * going. If we don't have a prematch, stop + * and go for the regexes. + */ + if (nnode->prematch) { + const char *llog2; + + /* If we have an offset set, use it */ + if (nnode->prematch_offset & AFTER_PARENT) { + llog2 = pmatch; + } else { + llog2 = lf->log; + } + + if ((cmatch = OSRegex_Execute(llog2, nnode->prematch))) { + lf->decoder_info = nnode; + + break; + } + } else if (nnode->prematch_pcre2) { + const char *llog2; + + /* If we have an offset set, use it */ + if (nnode->prematch_offset & AFTER_PARENT) { + llog2 = pmatch; + } else { + llog2 = lf->log; + } + + if ((cmatch = OSPcre2_Execute(llog2, nnode->prematch_pcre2))) { + lf->decoder_info = nnode; + + break; + } + } else { + cmatch = pmatch; + break; + } + + /* If we have multiple regex-only childs, + * do not attempt to go any further with them. + */ + if (child_node->osdecoder->get_next) { + do { + child_node = child_node->next; + } while (child_node && child_node->osdecoder->get_next); + + if (!child_node) { + return; + } + + child_node = child_node->next; + nnode = NULL; + } else { + child_node = child_node->next; + nnode = NULL; + } + } + } + + /* Nothing matched */ + if (!nnode) { + return; + } + + /* If we have an external decoder, execute it */ + if (nnode->plugindecoder) { + nnode->plugindecoder(lf); + return; + } + + /* Get the regex */ + while (child_node) { + if (nnode->regex) { + int i; + + /* With regex we have multiple options + * regarding the offset: + * after the prematch, + * after the parent, + * after some previous regex, + * or any offset + */ + if (nnode->regex_offset) { + if (nnode->regex_offset & AFTER_PARENT) { + llog = pmatch; + } else if (nnode->regex_offset & AFTER_PREMATCH) { + llog = cmatch; + } else if (nnode->regex_offset & AFTER_PREVREGEX) { + if (!regex_prev) { + llog = cmatch; + } else { + llog = regex_prev; + } + } + } else { + llog = lf->log; + } + + /* If Regex does not match, return */ + if (!(regex_prev = OSRegex_Execute(llog, nnode->regex))) { + if (nnode->get_next) { + child_node = child_node->next; + nnode = child_node->osdecoder; + continue; + } + return; + } + + lf->decoder_info = nnode; + + for (i = 0; nnode->regex->sub_strings[i]; i++) { + if (i >= Config.decoder_order_size) { + ErrorExit("%s: ERROR: Regex has too many groups.", ARGV0); + } + + if (nnode->order[i]) + nnode->order[i](lf, nnode->regex->sub_strings[i], i); + else + /* We do not free any memory used above */ + os_free(nnode->regex->sub_strings[i]); + + nnode->regex->sub_strings[i] = NULL; + } + + /* If we have a next regex, try getting it */ + if (nnode->get_next) { + child_node = child_node->next; + nnode = child_node->osdecoder; + continue; + } + + break; + } + else if (nnode->pcre2) { + int i; + + /* With regex we have multiple options + * regarding the offset: + * after the prematch, + * after the parent, + * after some previous regex, + * or any offset + */ + if (nnode->regex_offset) { + if (nnode->regex_offset & AFTER_PARENT) { + llog = pmatch; + } else if (nnode->regex_offset & AFTER_PREMATCH) { + llog = cmatch; + } else if (nnode->regex_offset & AFTER_PREVREGEX) { + if (!regex_prev) { + llog = cmatch; + } else { + llog = regex_prev; + } + } + } else { + llog = lf->log; + } + + /* If Regex does not match, return */ + if (!(regex_prev = OSPcre2_Execute(llog, nnode->pcre2))) { + if (nnode->get_next) { + child_node = child_node->next; + nnode = child_node->osdecoder; + continue; + } + return; + } + + + lf->decoder_info = nnode; + + for (i = 0; nnode->pcre2->sub_strings[i]; i++) { + if (i >= Config.decoder_order_size) { + ErrorExit("%s: ERROR: Regex has too many groups.", ARGV0); + } + + if (nnode->order[i]) + nnode->order[i](lf, nnode->pcre2->sub_strings[i], i); + else + /* We do not free any memory used above */ + os_free(nnode->pcre2->sub_strings[i]); + + nnode->pcre2->sub_strings[i] = NULL; + } + + /* If we have a next regex, try getting it */ + if (nnode->get_next) { + child_node = child_node->next; + nnode = child_node->osdecoder; + continue; + } + + break; + } + + + /* If we don't have a regex, we may leave now */ + return; + } + + /* ok to return */ + return; + } while ((node = node->next) != NULL); + +#ifdef TESTRULE + if (!alert_only) { + print_out(" No decoder matched."); + } +#endif +} + +/*** Event decoders ****/ + +void *DstUser_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" dstuser: '%s'", field); + } +#endif + + lf->dstuser = field; + return (NULL); +} + +void *SrcUser_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" srcuser: '%s'", field); + } +#endif + + lf->srcuser = field; + return (NULL); +} + +void *SrcIP_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" srcip: '%s'", field); + } +#endif + + lf->srcip = field; + +#ifdef LIBGEOIP_ENABLED + + if(!lf->srcgeoip) { + lf->srcgeoip = GetGeoInfobyIP(lf->srcip); + } + + #ifdef TESTRULE + if (lf->srcgeoip && !alert_only) + print_out(" srcgeoip: '%s'", lf->srcgeoip); + #endif + +#endif + return (NULL); + +} + +void *DstIP_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" dstip: '%s'", field); + } +#endif + + lf->dstip = field; +#ifdef LIBGEOIP_ENABLED + + if(!lf->dstgeoip) { + lf->dstgeoip = GetGeoInfobyIP(lf->dstip); + } + #ifdef TESTRULE + if (lf->dstgeoip && !alert_only) + print_out(" dstgeoip: '%s'", lf->dstgeoip); + #endif + +#endif + return (NULL); + +} + +void *SrcPort_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" srcport: '%s'", field); + } +#endif + + lf->srcport = field; + return (NULL); +} + +void *DstPort_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" dstport: '%s'", field); + } +#endif + + lf->dstport = field; + return (NULL); +} + +void *Protocol_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" proto: '%s'", field); + } +#endif + + lf->protocol = field; + return (NULL); +} + +void *Action_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" action: '%s'", field); + } +#endif + + lf->action = field; + return (NULL); +} + +void *ID_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" id: '%s'", field); + } +#endif + + lf->id = field; + return (NULL); +} + +void *Url_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" url: '%s'", field); + } +#endif + + lf->url = field; + return (NULL); +} + +void *Data_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" extra_data: '%s'", field); + } +#endif + + lf->data = field; + return (NULL); +} + +void *Status_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" status: '%s'", field); + } +#endif + + lf->status = field; + return (NULL); +} + +void *SystemName_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" system_name: '%s'", field); + } +#endif + + lf->systemname = field; + return (NULL); +} + +void *FileName_FP(Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" filename: '%s'", field); + } +#endif + + lf->filename = field; + return (NULL); +} + + +void *DynamicField_FP(Eventinfo *lf, char *field, int order) +{ +#ifdef TESTRULE + if (!alert_only) { + print_out(" %s: '%s'", lf->decoder_info->fields[order], field); + } +#endif + + lf->fields[order] = field; + + return (NULL); +} + +void *None_FP(__attribute__((unused)) Eventinfo *lf, char *field, __attribute__((unused)) int order) +{ + free(field); + return (NULL); +} + diff --git a/src/analysisd/decoders/decoder.h b/src/analysisd/decoders/decoder.h new file mode 100644 index 000000000..cc008daf8 --- /dev/null +++ b/src/analysisd/decoders/decoder.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef __DECODER_H +#define __DECODER_H + +#include "shared.h" +#include "os_regex/os_regex.h" + +#define AFTER_PARENT 0x001 /* 1 */ +#define AFTER_PREMATCH 0x002 /* 2 */ +#define AFTER_PREVREGEX 0x004 /* 4 */ +#define AFTER_ERROR 0x010 + +struct _Eventinfo; + + +/* Decoder structure */ +typedef struct { + u_int8_t get_next; + u_int8_t type; + u_int8_t use_own_name; + + u_int16_t id; + u_int16_t regex_offset; + u_int16_t prematch_offset; + + int fts; + int accumulate; + char *parent; + char *name; + char *ftscomment; + char **fields; + + + + OSRegex *regex; + OSRegex *prematch; + OSMatch *program_name; + + OSPcre2 *pcre2; + OSPcre2 *prematch_pcre2; + OSPcre2 *program_name_pcre2; + + void (*plugindecoder)(void *lf); + void* (**order)(struct _Eventinfo *, char *, int); +} OSDecoderInfo; + +/* List structure */ +typedef struct _OSDecoderNode { + struct _OSDecoderNode *next; + struct _OSDecoderNode *child; + OSDecoderInfo *osdecoder; +} OSDecoderNode; + +/* Functions to Create the list, add a osdecoder to the + * list and to get the first osdecoder + */ +void OS_CreateOSDecoderList(void); +int OS_AddOSDecoder(OSDecoderInfo *pi); +OSDecoderNode *OS_GetFirstOSDecoder(const char *pname); +int getDecoderfromlist(const char *name); +char *GetGeoInfobyIP(char *ip_addr); +int SetDecodeXML(void); +void HostinfoInit(void); +void SyscheckInit(void); +void RootcheckInit(void); + +int ReadDecodeXML(const char *file); + +#endif + diff --git a/src/analysisd/decoders/decoders_list.c b/src/analysisd/decoders/decoders_list.c new file mode 100644 index 000000000..2ce73d339 --- /dev/null +++ b/src/analysisd/decoders/decoders_list.c @@ -0,0 +1,207 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include +#include +#include + +#include "headers/debug_op.h" +#include "decoder.h" +#include "error_messages/error_messages.h" + +/* We have two internal lists. One with the program_name + * and one without. This is going to improve greatly the + * performance of our decoder matching. + */ +static OSDecoderNode *osdecodernode_forpname; +static OSDecoderNode *osdecodernode_nopname; + +static OSDecoderNode *_OS_AddOSDecoder(OSDecoderNode *s_node, OSDecoderInfo *pi); + +/* Create the Event List */ +void OS_CreateOSDecoderList() +{ + osdecodernode_forpname = NULL; + osdecodernode_nopname = NULL; + + return; +} + +/* Get first osdecoder */ +OSDecoderNode *OS_GetFirstOSDecoder(const char *p_name) +{ + /* If program name is set, we return the forpname list */ + if (p_name) { + return (osdecodernode_forpname); + } + + return (osdecodernode_nopname); +} + +/* Add an osdecoder to the list */ +static OSDecoderNode *_OS_AddOSDecoder(OSDecoderNode *s_node, OSDecoderInfo *pi) +{ + OSDecoderNode *tmp_node = s_node; + OSDecoderNode *new_node; + int rm_f = 0; + + if (tmp_node) { + new_node = (OSDecoderNode *)calloc(1, sizeof(OSDecoderNode)); + if (new_node == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + + /* Going to the last node */ + do { + /* Check for common names */ + if ((strcmp(tmp_node->osdecoder->name, pi->name) == 0) && + (pi->parent != NULL)) { + if ((tmp_node->osdecoder->prematch || + tmp_node->osdecoder->regex || + tmp_node->osdecoder->prematch_pcre2 || + tmp_node->osdecoder->pcre2) && pi->regex_offset) { + rm_f = 1; + } + + /* Multi-regexes patterns cannot have prematch */ + if (pi->prematch || pi->prematch_pcre2) { + merror(PDUP_INV, ARGV0, pi->name); + goto error; + } + + /* Multi-regex patterns cannot have fts set */ + if (pi->fts) { + merror(PDUPFTS_INV, ARGV0, pi->name); + goto error; + } + + if (tmp_node->osdecoder->regex && pi->regex) { + tmp_node->osdecoder->get_next = 1; + } else if (tmp_node->osdecoder->pcre2 && pi->pcre2) { + tmp_node->osdecoder->get_next = 1; + } else { + merror(DUP_INV, ARGV0, pi->name); + goto error; + } + } + + } while (tmp_node->next && (tmp_node = tmp_node->next)); + + /* Must have a prematch set */ + if (!rm_f && (pi->regex_offset & AFTER_PREVREGEX)) { + merror(INV_OFFSET, ARGV0, pi->name); + goto error; + } + + tmp_node->next = new_node; + + new_node->next = NULL; + new_node->osdecoder = pi; + new_node->child = NULL; + } + + else { + /* Must not have a previous regex set */ + if (pi->regex_offset & AFTER_PREVREGEX) { + merror(INV_OFFSET, ARGV0, pi->name); + return (NULL); + } + + tmp_node = (OSDecoderNode *)calloc(1, sizeof(OSDecoderNode)); + + if (tmp_node == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + tmp_node->child = NULL; + tmp_node->next = NULL; + tmp_node->osdecoder = pi; + + s_node = tmp_node; + } + + return (s_node); + +error: + if (new_node) { + free(new_node); + } + return (NULL); +} + +int OS_AddOSDecoder(OSDecoderInfo *pi) +{ + int added = 0; + OSDecoderNode *osdecodernode; + + /* We can actually have two lists. One with program + * name and the other without. + */ + if (pi->program_name || pi->program_name_pcre2) { + osdecodernode = osdecodernode_forpname; + } else { + osdecodernode = osdecodernode_nopname; + } + + /* Search for parent on both lists */ + if (pi->parent) { + OSDecoderNode *tmp_node = osdecodernode_forpname; + + /* List with p_name */ + while (tmp_node) { + if (strcmp(tmp_node->osdecoder->name, pi->parent) == 0) { + tmp_node->child = _OS_AddOSDecoder(tmp_node->child, pi); + if (!tmp_node->child) { + merror(DEC_PLUGIN_ERR, ARGV0); + return (0); + } + added = 1; + } + tmp_node = tmp_node->next; + } + + /* List without p name */ + tmp_node = osdecodernode_nopname; + while (tmp_node) { + if (strcmp(tmp_node->osdecoder->name, pi->parent) == 0) { + tmp_node->child = _OS_AddOSDecoder(tmp_node->child, pi); + if (!tmp_node->child) { + merror(DEC_PLUGIN_ERR, ARGV0); + return (0); + } + added = 1; + } + tmp_node = tmp_node->next; + } + + /* OSDecoder was added correctly */ + if (added == 1) { + return (1); + } + + merror(PPLUGIN_INV, ARGV0, pi->parent); + return (0); + } else { + osdecodernode = _OS_AddOSDecoder(osdecodernode, pi); + if (!osdecodernode) { + merror(DEC_PLUGIN_ERR, ARGV0); + return (0); + } + + /* Update global decoder pointers */ + if (pi->program_name || pi->program_name_pcre2) { + osdecodernode_forpname = osdecodernode; + } else { + osdecodernode_nopname = osdecodernode; + } + } + return (1); +} + diff --git a/src/analysisd/decoders/geoip.c b/src/analysisd/decoders/geoip.c new file mode 100644 index 000000000..9816b4c81 --- /dev/null +++ b/src/analysisd/decoders/geoip.c @@ -0,0 +1,90 @@ +/* @(#) $Id: ./src/analysisd/decoders/geoip.c, 2014/03/08 dcid Exp $ + */ + +/* Copyright (C) 2014 Daniel Cid + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + + +/* GeoIP - Every IP address will have its geolocation added to it */ + +#ifdef LIBGEOIP_ENABLED + + +#include "config.h" +#include "os_regex/os_regex.h" +#include "eventinfo.h" +#include "alerts/alerts.h" +#include "decoder.h" +#include "GeoIP.h" +#include "GeoIPCity.h" + + +char *GetGeoInfobyIP(char *ip_addr) +{ + GeoIPRecord *geoiprecord; + char *geodata = NULL; + char geobuffer[256 +1]; + extern GeoIP *geoipdb; + + if(!geoipdb) + { + return(NULL); + } + + if(!ip_addr) + { + return(NULL); + } + + geoiprecord = GeoIP_record_by_name(geoipdb, (const char *)ip_addr); + if(geoiprecord == NULL) + { + return(NULL); + } + + if(geoiprecord->country_code == NULL) + { + GeoIPRecord_delete(geoiprecord); + return(NULL); + } + + if(strlen(geoiprecord->country_code) < 2) + { + GeoIPRecord_delete(geoiprecord); + return(NULL); + } + + + if(geoiprecord->region != NULL && geoiprecord->region[0] != '\0') + { + const char *regionname = NULL; + regionname = GeoIP_region_name_by_code(geoiprecord->country_code, geoiprecord->region); + if(regionname != NULL) + { + snprintf(geobuffer, 255, "%s / %s", geoiprecord->country_code, regionname); + geobuffer[255] = '\0'; + geodata = strdup(geobuffer); + } + else + { + geodata = strdup(geoiprecord->country_code); + } + } + else + { + geodata = strdup(geoiprecord->country_code); + } + + GeoIPRecord_delete(geoiprecord); + return(geodata); + +} + +#endif + diff --git a/src/analysisd/decoders/hostinfo.c b/src/analysisd/decoders/hostinfo.c new file mode 100644 index 000000000..23400b30b --- /dev/null +++ b/src/analysisd/decoders/hostinfo.c @@ -0,0 +1,224 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Hostinfo decoder */ +#include "decoder.h" + +#include "config.h" +#include "os_regex/os_regex.h" +#include "eventinfo.h" +#include "alerts/alerts.h" + +#define HOSTINFO_FILE "/queue/fts/hostinfo" +#define HOST_HOST "Host: " +/*#define HOST_PORT " open ports: " +#define HOST_CHANGED "Host information changed." +#define HOST_NEW "New host information added."*/ +#define PREV_OPEN "Previously" + +/* Local variables */ +static int hi_err = 0; +static int id_new = 0; +static int id_mod = 0; +static char _hi_buf[OS_MAXSTR + 1]; +static FILE *_hi_fp = NULL; + +/* Hostinfo decoder */ +static OSDecoderInfo *hostinfo_dec = NULL; + + +/* Check if the string matches */ +static char *__go_after(char *x, const char *y) +{ + size_t x_s; + size_t y_s; + + /* X and Y must be not null */ + if (!x || !y) { + return (NULL); + } + + x_s = strlen(x); + y_s = strlen(y); + + if (x_s <= y_s) { + return (NULL); + } + + /* String does not match */ + if (strncmp(x, y, y_s) != 0) { + return (NULL); + } + + x += y_s; + + return (x); +} + +/* Initialize the necessary information to process the host information */ +void HostinfoInit() +{ + hi_err = 0; + + /* Zero decoder */ + os_calloc(1, sizeof(OSDecoderInfo), hostinfo_dec); + hostinfo_dec->id = getDecoderfromlist(HOSTINFO_MOD); + hostinfo_dec->type = openarmor_RL; + hostinfo_dec->name = HOSTINFO_MOD; + hostinfo_dec->fts = 0; + id_new = getDecoderfromlist(HOSTINFO_NEW); + id_mod = getDecoderfromlist(HOSTINFO_MOD); + + /* Open HOSTINFO_FILE */ + snprintf(_hi_buf, OS_SIZE_1024, "%s", HOSTINFO_FILE); + + /* r+ to read and write. Do not truncate */ + _hi_fp = fopen(_hi_buf, "r+"); + if (!_hi_fp) { + /* Try opening with a w flag, file probably does not exist */ + _hi_fp = fopen(_hi_buf, "w"); + if (_hi_fp) { + fclose(_hi_fp); + _hi_fp = fopen(_hi_buf, "r+"); + } + } + if (!_hi_fp) { + merror(FOPEN_ERROR, ARGV0, _hi_buf, errno, strerror(errno)); + return; + } + + /* Clear the buffer */ + memset(_hi_buf, '\0', OS_MAXSTR + 1); + + return; +} + +/* Return the file pointer to be used */ +static FILE *HI_File(void) +{ + if (_hi_fp) { + fseek(_hi_fp, 0, SEEK_SET); + return (_hi_fp); + } + + return (NULL); +} + +/* Special decoder for Hostinformation + * Not using the default rendering tools for simplicity + * and to be less resource intensive + */ +int DecodeHostinfo(Eventinfo *lf) +{ + int changed = 0; + size_t bf_size; + + char *ip; + char *portss; + char *tmpstr; + + char buffer[OS_MAXSTR + 1]; + char opened[OS_MAXSTR + 1]; + FILE *fp; + + /* Check maximum number of errors */ + if (hi_err > 30) { + merror("%s: Too many errors handling host information db. " + "Ignoring it.", ARGV0); + return (0); + } + + /* Zero buffers */ + buffer[OS_MAXSTR] = '\0'; + opened[OS_MAXSTR] = '\0'; + fp = HI_File(); + if (!fp) { + merror("%s: Error handling host information database.", ARGV0); + hi_err++; + return (0); + } + + /* Copy log to buffer */ + strncpy(buffer, lf->log, OS_MAXSTR); + + /* Get IP */ + tmpstr = __go_after(buffer, HOST_HOST); + if (!tmpstr) { + merror("%s: Error handling host information database.", ARGV0); + hi_err++; + + return (0); + } + + /* Setting IP */ + ip = tmpstr; + tmpstr = strchr(tmpstr, ','); + if (!tmpstr) { + merror("%s: Error handling host information database.", ARGV0); + hi_err++; + + return (0); + } + *tmpstr = '\0'; + tmpstr++; + portss = tmpstr; + + /* Get IP only information -- to store */ + tmpstr = strchr(ip, ' '); + if (tmpstr) { + *tmpstr = '\0'; + } + bf_size = strlen(ip); + + /* Read the file and search for a possible entry */ + while (fgets(_hi_buf, OS_MAXSTR - 1, fp) != NULL) { + /* Ignore blank lines and lines with a comment */ + if (_hi_buf[0] == '\n' || _hi_buf[0] == '#') { + continue; + } + + /* Remove newline */ + tmpstr = strchr(_hi_buf, '\n'); + if (tmpstr) { + *tmpstr = '\0'; + } + + /* Check for IP */ + if (strncmp(ip, _hi_buf, bf_size) == 0) { + /* Cannot use strncmp to avoid errors with crafted files */ + if (strcmp(portss, _hi_buf + bf_size) == 0) { + return (0); + } else { + char *tmp_ports; + + tmp_ports = _hi_buf + (bf_size + 1); + snprintf(opened, OS_MAXSTR, "%s %s", PREV_OPEN, tmp_ports); + changed = 1; + } + } + } + + /* Add the new entry at the end of the file */ + fseek(fp, 0, SEEK_END); + fprintf(fp, "%s%s\n", ip, portss); + + /* Set decoder */ + lf->decoder_info = hostinfo_dec; + + /* Set comment */ + if (changed == 1) { + hostinfo_dec->id = id_mod; + /* lf->generated_rule->last_events[0] = opened; */ + } else { + hostinfo_dec->id = id_new; + } + + return (1); +} + diff --git a/src/analysisd/decoders/plugin_decoders.c b/src/analysisd/decoders/plugin_decoders.c new file mode 100644 index 000000000..244110434 --- /dev/null +++ b/src/analysisd/decoders/plugin_decoders.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "plugin_decoders.h" + +/* List of plugins. All three lists must be in the same order */ +const char *(plugin_decoders[]) = {"PF_Decoder", + "SymantecWS_Decoder", + "SonicWall_Decoder", + "openarmorAlert_Decoder", + NULL + }; +void *(plugin_decoders_init[]) = {PF_Decoder_Init, + SymantecWS_Decoder_Init, + SonicWall_Decoder_Init, + openarmorAlert_Decoder_Init, + NULL + }; +void *(plugin_decoders_exec[]) = {PF_Decoder_Exec, + SymantecWS_Decoder_Exec, + SonicWall_Decoder_Exec, + openarmorAlert_Decoder_Exec, + NULL + }; diff --git a/src/analysisd/decoders/plugin_decoders.h b/src/analysisd/decoders/plugin_decoders.h new file mode 100644 index 000000000..fdd0d996e --- /dev/null +++ b/src/analysisd/decoders/plugin_decoders.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef __PLUGINDECODER_H +#define __PLUGINDECODER_H + +#include "eventinfo.h" + +/* Plugin decoder for OpenBSD PF */ +void *PF_Decoder_Init(void); +void *PF_Decoder_Exec(Eventinfo *lf); + +/* Plugin for Symantec Web Security */ +void *SymantecWS_Decoder_Init(void); +void *SymantecWS_Decoder_Exec(Eventinfo *lf); + +/* Plugin for Sonicwall */ +void *SonicWall_Decoder_Init(void); +void *SonicWall_Decoder_Exec(Eventinfo *lf); + +/* Plugin for openarmor alert */ +void *openarmorAlert_Decoder_Init(void); +void *openarmorAlert_Decoder_Exec(Eventinfo *lf); + +/* List of plugins. All three lists must be in the same order */ +extern const char *(plugin_decoders[]); +extern void *(plugin_decoders_init[]); +extern void *(plugin_decoders_exec[]); + +#endif /* __PLUGINDECODER_H */ + diff --git a/src/analysisd/decoders/plugins/openarmoralert_decoder.c b/src/analysisd/decoders/plugins/openarmoralert_decoder.c new file mode 100644 index 000000000..6bb30790a --- /dev/null +++ b/src/analysisd/decoders/plugins/openarmoralert_decoder.c @@ -0,0 +1,197 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + * + */ + + +#include "shared.h" +#include "eventinfo.h" +#include "config.h" + + + + +/* openarmorAlert decoder init */ +void *openarmorAlert_Decoder_Init() +{ + debug1("%s: Initializing openarmorAlert decoder.", ARGV0); + + + /* There is nothing else to do over here */ + return(NULL); +} + + + +#define oa_strchr(x,y,z) z = strchr(x,y); if(!z){ return(NULL); } + +/* openarmorAlert decoder + * Will extract the rule_id and point back to the original rule. + * Will also extract srcip and username if available. + * Examples: + * + */ +void *openarmorAlert_Decoder_Exec(Eventinfo *lf) +{ + char *oa_id = 0; + char *oa_location; + char *oa_val; + char oa_newlocation[256]; + char agent_file[OS_SIZE_1024 +1]; + char tmpstr_buffer[4096 +1]; + char *tmp_str = NULL; + void *rule_pointer; + FILE *fp; + + + lf->decoder_info->type = openarmor_ALERT; + + + /* Checking the alert level. */ + if(strncmp("Alert Level: ", lf->log, 12) != 0 && + strncmp("openarmor: Alert Level:", lf->log, 18) != 0) + { + return(NULL); + } + + + /* Going past the level. */ + oa_strchr(lf->log, ';', tmp_str); + tmp_str++; + + + /* Getting rule id. */ + oa_strchr(tmp_str, ':', tmp_str); + tmp_str++; + if(*tmp_str != ' ') + { + return(NULL); + } + tmp_str++; + + + /* Getting id. */ + oa_id = tmp_str; + oa_strchr(tmp_str, ' ', tmp_str); + *tmp_str = '\0'; + + + /* Getting rule structure. */ + rule_pointer = OSHash_Get(Config.g_rules_hash, oa_id); + if(!rule_pointer) + { + *tmp_str = ' '; + merror("%s: WARN: Rule id '%s' not found internally: %s", ARGV0, oa_id, lf->log); + *tmp_str = ' '; + return(NULL); + } + *tmp_str = ' '; + oa_strchr(tmp_str, ';', tmp_str); + tmp_str++; + + + + + /* Checking location. */ + if(strncmp(" Location: ", tmp_str, 11) != 0) + { + return(NULL); + } + tmp_str+=11; + + + /* Setting location; */ + oa_location = tmp_str; + + + oa_strchr(tmp_str, ';', tmp_str); + *tmp_str = '\0'; + + + + /* Setting new location. */ + oa_newlocation[255] = '\0'; + agent_file[OS_SIZE_1024] = '\0'; + + + snprintf(agent_file, OS_SIZE_1024, "%s/%s->%s", + AGENTINFO_DIR, lf->hostname, lf->location); + + snprintf(oa_newlocation, 255, "%s|%s", lf->location, oa_location); + free(lf->location); + os_strdup(oa_newlocation, lf->location); + lf->hostname = lf->location; + + + + /* Writting to the agent file */ + fp = fopen(agent_file, "w"); + if(fp) + { + fprintf(fp, "%s\n", "Remote Syslog"); + fclose(fp); + } + + + *tmp_str = ';'; + tmp_str++; + + + + + /* Getting additional fields. */ + while((*tmp_str == ' ') && (tmp_str[1] != ' ')) + { + tmp_str++; + oa_val = tmp_str; + + tmp_str = strchr(tmp_str, ';'); + if(!tmp_str) + { + return(NULL); + } + *tmp_str = '\0'; + + if(strncmp(oa_val, "srcip: ", 7) == 0) + { + os_strdup(oa_val + 7, lf->srcip); + } + if(strncmp(oa_val, "user: ", 6) == 0) + { + os_strdup(oa_val + 6, lf->dstuser); + } + + *tmp_str = ';'; + tmp_str++; + } + + + /* Removing space. */ + while(*tmp_str == ' ') + tmp_str++; + + + /* Creating new full log. */ + tmpstr_buffer[0] = '\0'; + tmpstr_buffer[4095] = '\0'; + strncpy(tmpstr_buffer, tmp_str, 4094); + + free(lf->full_log); + lf->full_log = NULL; + os_strdup(tmpstr_buffer, lf->full_log); + lf->log = lf->full_log; + + + /* Rule that generated. */ + lf->generated_rule = rule_pointer; + + + return(NULL); +} + +/* END Decoder */ diff --git a/src/analysisd/decoders/plugins/pf_decoder.c b/src/analysisd/decoders/plugins/pf_decoder.c new file mode 100644 index 000000000..1a3983581 --- /dev/null +++ b/src/analysisd/decoders/plugins/pf_decoder.c @@ -0,0 +1,176 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "../plugin_decoders.h" + +#include "shared.h" +#include "eventinfo.h" + + +/* OpenBSD PF decoder init */ +void *PF_Decoder_Init() +{ + debug1("%s: Initializing PF decoder..", ARGV0); + + /* There is nothing to do over here */ + return (NULL); +} + +/* OpenBSD PF decoder + * Will extract the action,srcip,dstip,protocol,srcport,dstport + * + * Examples: + * Mar 30 15:33:26 enigma pf: Mar 30 15:32:33.483712 rule 2/(match) pass in on xl0: 140.211.166.3.6667 > 192.168.2.10.16290: P 7408:7677(269) ack 1773 win 2520 (DF) + * Mar 30 15:47:05.522341 rule 4/(match) block in on lo0: 127.0.0.1.48784 > 127.0.0.1.23: S 1381529123:1381529123(0) win 16384 (DF) [tos 0x10] + * Mar 30 15:54:22.171929 rule 3/(match) pass out on xl0: 192.168.2.10.1514 > 192.168.2.190.1030: udp 73 + * Mar 30 15:54:22.174412 rule 3/(match) pass out on xl0: 192.168.2.10.1514 > 192.168.2.190.1030: udp 89 + * Mar 30 17:47:40.390143 rule 2/(match) pass in on lo0: 127.0.0.1 > 127.0.0.1: icmp: echo reply + * Mar 30 17:47:41.400075 rule 3/(match) pass out on lo0: 127.0.0.1 > 127.0.0.1: icmp: echo request + */ +void *PF_Decoder_Exec(Eventinfo *lf) +{ + int port_count = 0; + char *tmp_str; + char *aux_str; + + /* tmp_str should be: Mar 30 15:54:22.171929 rule 3/(match) pass out .. */ + tmp_str = strchr(lf->log, ')'); + + /* Didn't match */ + if (!tmp_str) { + return (NULL); + } + + /* Go to the action entry */ + tmp_str++; + if (*tmp_str != ' ') { + return (NULL); + } + tmp_str++; + + /* tmp_str should be: pass out on xl0: 192.168.2.10.1514 .. */ + + /* Get action */ + if (*tmp_str == 'p') { + os_strdup("pass", lf->action); + } else if (*tmp_str == 'b') { + os_strdup("block", lf->action); + } else { + /* Unknown action */ + return (NULL); + } + + /* Jump to the src ip */ + tmp_str = strchr(tmp_str, ':'); + if (!tmp_str) { + return (NULL); + } + tmp_str++; + if (*tmp_str != ' ') { + return (NULL); + } + tmp_str++; + + /* tmp_str should be: 192.168.2.10.1514 > .. */ + aux_str = strchr(tmp_str, ' '); + if (!aux_str) { + return (NULL); + } + + /* Set aux_str to 0 for strdup */ + *aux_str = '\0'; + + os_strdup(tmp_str, lf->srcip); + + /* Aux str has a valid pointer to lf->log now */ + *aux_str = ' '; + aux_str++; + + /* Set the source port if present */ + tmp_str = lf->srcip; + while (*tmp_str != '\0') { + if (*tmp_str == '.') { + port_count++; + } + + /* Found port */ + if (port_count == 4) { + *tmp_str = '\0'; + tmp_str++; + os_strdup(tmp_str, lf->srcport); + break; + } + + tmp_str++; + } + + /* Invalid rest of log */ + if (*aux_str != '>') { + return (NULL); + } + + aux_str++; + if (*aux_str != ' ') { + return (NULL); + } + aux_str++; + + /* tmp_str should be: 192.168.2.10.1514: .. .. */ + tmp_str = strchr(aux_str, ':'); + if (!tmp_str) { + return (NULL); + } + + /* Set aux_str to 0 for strdup */ + *tmp_str = '\0'; + + os_strdup(aux_str, lf->dstip); + + /* tmp str has a valid pointer to lf->log now */ + *tmp_str = ':'; + tmp_str++; + + /* Get destination port */ + aux_str = lf->dstip; + port_count = 0; + while (*aux_str != '\0') { + if (*aux_str == '.') { + port_count++; + } + + /* Found port */ + if (port_count == 4) { + *aux_str = '\0'; + aux_str++; + os_strdup(aux_str, lf->dstport); + break; + } + + aux_str++; + } + + /* Get protocol */ + while (*tmp_str != '\0') { + if (*tmp_str == ' ') { + tmp_str++; + continue; + } else if (*tmp_str == 'u') { + os_strdup("UDP", lf->protocol); + } else if (*tmp_str == 'i') { + os_strdup("ICMP", lf->protocol); + } else { + os_strdup("TCP", lf->protocol); + } + + break; + } + + return (NULL); +} + diff --git a/src/analysisd/decoders/plugins/sonicwall_decoder.c b/src/analysisd/decoders/plugins/sonicwall_decoder.c new file mode 100644 index 000000000..c078af412 --- /dev/null +++ b/src/analysisd/decoders/plugins/sonicwall_decoder.c @@ -0,0 +1,264 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "../plugin_decoders.h" + +#include "shared.h" +#include "eventinfo.h" + +/* Regex to extract the priority and event id */ +#define SONICWALL_REGID "pri=(\\d) c=(\\d+) m=(\\d+) " + +/* Regex to extract the srcip and dst ip */ +#define SONICWALL_REGEX "src=(\\d+.\\d+.\\d+.\\d+):(\\d+):\\S+ " \ + "dst=(\\d+.\\d+.\\d+.\\d+):(\\d+):" + +/* Regex for the web proxy messages */ +#define SONICWALL_PROXY "result=(\\d+) dstname=(\\S+) arg=(\\S+)$" + +/* Global variables -- not thread safe. If we ever multi thread + * analysisd, these will need to be changed. + */ +static OSRegex *__sonic_regex_prid = NULL; +static OSRegex *__sonic_regex_sdip = NULL; +static OSRegex *__sonic_regex_prox = NULL; + + +void *SonicWall_Decoder_Init() +{ + debug1("%s: Initializing SonicWall decoder..", ARGV0); + + /* Allocate memory */ + os_calloc(1, sizeof(OSRegex), __sonic_regex_sdip); + os_calloc(1, sizeof(OSRegex), __sonic_regex_prid); + os_calloc(1, sizeof(OSRegex), __sonic_regex_prox); + + /* Compile our regexes */ + if (!OSRegex_Compile(SONICWALL_REGEX, __sonic_regex_sdip, OS_RETURN_SUBSTRING)) { + merror(REGEX_COMPILE, ARGV0, SONICWALL_REGEX, __sonic_regex_sdip->error); + return (0); + } + if (!OSRegex_Compile(SONICWALL_REGID, __sonic_regex_prid, OS_RETURN_SUBSTRING)) { + merror(REGEX_COMPILE, ARGV0, SONICWALL_REGID, __sonic_regex_prid->error); + return (0); + } + if (!OSRegex_Compile(SONICWALL_PROXY, __sonic_regex_prox, OS_RETURN_SUBSTRING)) { + merror(REGEX_COMPILE, ARGV0, SONICWALL_PROXY, __sonic_regex_prox->error); + return (0); + } + + /* We must have the sub_strings to retrieve the nodes */ + if (!__sonic_regex_sdip->sub_strings) { + merror(REGEX_SUBS, ARGV0, SONICWALL_REGEX); + return (0); + } + if (!__sonic_regex_prid->sub_strings) { + merror(REGEX_SUBS, ARGV0, SONICWALL_REGID); + return (0); + } + if (!__sonic_regex_prox->sub_strings) { + merror(REGEX_SUBS, ARGV0, SONICWALL_PROXY); + return (0); + } + + /* There is nothing else to do over here */ + return (NULL); +} + +/* SonicWall decoder + * Will extract the id, severity, action, srcip, dstip, protocol,srcport,dstport + * severity will be extracted as status. + * Examples: + * Jan 3 13:45:36 192.168.5.1 id=firewall sn=000SERIAL time="2007-01-03 14:48:06" fw=1.1.1.1 pri=6 c=262144 m=98 msg="Connection Opened" n=23419 src=2.2.2.2:36701:WAN dst=1.1.1.1:50000:WAN proto=tcp/50000 + * Jan 3 13:45:36 192.168.5.1 id=firewall sn=000SERIAL time="2007-01-03 14:48:07" fw=1.1.1.1 pri=1 c=32 m=30 msg="Administrator login denied due to bad credentials" n=7 src=2.2.2.2:36701:WAN dst=1.1.1.1:50000:WAN + */ +void *SonicWall_Decoder_Exec(Eventinfo *lf) +{ + int i = 0; + char category[8]; + const char *tmp_str = NULL; + + /* Zero category */ + category[0] = '\0'; + lf->decoder_info->type = SYSLOG; + + /* First run regex to extract the severity, cat and id */ + if (!(tmp_str = OSRegex_Execute(lf->log, __sonic_regex_prid))) { + return (NULL); + } + + /* Get severity, id and category */ + if (__sonic_regex_prid->sub_strings[0] && + __sonic_regex_prid->sub_strings[1] && + __sonic_regex_prid->sub_strings[2]) { + lf->status = __sonic_regex_prid->sub_strings[0]; + lf->id = __sonic_regex_prid->sub_strings[2]; + + /* Get category */ + strncpy(category, __sonic_regex_prid->sub_strings[1], 7); + + /* Clear all substrings */ + __sonic_regex_prid->sub_strings[0] = NULL; + __sonic_regex_prid->sub_strings[2] = NULL; + + free(__sonic_regex_prid->sub_strings[1]); + __sonic_regex_prid->sub_strings[1] = NULL; + } else { + i = 0; + while (__sonic_regex_prid->sub_strings[i]) { + free(__sonic_regex_prid->sub_strings[i]); + __sonic_regex_prid->sub_strings[i] = NULL; + i++; + } + + return (NULL); + } + + /* Get ips and ports */ + if (!(tmp_str = OSRegex_Execute(tmp_str, __sonic_regex_sdip))) { + return (NULL); + } + if (__sonic_regex_sdip->sub_strings[0] && + __sonic_regex_sdip->sub_strings[1] && + __sonic_regex_sdip->sub_strings[2] && + __sonic_regex_sdip->sub_strings[3]) { + /* Set all the values */ + lf->srcip = __sonic_regex_sdip->sub_strings[0]; + lf->srcport = __sonic_regex_sdip->sub_strings[1]; + lf->dstip = __sonic_regex_sdip->sub_strings[2]; + lf->dstport = __sonic_regex_sdip->sub_strings[3]; + + /* Clear substrings */ + __sonic_regex_sdip->sub_strings[0] = NULL; + __sonic_regex_sdip->sub_strings[1] = NULL; + __sonic_regex_sdip->sub_strings[2] = NULL; + __sonic_regex_sdip->sub_strings[3] = NULL; + + /* Look for protocol */ + tmp_str = strchr(tmp_str, ' '); + if (tmp_str) { + tmp_str++; + if (strncmp(tmp_str, "proto=", 6) == 0) { + char *proto = NULL; + + i = 0; + tmp_str += 6; + + /* Allocate memory for the protocol */ + os_calloc(8, sizeof(char), proto); + while (isValidChar(*tmp_str) && (*tmp_str != '/')) { + proto[i] = *tmp_str; + i++; + tmp_str++; + + if (i >= 6) { + break; + } + } + + /* Set protocol to event info structure */ + lf->protocol = proto; + } + } + } else { + i = 0; + while (__sonic_regex_sdip->sub_strings[i]) { + free(__sonic_regex_sdip->sub_strings[i]); + __sonic_regex_sdip->sub_strings[i] = 0; + i++; + } + + return (NULL); + } + + /* Set the category/action based on the id */ + + /* IDS event */ + if (strcmp(category, "32") == 0) { + lf->decoder_info->type = IDS; + } + + /* Firewall connection opened */ + else if ((strcmp(lf->id, "98") == 0) || + (strcmp(lf->id, "597") == 0) || + (strcmp(lf->id, "598") == 0)) { + lf->decoder_info->type = FIREWALL; + os_strdup("pass", lf->action); + } + + /* Firewall connection dropped */ + else if ((strcmp(lf->id, "38") == 0) || + (strcmp(lf->id, "36") == 0) || + (strcmp(lf->id, "173") == 0) || + (strcmp(lf->id, "174") == 0) || + (strcmp(lf->id, "37") == 0)) { + lf->decoder_info->type = FIREWALL; + os_strdup("drop", lf->action); + } + + /* Firewall connection closed */ + else if (strcmp(lf->id, "537") == 0) { + lf->decoder_info->type = FIREWALL; + os_strdup("close", lf->action); + } + + /* Proxy msg */ + else if (strcmp(lf->id, "97") == 0) { + lf->decoder_info->type = SQUID; + + /* Check if tmp_str is valid */ + if (!tmp_str) { + return (NULL); + } + + /* First run regex to extract the severity and id */ + if (!OSRegex_Execute(tmp_str, __sonic_regex_prox)) { + return (NULL); + } + + /* Get HTTP responde code as id */ + if (__sonic_regex_prox->sub_strings[0]) { + free(lf->id); + lf->id = __sonic_regex_prox->sub_strings[0]; + __sonic_regex_prox->sub_strings[0] = NULL; + } else { + return (NULL); + } + + /* Get HTTP page */ + if (__sonic_regex_prox->sub_strings[1] && + __sonic_regex_prox->sub_strings[2]) { + char *final_url; + size_t url_size = strlen(__sonic_regex_prox->sub_strings[1]) + + strlen(__sonic_regex_prox->sub_strings[2]) + 2; + + os_calloc(url_size + 1, sizeof(char), final_url); + snprintf(final_url, url_size, "%s%s", + __sonic_regex_prox->sub_strings[1], + __sonic_regex_prox->sub_strings[2]); + + + /* Clear memory */ + free(__sonic_regex_prox->sub_strings[1]); + free(__sonic_regex_prox->sub_strings[2]); + __sonic_regex_prox->sub_strings[1] = NULL; + __sonic_regex_prox->sub_strings[2] = NULL; + + /* Set the URL */ + lf->url = final_url; + } else { + merror("%s: Error getting regex - SonicWall." , ARGV0); + } + + return (NULL); + } + + return (NULL); +} + diff --git a/src/analysisd/decoders/plugins/symantecws_decoder.c b/src/analysisd/decoders/plugins/symantecws_decoder.c new file mode 100644 index 000000000..182b1fa0f --- /dev/null +++ b/src/analysisd/decoders/plugins/symantecws_decoder.c @@ -0,0 +1,129 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "../plugin_decoders.h" + +#include "shared.h" +#include "eventinfo.h" + + +void *SymantecWS_Decoder_Init() +{ + debug1("%s: Initializing SymantecWS decoder..", ARGV0); + + /* There is nothing to do over here */ + return (NULL); +} + +/* Symantec Web Security decoder + * Will extract the action, srcip, id, url and username. + * + * Examples (also online at + * http://www.theopenarmor.org/wiki/index.php/Symantec_WebSecurity ). + * 20070717,73613,1=5,11=10.1.1.3,10=userc,3=1,2=1 + * 20070717,73614,1=5,11=1.2.3.4,1106=News,60=http://news.bbc.co.uk/,10=userX,1000=212.58.240.42,2=27 + */ +void *SymantecWS_Decoder_Exec(Eventinfo *lf) +{ + int count = 0; + char buf_str[OS_SIZE_1024 + 1]; + char *tmp_str = NULL; + + /* Initialize buffer */ + buf_str[0] = '\0'; + buf_str[OS_SIZE_1024] = '\0'; + + /* Remove date and time */ + if (!(tmp_str = strchr(lf->log, ','))) { + return (NULL); + } + if (!(tmp_str = strchr(tmp_str, ','))) { + return (NULL); + } + tmp_str++; + + /* Get all the values */ + while (tmp_str != NULL) { + /* Check if we have the username */ + if (strncmp(tmp_str, "10=", 3) == 0) { + count = 0; + tmp_str += 3; + while (*tmp_str != '\0' && count < 128 && *tmp_str != ',') { + buf_str[count] = *tmp_str; + count++; + tmp_str++; + } + buf_str[count] = '\0'; + + if (!lf->dstuser) { + os_strdup(buf_str, lf->dstuser); + } + } + + /* Check the IP address */ + else if (strncmp(tmp_str, "11=", 3) == 0) { + count = 0; + tmp_str += 3; + while (*tmp_str != '\0' && count < 128 && *tmp_str != ',') { + buf_str[count] = *tmp_str; + count++; + tmp_str++; + } + buf_str[count] = '\0'; + + /* Avoid memory leaks -- only adding the first one */ + if (!lf->srcip) { + os_strdup(buf_str, lf->srcip); + } + } + + /* Get the URL */ + else if (strncmp(tmp_str, "60=", 3) == 0) { + count = 0; + tmp_str += 3; + while (*tmp_str != '\0' && count < OS_SIZE_1024 && *tmp_str != ',') { + buf_str[count] = *tmp_str; + count++; + tmp_str++; + } + buf_str[count] = '\0'; + + /* Avoid memory leaks -- only adding the first one */ + if (!lf->url) { + os_strdup(buf_str, lf->url); + } + } + + /* Get ID */ + else if ((strncmp(tmp_str, "3=", 2) == 0) || + (strncmp(tmp_str, "2=", 2) == 0)) { + count = 0; + while (*tmp_str != '\0' && count < 9) { + buf_str[count] = *tmp_str; + count++; + tmp_str++; + } + buf_str[count] = '\0'; + + /* Avoid memory leaks -- only adding the first one */ + if (!lf->id) { + os_strdup(buf_str, lf->id); + } + } + + /* Get next entry */ + tmp_str = strchr(tmp_str, ','); + if (tmp_str) { + tmp_str++; + } + } + + return (NULL); +} + diff --git a/src/analysisd/decoders/rootcheck.c b/src/analysisd/decoders/rootcheck.c new file mode 100644 index 000000000..f00d59679 --- /dev/null +++ b/src/analysisd/decoders/rootcheck.c @@ -0,0 +1,213 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Rootcheck decoder */ + +#include "config.h" +#include "os_regex/os_regex.h" +#include "eventinfo.h" +#include "alerts/alerts.h" +#include "decoder.h" + +#define ROOTCHECK_DIR "/queue/rootcheck" + +/* Local variables */ +static char *rk_agent_ips[MAX_AGENTS]; +static FILE *rk_agent_fps[MAX_AGENTS]; +static int rk_err; + +/* Rootcheck decoder */ +static OSDecoderInfo *rootcheck_dec = NULL; + + +/* Initialize the necessary information to process the rootcheck information */ +void RootcheckInit() +{ + int i = 0; + + rk_err = 0; + + for (; i < MAX_AGENTS; i++) { + rk_agent_ips[i] = NULL; + rk_agent_fps[i] = NULL; + } + + /* Zero decoder */ + os_calloc(1, sizeof(OSDecoderInfo), rootcheck_dec); + rootcheck_dec->id = getDecoderfromlist(ROOTCHECK_MOD); + rootcheck_dec->type = openarmor_RL; + rootcheck_dec->name = ROOTCHECK_MOD; + rootcheck_dec->fts = 0; + + debug1("%s: RootcheckInit completed.", ARGV0); + + return; +} + +/* Return the file pointer to be used */ +static FILE *RK_File(const char *agent, int *agent_id) +{ + int i = 0; + char rk_buf[OS_SIZE_1024 + 1]; + + while (i < MAX_AGENTS && rk_agent_ips[i] != NULL) { + if (strcmp(rk_agent_ips[i], agent) == 0) { + /* Pointing to the beginning of the file */ + fseek(rk_agent_fps[i], 0, SEEK_SET); + *agent_id = i; + return (rk_agent_fps[i]); + } + + i++; + } + + /* If here, our agent wasn't found */ + if (i == MAX_AGENTS) { + merror("%s: Unable to open rootcheck file. Increase MAX_AGENTS.", ARGV0); + return (NULL); + } + + /* If here, our agent wasn't found */ + rk_agent_ips[i] = strdup(agent); + + if (rk_agent_ips[i] != NULL) { + snprintf(rk_buf, OS_SIZE_1024, "%s/%s", ROOTCHECK_DIR, agent); + + /* r+ to read and write. Do not truncate */ + rk_agent_fps[i] = fopen(rk_buf, "r+"); + if (!rk_agent_fps[i]) { + /* Try opening with a w flag, file probably does not exist */ + rk_agent_fps[i] = fopen(rk_buf, "w"); + if (rk_agent_fps[i]) { + fclose(rk_agent_fps[i]); + rk_agent_fps[i] = fopen(rk_buf, "r+"); + } + } + if (!rk_agent_fps[i]) { + merror(FOPEN_ERROR, ARGV0, rk_buf, errno, strerror(errno)); + + free(rk_agent_ips[i]); + rk_agent_ips[i] = NULL; + + return (NULL); + } + + /* Return the opened pointer (the beginning of it) */ + fseek(rk_agent_fps[i], 0, SEEK_SET); + *agent_id = i; + return (rk_agent_fps[i]); + } + + else { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + + return (NULL); +} + +/* Special decoder for rootcheck + * Not using the default rendering tools for simplicity + * and to be less resource intensive + */ +int DecodeRootcheck(Eventinfo *lf) +{ + int agent_id; + + char *tmpstr; + char rk_buf[OS_SIZE_2048 + 1]; + + FILE *fp; + + fpos_t fp_pos; + + /* Zero rk_buf */ + rk_buf[0] = '\0'; + rk_buf[OS_SIZE_2048] = '\0'; + + fp = RK_File(lf->location, &agent_id); + + if (!fp) { + merror("%s: Error handling rootcheck database.", ARGV0); + rk_err++; + + return (0); + } + + /* Get initial position */ + if (fgetpos(fp, &fp_pos) == -1) { + merror("%s: Error handling rootcheck database (fgetpos).", ARGV0); + return (0); + } + + + /* Reads the file and search for a possible entry */ + while (fgets(rk_buf, OS_SIZE_2048 - 1, fp) != NULL) { + /* Ignore blank lines and lines with a comment */ + if (rk_buf[0] == '\n' || rk_buf[0] == '#') { + if (fgetpos(fp, &fp_pos) == -1) { + merror("%s: Error handling rootcheck database " + "(fgetpos2).", ARGV0); + return (0); + } + continue; + } + + /* Remove newline */ + tmpstr = strchr(rk_buf, '\n'); + if (tmpstr) { + *tmpstr = '\0'; + } + + /* Old format without the time stamps */ + if (rk_buf[0] != '!') { + /* Cannot use strncmp to avoid errors with crafted files */ + if (strcmp(lf->log, rk_buf) == 0) { + rootcheck_dec->fts = 0; + lf->decoder_info = rootcheck_dec; + return (1); + } + } + /* New format */ + else { + /* Going past time: !1183431603!1183431603 (last, first seen) */ + tmpstr = rk_buf + 23; + + /* Matches, we need to upgrade last time saw */ + if (strcmp(lf->log, tmpstr) == 0) { + if(fsetpos(fp, &fp_pos)) { + merror("%s: Error handling rootcheck database " + "(fsetpos).", ARGV0); + return (0); + } + fprintf(fp, "!%ld", (long int)lf->time); + rootcheck_dec->fts = 0; + lf->decoder_info = rootcheck_dec; + return (1); + } + } + + /* Get current position */ + if (fgetpos(fp, &fp_pos) == -1) { + merror("%s: Error handling rootcheck database (fgetpos3).", ARGV0); + return (0); + } + } + + /* Add the new entry at the end of the file */ + fseek(fp, 0, SEEK_END); + fprintf(fp, "!%ld!%ld %s\n", (long int)lf->time, (long int)lf->time, lf->log); + fflush(fp); + + rootcheck_dec->fts = 0; + rootcheck_dec->fts |= FTS_DONE; + lf->decoder_info = rootcheck_dec; + return (1); +} + diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c new file mode 100644 index 000000000..d0120e683 --- /dev/null +++ b/src/analysisd/decoders/syscheck.c @@ -0,0 +1,767 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Syscheck decoder */ + +#include "eventinfo.h" +#include "os_regex/os_regex.h" +#include "config.h" +#include "alerts/alerts.h" +#include "decoder.h" + +#ifdef SQLITE_ENABLED +#include +#endif + +typedef struct __sdb { + char buf[OS_MAXSTR + 1]; + char comment[OS_MAXSTR + 1]; + + char size[OS_FLSIZE + 1]; + char perm[OS_FLSIZE + 1]; + char owner[OS_FLSIZE + 1]; + char gowner[OS_FLSIZE + 1]; + char md5[OS_FLSIZE + 1]; + char sha1[OS_FLSIZE + 1]; + + char agent_cp[MAX_AGENTS + 1][1]; + char *agent_ips[MAX_AGENTS + 1]; + FILE *agent_fps[MAX_AGENTS + 1]; + + int db_err; + + /* Ids for decoder */ + int id1; + int id2; + int id3; + int idn; + int idd; + + /* Syscheck rule */ + OSDecoderInfo *syscheck_dec; + + /* File search variables */ + fpos_t init_pos; + +} _sdb; /* syscheck db information */ + +/* Local variables */ +static _sdb sdb; + +/* Extract a token from a string */ +char *extract_token(const char *s, char *delim, int position) { + int count = 0; + char tmp[OS_MAXSTR + 1]; + char *token; + strncpy(tmp,s, OS_MAXSTR); + token = strtok(tmp, delim); + while (token != NULL) { + count++; + token = strtok(NULL, delim); + if (count == position) { + return(token); + } + } + return(NULL); +} + + +/* Validate a MD5 string format */ +int validate_md5(char *s) { + unsigned int i; + char *hex_chars = "abcdefABCDEF0123456789"; + if (strlen(s) != 32) { + return(0); + } + for (i = 0; i < strlen(s); i++) { + if (!strchr(hex_chars, s[i])) return(0); + } + return(1); +} + + +/* Initialize the necessary information to process the syscheck information */ +void SyscheckInit() +{ + int i = 0; + + sdb.db_err = 0; + + for (; i <= MAX_AGENTS; i++) { + sdb.agent_ips[i] = NULL; + sdb.agent_fps[i] = NULL; + sdb.agent_cp[i][0] = '0'; + } + + /* Clear db memory */ + memset(sdb.buf, '\0', OS_MAXSTR + 1); + memset(sdb.comment, '\0', OS_MAXSTR + 1); + + memset(sdb.size, '\0', OS_FLSIZE + 1); + memset(sdb.perm, '\0', OS_FLSIZE + 1); + memset(sdb.owner, '\0', OS_FLSIZE + 1); + memset(sdb.gowner, '\0', OS_FLSIZE + 1); + memset(sdb.md5, '\0', OS_FLSIZE + 1); + memset(sdb.sha1, '\0', OS_FLSIZE + 1); + + /* Create decoder */ + os_calloc(1, sizeof(OSDecoderInfo), sdb.syscheck_dec); + sdb.syscheck_dec->id = getDecoderfromlist(SYSCHECK_MOD); + sdb.syscheck_dec->name = SYSCHECK_MOD; + sdb.syscheck_dec->type = openarmor_RL; + sdb.syscheck_dec->fts = 0; + + sdb.id1 = getDecoderfromlist(SYSCHECK_MOD); + sdb.id2 = getDecoderfromlist(SYSCHECK_MOD2); + sdb.id3 = getDecoderfromlist(SYSCHECK_MOD3); + sdb.idn = getDecoderfromlist(SYSCHECK_NEW); + sdb.idd = getDecoderfromlist(SYSCHECK_DEL); + + debug1("%s: SyscheckInit completed.", ARGV0); + return; +} + +/* Check if the db is completed for that specific agent */ +#define DB_IsCompleted(x) (sdb.agent_cp[x][0] == '1')?1:0 + +static void __setcompleted(const char *agent) +{ + FILE *fp; + + /* Get agent file */ + snprintf(sdb.buf, OS_FLSIZE , "%s/.%s.cpt", SYSCHECK_DIR, agent); + + fp = fopen(sdb.buf, "w"); + if (fp) { + fprintf(fp, "#!X"); + fclose(fp); + } +} + +static int __iscompleted(const char *agent) +{ + FILE *fp; + + /* Get agent file */ + snprintf(sdb.buf, OS_FLSIZE , "%s/.%s.cpt", SYSCHECK_DIR, agent); + + fp = fopen(sdb.buf, "r"); + if (fp) { + fclose(fp); + return (1); + } + return (0); +} + +/* Set the database of a specific agent as completed */ +static void DB_SetCompleted(const Eventinfo *lf) +{ + int i = 0; + + /* Find file pointer */ + while (sdb.agent_ips[i] != NULL && i < MAX_AGENTS) { + if (strcmp(sdb.agent_ips[i], lf->location) == 0) { + /* Return if already set as completed */ + if (DB_IsCompleted(i)) { + return; + } + + __setcompleted(lf->location); + + /* Set as completed in memory */ + sdb.agent_cp[i][0] = '1'; + return; + } + + i++; + } +} + + +/* Return the file pointer to be used to verify the integrity */ +static FILE *DB_File(const char *agent, int *agent_id) +{ + int i = 0; + + /* Find file pointer */ + while (sdb.agent_ips[i] != NULL && i < MAX_AGENTS) { + if (strcmp(sdb.agent_ips[i], agent) == 0) { + /* Point to the beginning of the file */ + fseek(sdb.agent_fps[i], 0, SEEK_SET); + *agent_id = i; + return (sdb.agent_fps[i]); + } + + i++; + } + + /* If here, our agent wasn't found */ + if (i == MAX_AGENTS) { + merror("%s: Unable to open integrity file. Increase MAX_AGENTS.", ARGV0); + return (NULL); + } + + os_strdup(agent, sdb.agent_ips[i]); + + /* Get agent file */ + snprintf(sdb.buf, OS_FLSIZE , "%s/%s", SYSCHECK_DIR, agent); + + /* r+ to read and write. Do not truncate */ + sdb.agent_fps[i] = fopen(sdb.buf, "r+"); + if (!sdb.agent_fps[i]) { + /* Try opening with a w flag, file probably does not exist */ + sdb.agent_fps[i] = fopen(sdb.buf, "w"); + if (sdb.agent_fps[i]) { + fclose(sdb.agent_fps[i]); + sdb.agent_fps[i] = fopen(sdb.buf, "r+"); + } + } + + /* Check again */ + if (!sdb.agent_fps[i]) { + merror("%s: Unable to open '%s'", ARGV0, sdb.buf); + + free(sdb.agent_ips[i]); + sdb.agent_ips[i] = NULL; + return (NULL); + } + + /* Return the opened pointer (the beginning of it) */ + fseek(sdb.agent_fps[i], 0, SEEK_SET); + *agent_id = i; + + /* Check if the agent was completed */ + if (__iscompleted(agent)) { + sdb.agent_cp[i][0] = '1'; + } + + return (sdb.agent_fps[i]); +} + +/* Search the DB for any entry related to the file being received */ +static int DB_Search(const char *f_name, const char *c_sum, Eventinfo *lf) +{ + int p = 0; + size_t sn_size; + int agent_id; + + char *saved_sum; + char *saved_name; + + FILE *fp; + + /* Expose filename variable for active response */ + os_strdup(f_name, lf->filename); + + + + /* Get db pointer */ + fp = DB_File(lf->location, &agent_id); + if (!fp) { + merror("%s: Error handling integrity database.", ARGV0); + sdb.db_err++; + lf->data = NULL; + return (0); + } + + /* Read the integrity file and search for a possible entry */ + if (fgetpos(fp, &sdb.init_pos) == -1) { + merror("%s: Error handling integrity database (fgetpos).", ARGV0); + return (0); + } + + /* Loop over the file */ + while (fgets(sdb.buf, OS_MAXSTR, fp) != NULL) { + /* Ignore blank lines and lines with a comment */ + if (sdb.buf[0] == '\n' || sdb.buf[0] == '#') { + fgetpos(fp, &sdb.init_pos); /* Get next location */ + continue; + } + + /* Get name */ + saved_name = strchr(sdb.buf, ' '); + if (saved_name == NULL) { + merror("%s: Invalid integrity message in the database.", ARGV0); + fgetpos(fp, &sdb.init_pos); /* Get next location */ + continue; + } + *saved_name = '\0'; + saved_name++; + + /* New format - with a timestamp */ + if (*saved_name == '!') { + saved_name = strchr(saved_name, ' '); + if (saved_name == NULL) { + merror("%s: Invalid integrity message in the database", ARGV0); + fgetpos(fp, &sdb.init_pos); /* Get next location */ + continue; + } + saved_name++; + } + + /* Remove newline from saved_name */ + sn_size = strlen(saved_name); + sn_size -= 1; + if (saved_name[sn_size] == '\n') { + saved_name[sn_size] = '\0'; + } + + /* If name is different, go to next one */ + if (strcmp(f_name, saved_name) != 0) { + /* Save current location */ + fgetpos(fp, &sdb.init_pos); + continue; + } + + saved_sum = sdb.buf; + + /* First three bytes are for frequency check */ + saved_sum += 3; + + /* Checksum match, we can just return and keep going */ + if (strcmp(saved_sum, c_sum) == 0) { + lf->data = NULL; + return (0); + } + + + + + /* If we reached here, the checksum of the file has changed */ + if (saved_sum[-3] == '!') { + p++; + if (saved_sum[-2] == '!') { + p++; + if (saved_sum[-1] == '!') { + p++; + } else if (saved_sum[-1] == '?') { + p += 2; + } + } + } + + /* Check the number of changes */ + if (!Config.syscheck_auto_ignore) { + sdb.syscheck_dec->id = sdb.id1; + } else { + switch (p) { + case 0: + sdb.syscheck_dec->id = sdb.id1; + break; + + case 1: + sdb.syscheck_dec->id = sdb.id2; + break; + + case 2: + sdb.syscheck_dec->id = sdb.id3; + break; + + default: + lf->data = NULL; + return (0); + break; + } + } + + /* Add new checksum to the database */ + /* Commenting the file entry and adding a new one later */ + if (fsetpos(fp, &sdb.init_pos)) { + merror("%s: Error handling integrity database (fsetpos).", ARGV0); + return (0); + } + fputc('#', fp); + + /* Add the new entry at the end of the file */ + fseek(fp, 0, SEEK_END); + fprintf(fp, "%c%c%c%s !%ld %s\n", + '!', + p >= 1 ? '!' : '+', + p == 2 ? '!' : (p > 2) ? '?' : '+', + c_sum, + (long int)lf->time, + f_name); + fflush(fp); + + /* File deleted */ + if (c_sum[0] == '-' && c_sum[1] == '1') { + sdb.syscheck_dec->id = sdb.idd; + snprintf(sdb.comment, OS_MAXSTR, + "File '%.756s' was deleted. Unable to retrieve " + "checksum.", f_name); + } + + /* If file was re-added, do not compare changes */ + else if (saved_sum[0] == '-' && saved_sum[1] == '1') { + sdb.syscheck_dec->id = sdb.idn; + snprintf(sdb.comment, OS_MAXSTR, + "File '%.756s' was re-added.", f_name); + } + + else { + int oldperm = 0, newperm = 0; + + /* Provide more info about the file change */ + const char *oldsize = NULL, *newsize = NULL; + char *olduid = NULL, *newuid = NULL; + char *c_oldperm = NULL, *c_newperm = NULL; + char *oldgid = NULL, *newgid = NULL; + char *oldmd5 = NULL, *newmd5 = NULL; + char *oldsha1 = NULL, *newsha1 = NULL; + + oldsize = saved_sum; + newsize = c_sum; + + c_oldperm = strchr(saved_sum, ':'); + c_newperm = strchr(c_sum, ':'); + + /* Get old/new permissions */ + if (c_oldperm && c_newperm) { + *c_oldperm = '\0'; + c_oldperm++; + + *c_newperm = '\0'; + c_newperm++; + + /* Get old/new uid/gid */ + olduid = strchr(c_oldperm, ':'); + newuid = strchr(c_newperm, ':'); + + if (olduid && newuid) { + *olduid = '\0'; + *newuid = '\0'; + olduid++; + newuid++; + + oldgid = strchr(olduid, ':'); + newgid = strchr(newuid, ':'); + + if (oldgid && newgid) { + *oldgid = '\0'; + *newgid = '\0'; + oldgid++; + newgid++; + + /* Get MD5 */ + oldmd5 = strchr(oldgid, ':'); + newmd5 = strchr(newgid, ':'); + + if (oldmd5 && newmd5) { + *oldmd5 = '\0'; + *newmd5 = '\0'; + oldmd5++; + newmd5++; + + /* Get SHA-1 */ + oldsha1 = strchr(oldmd5, ':'); + newsha1 = strchr(newmd5, ':'); + + if (oldsha1 && newsha1) { + *oldsha1 = '\0'; + *newsha1 = '\0'; + oldsha1++; + newsha1++; + } + } + } + } + } + + /* Get integer values */ + if (c_newperm && c_oldperm) { + newperm = atoi(c_newperm); + oldperm = atoi(c_oldperm); + } + + /* Generate size message */ + if (!oldsize || !newsize || strcmp(oldsize, newsize) == 0) { + sdb.size[0] = '\0'; + } else { + snprintf(sdb.size, OS_FLSIZE, + "Size changed from '%s' to '%s'\n", + oldsize, newsize); + + os_strdup(oldsize, lf->size_before); + os_strdup(newsize, lf->size_after); + } + + /* Permission message */ + if (oldperm == newperm) { + sdb.perm[0] = '\0'; + } else if (oldperm > 0 && newperm > 0) { + char opstr[10]; + char npstr[10]; + + strncpy(opstr, agent_file_perm(c_oldperm), sizeof(opstr) - 1); + strncpy(npstr, agent_file_perm(c_newperm), sizeof(npstr) - 1); + + snprintf(sdb.perm, OS_FLSIZE, "Permissions changed from " + "'%9.9s' to '%9.9s'\n", opstr, npstr); + + lf->perm_before = oldperm; + lf->perm_after = newperm; + } + + /* Ownership message */ + if (!newuid || !olduid || strcmp(newuid, olduid) == 0) { + sdb.owner[0] = '\0'; + } else { + snprintf(sdb.owner, OS_FLSIZE, "Ownership was '%s', " + "now it is '%s'\n", + olduid, newuid); + + + os_strdup(olduid, lf->owner_before); + os_strdup(newuid, lf->owner_after); + } + + /* Group ownership message */ + if (!newgid || !oldgid || strcmp(newgid, oldgid) == 0) { + sdb.gowner[0] = '\0'; + } else { + snprintf(sdb.gowner, OS_FLSIZE, "Group ownership was '%s', " + "now it is '%s'\n", + oldgid, newgid); + os_strdup(oldgid, lf->gowner_before); + os_strdup(newgid, lf->gowner_after); + } + + /* MD5 message */ + if (!newmd5 || !oldmd5 || strcmp(newmd5, oldmd5) == 0) { + sdb.md5[0] = '\0'; + } else { + snprintf(sdb.md5, OS_FLSIZE, "Old md5sum was: '%s'\n" + "New md5sum is : '%s'\n", + oldmd5, newmd5); + os_strdup(oldmd5, lf->md5_before); + os_strdup(newmd5, lf->md5_after); + } + + /* SHA-1 message */ + if (!newsha1 || !oldsha1 || strcmp(newsha1, oldsha1) == 0) { + sdb.sha1[0] = '\0'; + } else { + snprintf(sdb.sha1, OS_FLSIZE, "Old sha1sum was: '%s'\n" + "New sha1sum is : '%s'\n", + oldsha1, newsha1); + os_strdup(oldsha1, lf->sha1_before); + os_strdup(newsha1, lf->sha1_after); + } + + /* Provide information about the file */ + snprintf(sdb.comment, OS_MAXSTR, "Integrity checksum changed for: " + "'%.756s'\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s%s", + f_name, + sdb.size, + sdb.perm, + sdb.owner, + sdb.gowner, + sdb.md5, + sdb.sha1, + lf->data == NULL ? "" : "What changed:\n", + lf->data == NULL ? "" : lf->data + ); + } + + /* Create a new log message */ + free(lf->full_log); + os_strdup(sdb.comment, lf->full_log); + lf->log = lf->full_log; + lf->data = NULL; + + /* Set decoder */ + lf->decoder_info = sdb.syscheck_dec; + + return (1); + + } /* Continue */ + + /* If we reach here, this file is not present in our database */ + fseek(fp, 0, SEEK_END); + fprintf(fp, "+++%s !%ld %s\n", c_sum, (long int)lf->time, f_name); + fflush(fp); + + /* Alert if configured to notify on new files */ + /* TODO: debugging this - Scott */ + /* if ((Config.syscheck_alert_new == 1) && (DB_IsCompleted(agent_id))) { */ + if (Config.syscheck_alert_new == 1) { + sdb.syscheck_dec->id = sdb.idn; + + char *newfilec_sum = NULL; + char *newfilemd5 = NULL; + char *newfilesha1 = NULL; + + os_strdup(c_sum, newfilec_sum); + + char *token = strtok(newfilec_sum, ":"); + + int tok_count = 1; + + while (token != NULL) + { + if(tok_count == 5) + { + newfilemd5 = token; + } + if(tok_count == 6) + { + newfilesha1 = token; + } + + token = strtok(NULL, ":"); + tok_count++; + } + + /* SHA-1 message */ + snprintf(sdb.sha1, OS_FLSIZE, + "New sha1sum is : '%s'\n", + newfilesha1); + os_strdup(newfilesha1, lf->sha1_after); + + /* MD5 message */ + snprintf(sdb.md5, OS_FLSIZE, + "New md5sum is : '%s'\n", + newfilemd5); + os_strdup(newfilemd5, lf->md5_after); + + /* New file message */ + snprintf(sdb.comment, OS_MAXSTR, + "New file '%.756s' " + "added to the file system.\n" + "%s" + "%s", + f_name, + sdb.sha1, + sdb.md5 + ); + + /* Create a new log message */ + free(lf->full_log); + os_strdup(sdb.comment, lf->full_log); + lf->log = lf->full_log; + + /* Set decoder */ + lf->decoder_info = sdb.syscheck_dec; + lf->data = NULL; + + return (1); + } + + lf->data = NULL; + return (0); +} + +/* Special decoder for syscheck + * Not using the default decoding lib for simplicity + * and to be less resource intensive + */ +int DecodeSyscheck(Eventinfo *lf) +{ + const char *c_sum; + char *f_name; + +#ifdef SQLITE_ENABLED + char *p; + char stmt[OS_MAXSTR + 1]; + sqlite3_stmt *res; + int error = 0; + int rec_count = 0; + const char *tail; +#endif // SQLITE_ENABLED + + /* Every syscheck message must be in the following format: + * checksum filename + */ + f_name = strchr(lf->log, ' '); + if (f_name == NULL) { + /* If we don't have a valid syscheck message, it may be + * a database completed message + */ + if (strcmp(lf->log, HC_SK_DB_COMPLETED) == 0) { + DB_SetCompleted(lf); + return (0); + } + + merror(SK_INV_MSG, ARGV0); + return (0); + } + + /* Zero to get the check sum */ + *f_name = '\0'; + f_name++; + + /* Get diff */ + lf->data = strchr(f_name, '\n'); + if (lf->data) { + *lf->data = '\0'; + lf->data++; + } else { + lf->data = NULL; + } + + /* Check if file is supposed to be ignored */ + if (Config.syscheck_ignore) { + char **ff_ig = Config.syscheck_ignore; + + while (*ff_ig) { + if (strncasecmp(*ff_ig, f_name, strlen(*ff_ig)) == 0) { + lf->data = NULL; + return (0); + } + + ff_ig++; + } + } + + /* Checksum is at the beginning of the log */ + c_sum = lf->log; + + /* Extract the MD5 hash and search for it in the allowlist + * Sample message: + * 0:0:0:0:78f5c869675b1d09ddad870adad073f9:bd6c8d7a58b462aac86475e59af0e22954039c50 + */ +#ifdef SQLITE_ENABLED + if (Config.md5_allowlist) { + extern sqlite3 *conn; + if ((p = extract_token(c_sum, ":", 4))) { + if (!validate_md5(p)) { /* Never trust input from other origin */ + merror("%s: Not a valid MD5 hash: '%s'", ARGV0, p); + return(0); + } + debug1("%s: Checking MD5 '%s' in %s", ARGV0, p, Config.md5_allowlist); + sprintf(stmt, "select md5sum from files where md5sum = \"%s\"", p); + error = sqlite3_prepare_v2(conn, stmt, 1000, &res, &tail); + if (error == SQLITE_OK) { + while (sqlite3_step(res) == SQLITE_ROW) { + rec_count++; + } + if (rec_count) { + sqlite3_finalize(res); + //sqlite3_close(conn); + merror(MD5_NOT_CHECKED, ARGV0, p); + return(0); + } + } + sqlite3_finalize(res); + } + } +#endif + + + /* Search for file changes */ + return (DB_Search(f_name, c_sum, lf)); +} + diff --git a/src/analysisd/dodiff.c b/src/analysisd/dodiff.c new file mode 100644 index 000000000..d05860153 --- /dev/null +++ b/src/analysisd/dodiff.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "dodiff.h" + +#include "shared.h" + +static int _add2last(const char *str, size_t strsize, const char *file) +{ + FILE *fp; + + fp = fopen(file, "w"); + if (!fp) { + /* Try to create the directories */ + char *dirrule = NULL; + char *diragent = NULL; + + dirrule = strrchr(file, '/'); + if (!dirrule) { + merror("%s: ERROR: Invalid file name to diff: %s", + ARGV0, file); + return (0); + } + *dirrule = '\0'; + + diragent = strrchr(file, '/'); + if (!diragent) { + merror("%s: ERROR: Invalid file name to diff (2): %s", + ARGV0, file); + return (0); + } + *diragent = '\0'; + + /* Check if the diragent exists */ + if (IsDir(file) != 0) { + if (mkdir(file, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, file, errno, strerror(errno)); + return (0); + } + } + *diragent = '/'; + + if (IsDir(file) != 0) { + if (mkdir(file, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, file, errno, strerror(errno)); + return (0); + } + } + *dirrule = '/'; + + fp = fopen(file, "w"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, file, errno, strerror(errno)); + return (0); + } + } + + fwrite(str, strsize + 1, 1, fp); + fclose(fp); + return (1); +} + +int doDiff(RuleInfo *rule, const Eventinfo *lf) +{ + time_t date_of_change; + char *htpt = NULL; + char flastfile[OS_SIZE_2048 + 1]; + char flastcontent[OS_SIZE_8192 + 1]; + + /* Clean up global */ + flastcontent[0] = '\0'; + flastcontent[OS_SIZE_8192] = '\0'; + rule->last_events[0] = NULL; + + if (lf->hostname[0] == '(') { + htpt = strchr(lf->hostname, ')'); + if (htpt) { + *htpt = '\0'; + } + snprintf(flastfile, OS_SIZE_2048, "%s/%s/%d/%s", DIFF_DIR, lf->hostname + 1, + rule->sigid, DIFF_LAST_FILE); + + if (htpt) { + *htpt = ')'; + } + htpt = NULL; + } else { + snprintf(flastfile, OS_SIZE_2048, "%s/%s/%d/%s", DIFF_DIR, lf->hostname, + rule->sigid, DIFF_LAST_FILE); + } + + /* lf->size can't be too long */ + if (lf->size >= OS_SIZE_8192) { + merror("%s: ERROR: event size (%ld) too long for diff.", ARGV0, lf->size); + return (0); + } + + /* Check if last diff exists */ + date_of_change = File_DateofChange(flastfile); + if (date_of_change <= 0) { + if (!_add2last(lf->log, lf->size, flastfile)) { + merror("%s: ERROR: unable to create last file: %s", ARGV0, flastfile); + return (0); + } + return (0); + } else { + FILE *fp; + size_t n; + fp = fopen(flastfile, "r"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, flastfile, errno, strerror(errno)); + return (0); + } + + n = fread(flastcontent, 1, OS_SIZE_8192, fp); + if (n > 0) { + flastcontent[n] = '\0'; + } else { + merror("%s: ERROR: read error on %s", ARGV0, flastfile); + fclose(fp); + return (0); + } + fclose(fp); + } + + /* Nothing changed */ + if (strcmp(flastcontent, lf->log) == 0) { + return (0); + } + + if (!_add2last(lf->log, lf->size, flastfile)) { + merror("%s: ERROR: unable to create last file: %s", ARGV0, flastfile); + } + + rule->last_events[0] = "Previous output:"; + rule->last_events[1] = flastcontent; + return (1); +} + diff --git a/src/analysisd/dodiff.h b/src/analysisd/dodiff.h new file mode 100644 index 000000000..d9ed75cb1 --- /dev/null +++ b/src/analysisd/dodiff.h @@ -0,0 +1,19 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _DODIFF_H_ +#define _DODIFF_H_ + +#include "rules.h" +#include "eventinfo.h" + +int doDiff(RuleInfo *rule, const Eventinfo *lf); + + +#endif /* _DODIFF_H_ */ diff --git a/src/analysisd/eventinfo.c b/src/analysisd/eventinfo.c new file mode 100644 index 000000000..9cc2b62e3 --- /dev/null +++ b/src/analysisd/eventinfo.c @@ -0,0 +1,692 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "config.h" +#include "analysisd.h" +#include "eventinfo.h" +#include "os_regex/os_regex.h" + +/* Global definitions */ +#ifdef TESTRULE +int full_output; +int alert_only; +#endif + + +/* Search last times a signature fired + * Will look for only that specific signature. + */ +Eventinfo *Search_LastSids(Eventinfo *my_lf, RuleInfo *rule) +{ + Eventinfo *lf; + Eventinfo *first_lf; + OSListNode *lf_node; + + /* Set frequency to 0 */ + rule->__frequency = 0; + + /* Checking if sid search is valid */ + if (!rule->sid_search) { + merror("%s: ERROR: No sid search.", ARGV0); + return (NULL); + } + + /* Get last node */ + lf_node = OSList_GetLastNode(rule->sid_search); + if (!lf_node) { + return (NULL); + } + first_lf = (Eventinfo *)lf_node->data; + + do { + lf = (Eventinfo *)lf_node->data; + + /* If time is outside the timeframe, return */ + if ((c_time - lf->time) > rule->timeframe) { + return (NULL); + } + + /* We avoid multiple triggers for the same rule + * or rules with a lower level. + */ + else if (lf->matched >= rule->level) { + return (NULL); + } + + /* Check for same ID */ + if (rule->context_opts & SAME_ID) { + if ((!lf->id) || (!my_lf->id)) { + continue; + } + + if (strcmp(lf->id, my_lf->id) != 0) { + continue; + } + } + + /* Check for repetitions from same src_ip */ + if (rule->context_opts & SAME_SRCIP) { + if ((!lf->srcip) || (!my_lf->srcip)) { + continue; + } + + if (strcmp(lf->srcip, my_lf->srcip) != 0) { + continue; + } + } + + /* Grouping of additional data */ + if (rule->alert_opts & SAME_EXTRAINFO) { + /* Check for same source port */ + if (rule->context_opts & SAME_SRCPORT) { + if ((!lf->srcport) || (!my_lf->srcport)) { + continue; + } + + if (strcmp(lf->srcport, my_lf->srcport) != 0) { + continue; + } + } + + /* Check for same dst port */ + if (rule->context_opts & SAME_DSTPORT) { + if ((!lf->dstport) || (!my_lf->dstport)) { + continue; + } + + if (strcmp(lf->dstport, my_lf->dstport) != 0) { + continue; + } + } + + /* Check for repetitions on user error */ + if (rule->context_opts & SAME_USER) { + if ((!lf->dstuser) || (!my_lf->dstuser)) { + continue; + } + + if (strcmp(lf->dstuser, my_lf->dstuser) != 0) { + continue; + } + } + + /* Check for same location */ + if (rule->context_opts & SAME_LOCATION) { + if (strcmp(lf->hostname, my_lf->hostname) != 0) { + continue; + } + } + + /* Check for different URLs */ + if (rule->context_opts & DIFFERENT_URL) { + if ((!lf->url) || (!my_lf->url)) { + continue; + } + + if (strcmp(lf->url, my_lf->url) == 0) { + continue; + } + } + + /* GEOIP version of check for repetitions from same src_ip */ + if (rule->context_opts & DIFFERENT_SRCGEOIP) { + if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) { + continue; + } + + if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) { + continue; + } + } + + + } + + /* We avoid multiple triggers for the same rule + * or rules with a lower level. + */ + else if (lf->matched >= rule->level) { + return (NULL); + } + + + + /* Check if the number of matches worked */ + if (rule->__frequency <= 10) { + rule->last_events[rule->__frequency] + = lf->full_log; + rule->last_events[rule->__frequency + 1] + = NULL; + } + + if (rule->__frequency < rule->frequency) { + rule->__frequency++; + continue; + } + rule->__frequency++; + + + /* If reached here, we matched */ + my_lf->matched = rule->level; + lf->matched = rule->level; + first_lf->matched = rule->level; + + return (lf); + + } while ((lf_node = lf_node->prev) != NULL); + + return (NULL); +} + +/* Search last times a group fired + * Will look for only that specific group on that rule. + */ +Eventinfo *Search_LastGroups(Eventinfo *my_lf, RuleInfo *rule) +{ + Eventinfo *lf; + Eventinfo *first_lf; + OSListNode *lf_node; + + /* Set frequency to 0 */ + rule->__frequency = 0; + + /* Check if sid search is valid */ + if (!rule->group_search) { + merror("%s: No group search!", ARGV0); + return (NULL); + } + + /* Get last node */ + lf_node = OSList_GetLastNode(rule->group_search); + if (!lf_node) { + return (NULL); + } + first_lf = (Eventinfo *)lf_node->data; + + do { + lf = (Eventinfo *)lf_node->data; + + /* If time is outside the timeframe, return */ + if ((c_time - lf->time) > rule->timeframe) { + return (NULL); + } + + /* We avoid multiple triggers for the same rule + * or rules with a lower level. + */ + else if (lf->matched >= rule->level) { + return (NULL); + } + + /* Check for same ID */ + if (rule->context_opts & SAME_ID) { + if ((!lf->id) || (!my_lf->id)) { + continue; + } + + if (strcmp(lf->id, my_lf->id) != 0) { + continue; + } + } + + /* Check for repetitions from same src_ip */ + if (rule->context_opts & SAME_SRCIP) { + if ((!lf->srcip) || (!my_lf->srcip)) { + continue; + } + + if (strcmp(lf->srcip, my_lf->srcip) != 0) { + continue; + } + } + + /* Grouping of additional data */ + if (rule->alert_opts & SAME_EXTRAINFO) { + /* Check for same source port */ + if (rule->context_opts & SAME_SRCPORT) { + if ((!lf->srcport) || (!my_lf->srcport)) { + continue; + } + + if (strcmp(lf->srcport, my_lf->srcport) != 0) { + continue; + } + } + + /* Check for same dst port */ + if (rule->context_opts & SAME_DSTPORT) { + if ((!lf->dstport) || (!my_lf->dstport)) { + continue; + } + + if (strcmp(lf->dstport, my_lf->dstport) != 0) { + continue; + } + } + + /* Check for repetitions on user error */ + if (rule->context_opts & SAME_USER) { + if ((!lf->dstuser) || (!my_lf->dstuser)) { + continue; + } + + if (strcmp(lf->dstuser, my_lf->dstuser) != 0) { + continue; + } + } + + /* Check for same location */ + if (rule->context_opts & SAME_LOCATION) { + if (strcmp(lf->hostname, my_lf->hostname) != 0) { + continue; + } + } + + + /* Check for different URLs */ + if (rule->context_opts & DIFFERENT_URL) { + if ((!lf->url) || (!my_lf->url)) { + continue; + } + + if (strcmp(lf->url, my_lf->url) == 0) { + continue; + } + } + + + /* Check for different from same srcgeoip */ + if (rule->context_opts & DIFFERENT_SRCGEOIP) { + + if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) { + continue; + } + + if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) { + continue; + } + } + + + } + /* We avoid multiple triggers for the same rule + * or rules with a lower level. + */ + else if (lf->matched >= rule->level) { + return (NULL); + } + + + /* Check if the number of matches worked */ + if (rule->__frequency < rule->frequency) { + if (rule->__frequency <= 10) { + rule->last_events[rule->__frequency] + = lf->full_log; + rule->last_events[rule->__frequency + 1] + = NULL; + } + + rule->__frequency++; + continue; + } + + + /* If reached here, we matched */ + my_lf->matched = rule->level; + lf->matched = rule->level; + first_lf->matched = rule->level; + + return (lf); + + + } while ((lf_node = lf_node->prev) != NULL); + + return (NULL); +} + + +/* Look if any of the last events (inside the timeframe) + * match the specified rule + */ +Eventinfo *Search_LastEvents(Eventinfo *my_lf, RuleInfo *rule) +{ + EventNode *eventnode_pt; + Eventinfo *lf; + Eventinfo *first_lf; + + + /* Last events */ + eventnode_pt = OS_GetLastEvent(); + if (!eventnode_pt) { + /* Nothing found */ + return (NULL); + } + + /* Set frequency to 0 */ + rule->__frequency = 0; + first_lf = (Eventinfo *)eventnode_pt->event; + + /* Search all previous events */ + do { + lf = eventnode_pt->event; + + /* If time is outside the timeframe, return */ + if ((c_time - lf->time) > rule->timeframe) { + return (NULL); + } + + /* We avoid multiple triggers for the same rule + * or rules with a lower level. + */ + else if (lf->matched >= rule->level) { + return (NULL); + } + + /* The category must be the same */ + else if (lf->decoder_info->type != my_lf->decoder_info->type) { + continue; + } + + /* If regex does not match, go to next */ + if (rule->if_matched_regex) { + if (!OSRegex_Execute(lf->log, rule->if_matched_regex)) { + /* Didn't match */ + continue; + } + } + + /* Check for repetitions on user error */ + if (rule->context_opts & SAME_USER) { + if ((!lf->dstuser) || (!my_lf->dstuser)) { + continue; + } + + if (strcmp(lf->dstuser, my_lf->dstuser) != 0) { + continue; + } + } + + /* Check for same ID */ + if (rule->context_opts & SAME_ID) { + if ((!lf->id) || (!my_lf->id)) { + continue; + } + + if (strcmp(lf->id, my_lf->id) != 0) { + continue; + } + } + + /* Check for repetitions from same src_ip */ + if (rule->context_opts & SAME_SRCIP) { + if ((!lf->srcip) || (!my_lf->srcip)) { + continue; + } + + if (strcmp(lf->srcip, my_lf->srcip) != 0) { + continue; + } + } + + /* Check for different urls */ + if (rule->context_opts & DIFFERENT_URL) { + if ((!lf->url) || (!my_lf->url)) { + continue; + } + + if (strcmp(lf->url, my_lf->url) == 0) { + continue; + } + } + + /* Check for different from same srcgeoip */ + if (rule->context_opts & DIFFERENT_SRCGEOIP) { + + if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) { + continue; + } + + if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) { + continue; + } + } + + /* We avoid multiple triggers for the same rule + * or rules with a lower level. + */ + else if (lf->matched >= rule->level) { + return (NULL); + } + + + + + /* Check if the number of matches worked */ + if (rule->__frequency < rule->frequency) { + if (rule->__frequency <= 10) { + rule->last_events[rule->__frequency] + = lf->full_log; + rule->last_events[rule->__frequency + 1] + = NULL; + } + + rule->__frequency++; + continue; + } + + /* If reached here, we matched */ + my_lf->matched = rule->level; + lf->matched = rule->level; + first_lf->matched = rule->level; + + return (lf); + + } while ((eventnode_pt = eventnode_pt->next) != NULL); + + return (NULL); +} + +/* Zero the loginfo structure */ +void Zero_Eventinfo(Eventinfo *lf) +{ + lf->log = NULL; + lf->full_log = NULL; + lf->hostname = NULL; + lf->program_name = NULL; + lf->location = NULL; + + lf->srcip = NULL; + lf->srcgeoip = NULL; + lf->dstip = NULL; + lf->dstgeoip = NULL; + lf->srcport = NULL; + lf->dstport = NULL; + lf->protocol = NULL; + lf->action = NULL; + lf->srcuser = NULL; + lf->dstuser = NULL; + lf->id = NULL; + lf->status = NULL; + lf->command = NULL; + lf->url = NULL; + lf->data = NULL; + lf->systemname = NULL; + + if (lf->fields) { + int i; + for (i = 0; i < Config.decoder_order_size; i++) { + free(lf->fields[i]); + } + } + + lf->time = 0; + lf->matched = 0; + + lf->year = 0; + lf->mon[3] = '\0'; + lf->hour[9] = '\0'; + lf->day = 0; + + lf->generated_rule = NULL; + lf->sid_node_to_delete = NULL; + lf->decoder_info = NULL_Decoder; + + lf->filename = NULL; + lf->perm_before = 0; + lf->perm_after = 0; + lf->md5_before = NULL; + lf->md5_after = NULL; + lf->sha1_before = NULL; + lf->sha1_after = NULL; + lf->size_before = NULL; + lf->size_after = NULL; + lf->owner_before = NULL; + lf->owner_after = NULL; + lf->gowner_before = NULL; + lf->gowner_after = NULL; + + return; +} + +/* Free the loginfo structure */ +void Free_Eventinfo(Eventinfo *lf) +{ + if (!lf) { + merror("%s: Trying to free NULL event. Inconsistent..", ARGV0); + return; + } + + if (lf->full_log) { + free(lf->full_log); + } + if (lf->location) { + free(lf->location); + } + + if (lf->srcip) { + free(lf->srcip); + } + + if(lf->srcgeoip) { + free(lf->srcgeoip); + lf->srcgeoip = NULL; + } + + if (lf->dstip) { + free(lf->dstip); + } + + if(lf->dstgeoip) { + free(lf->dstgeoip); + lf->dstgeoip = NULL; + } + + if (lf->srcport) { + free(lf->srcport); + } + if (lf->dstport) { + free(lf->dstport); + } + if (lf->protocol) { + free(lf->protocol); + } + if (lf->action) { + free(lf->action); + } + if (lf->status) { + free(lf->status); + } + if (lf->srcuser) { + free(lf->srcuser); + } + if (lf->dstuser) { + free(lf->dstuser); + } + if (lf->id) { + free(lf->id); + } + if (lf->command) { + free(lf->command); + } + if (lf->url) { + free(lf->url); + } + + if (lf->data) { + free(lf->data); + } + if (lf->systemname) { + free(lf->systemname); + } + + if (lf->fields) { + int i; + for (i = 0; i < Config.decoder_order_size; i++) { + free(lf->fields[i]); + } + free(lf->fields); + } + + if (lf->filename) { + free(lf->filename); + } + if (lf->md5_before) { + free(lf->md5_before); + } + if (lf->md5_after) { + free(lf->md5_after); + } + if (lf->sha1_before) { + free(lf->sha1_before); + } + if (lf->sha1_after) { + free(lf->sha1_after); + } + if (lf->size_before) { + free(lf->size_before); + } + if (lf->size_after) { + free(lf->size_after); + } + if (lf->owner_before) { + free(lf->owner_before); + } + if (lf->owner_after) { + free(lf->owner_after); + } + if (lf->gowner_before) { + free(lf->gowner_before); + } + if (lf->gowner_after) { + free(lf->gowner_after); + } + + /* Free node to delete */ + if (lf->sid_node_to_delete) { + OSList_DeleteThisNode(lf->generated_rule->sid_prev_matched, + lf->sid_node_to_delete); + } else if (lf->generated_rule && lf->generated_rule->group_prev_matched) { + unsigned int i = 0; + + while (i < lf->generated_rule->group_prev_matched_sz) { + OSList_DeleteOldestNode(lf->generated_rule->group_prev_matched[i]); + i++; + } + } + + /* We dont need to free: + * fts + * comment + */ + free(lf); + lf = NULL; + + return; +} + diff --git a/src/analysisd/eventinfo.h b/src/analysisd/eventinfo.h new file mode 100644 index 000000000..2366b06ec --- /dev/null +++ b/src/analysisd/eventinfo.h @@ -0,0 +1,162 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _EVTINFO__H +#define _EVTINFO__H + +#include "rules.h" +#include "decoders/decoder.h" + +/* Event Information structure */ +typedef struct _Eventinfo { + /* Extracted from the event */ + char *log; + char *full_log; + char *location; + char *hostname; + char *program_name; + + /* Extracted from the decoders */ + char *srcip; + char *srcgeoip; + char *dstip; + char *dstgeoip; + char *srcport; + char *dstport; + char *protocol; + char *action; + char *srcuser; + char *dstuser; + char *id; + char *status; + char *command; + char *url; + char *data; + char *systemname; + char **fields; + + + + /* Pointer to the rule that generated it */ + RuleInfo *generated_rule; + + /* Pointer to the decoder that matched */ + OSDecoderInfo *decoder_info; + + /* Sid node to delete */ + OSListNode *sid_node_to_delete; + + /* Extract when the event fires a rule */ + size_t size; + size_t p_name_size; + + /* Other internal variables */ + int matched; + + time_t time; + int day; + int year; + char hour[10]; + char mon[4]; + + /* SYSCHECK Results variables */ + char *filename; + int perm_before; + int perm_after; + char *md5_before; + char *md5_after; + char *sha1_before; + char *sha1_after; + char *size_before; + char *size_after; + char *owner_before; + char *owner_after; + char *gowner_before; + char *gowner_after; +} Eventinfo; + +/* Events List structure */ +typedef struct _EventNode { + Eventinfo *event; + struct _EventNode *next; + struct _EventNode *prev; +} EventNode; + +#ifdef TESTRULE +extern int full_output; +extern int alert_only; +#endif + +/* Types of events (from decoders) */ +#define UNKNOWN 0 /* Unknown */ +#define SYSLOG 1 /* syslog messages */ +#define IDS 2 /* IDS alerts */ +#define FIREWALL 3 /* Firewall events */ +#define WEBLOG 7 /* Apache logs */ +#define SQUID 8 /* Squid logs */ +#define DECODER_WINDOWS 9 /* Windows logs */ +#define HOST_INFO 10 /* Host information logs (from nmap or similar) */ +#define openarmor_RL 11 /* openarmor rules */ +#define openarmor_ALERT 12 /* openarmor alerts */ + +/* FTS allowed values */ +#define FTS_NAME 001000 +#define FTS_SRCUSER 002000 +#define FTS_DSTUSER 004000 +#define FTS_SRCIP 000100 +#define FTS_DSTIP 000200 +#define FTS_LOCATION 000400 +#define FTS_ID 000010 +#define FTS_DATA 000020 +#define FTS_SYSTEMNAME 000040 +#define FTS_DONE 010000 + +/** Functions for events **/ + +/* Search for matches in the last events */ +Eventinfo *Search_LastEvents(Eventinfo *lf, RuleInfo *currently_rule); +Eventinfo *Search_LastSids(Eventinfo *my_lf, RuleInfo *currently_rule); +Eventinfo *Search_LastGroups(Eventinfo *my_lf, RuleInfo *currently_rule); + +/* Zero the eventinfo structure */ +void Zero_Eventinfo(Eventinfo *lf); + +/* Free the eventinfo structure */ +void Free_Eventinfo(Eventinfo *lf); + +/* Add and event to the list of previous events */ +void OS_AddEvent(Eventinfo *lf); + +/* Return the last event from the Event list */ +EventNode *OS_GetLastEvent(void); + +/* Create the event list. Maxsize must be specified */ +void OS_CreateEventList(int maxsize); + +/* Pointers to the event decoders */ +void *SrcUser_FP(Eventinfo *lf, char *field, int order); +void *DstUser_FP(Eventinfo *lf, char *field, int order); +void *SrcIP_FP(Eventinfo *lf, char *field, int order); +void *DstIP_FP(Eventinfo *lf, char *field, int order); +void *SrcPort_FP(Eventinfo *lf, char *field, int order); +void *DstPort_FP(Eventinfo *lf, char *field, int order); +void *Protocol_FP(Eventinfo *lf, char *field, int order); +void *Action_FP(Eventinfo *lf, char *field, int order); +void *ID_FP(Eventinfo *lf, char *field, int order); +void *Url_FP(Eventinfo *lf, char *field, int order); +void *Data_FP(Eventinfo *lf, char *field, int order); +void *Status_FP(Eventinfo *lf, char *field, int order); +void *SystemName_FP(Eventinfo *lf, char *field, int order); +void *FileName_FP(Eventinfo *lf, char *field, int order); +void *DynamicField_FP(Eventinfo *lf, char *field, int order); +void *None_FP(Eventinfo *lf, char *field, int order); + + +#endif /* _EVTINFO__H */ + diff --git a/src/analysisd/eventinfo_list.c b/src/analysisd/eventinfo_list.c new file mode 100644 index 000000000..8d1f35cbd --- /dev/null +++ b/src/analysisd/eventinfo_list.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "eventinfo.h" +#include "rules.h" + +/* Local variables */ +static EventNode *eventnode; +static EventNode *lastnode; + +static int _memoryused = 0; +static int _memorymaxsize = 0; +int _max_freq = 0; + + +/* Create the Event List */ +void OS_CreateEventList(int maxsize) +{ + eventnode = NULL; + _memorymaxsize = maxsize; + _memoryused = 0; + + debug1("%s: OS_CreateEventList completed.", ARGV0); + return; +} + +/* Get the last event -- or first node */ +EventNode *OS_GetLastEvent() +{ + EventNode *eventnode_pt = eventnode; + + return (eventnode_pt); +} + +/* Add an event to the list -- always to the beginning */ +void OS_AddEvent(Eventinfo *lf) +{ + EventNode *tmp_node = eventnode; + + if (tmp_node) { + EventNode *new_node; + new_node = (EventNode *)calloc(1, sizeof(EventNode)); + + if (new_node == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Always add to the beginning of the list + * The new node will become the first node and + * new_node->next will be the previous first node + */ + new_node->next = tmp_node; + new_node->prev = NULL; + tmp_node->prev = new_node; + + eventnode = new_node; + + /* Add the event to the node */ + new_node->event = lf; + + _memoryused++; + + /* Need to remove the last nodes */ + if (_memoryused > _memorymaxsize) { + int i = 0; + EventNode *oldlast; + + /* Remove at least the last 10 events + * or the events that will not match anymore + * (higher than max frequency) + */ + while ((i < 10) || ((lf->time - lastnode->event->time) > _max_freq)) { + oldlast = lastnode; + lastnode = lastnode->prev; + lastnode->next = NULL; + + /* Free event info */ + Free_Eventinfo(oldlast->event); + free(oldlast); + + _memoryused--; + i++; + } + } + } + + else { + /* Add first node */ + eventnode = (EventNode *)calloc(1, sizeof(EventNode)); + if (eventnode == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + eventnode->prev = NULL; + eventnode->next = NULL; + eventnode->event = lf; + + lastnode = eventnode; + } + + return; +} + diff --git a/src/analysisd/format/json_extended.c b/src/analysisd/format/json_extended.c new file mode 100644 index 000000000..00c7c02ea --- /dev/null +++ b/src/analysisd/format/json_extended.c @@ -0,0 +1,379 @@ +/* Copyright (C) 2015 Wazuh Inc + * All rights reserved. + * + */ + +#include "json_extended.h" +#include + +#define MAX_MATCHES 10 +#define MAX_STRING 1024 +#define MAX_STRING_LESS 30 + +void W_ParseJSON(cJSON* root, const Eventinfo* lf) +{ + + // Parse hostname & Parse AGENTIP + if(lf->hostname) { + W_JSON_ParseHostname(root, lf->hostname); + W_JSON_ParseAgentIP(root, lf); + } + // Parse timestamp + if(lf->year && (strnlen(lf->mon, 3) > 0) && lf->day && (strnlen(lf->hour, 2) > 0)) { + W_JSON_ParseTimestamp(root, lf); + } + // Parse Location + if(lf->location) { + W_JSON_ParseLocation(root, lf, 0); + } + // Parse groups && Parse PCIDSS && Parse CIS + if(lf->generated_rule->group) { + W_JSON_ParseGroups(root, lf, 1); + } + // Parse CIS and PCIDSS rules from rootcheck .txt benchmarks + if(lf->full_log && W_isRootcheck(root, 1)) { + W_JSON_ParseRootcheck(root, lf, 1); + } +} + + +// Detect if the alert is coming from rootcheck controls. + +int W_isRootcheck(cJSON* root, int nested) +{ + cJSON* groups; + cJSON* group; + cJSON* rule; + char* group_json; + + int totalGroups, i; + + if(!nested) + rule = root; + else + rule = cJSON_GetObjectItem(root, "rule"); + + groups = cJSON_GetObjectItem(rule, "groups"); + totalGroups = cJSON_GetArraySize(groups); + for(i = 0; i < totalGroups; i++) { + group = cJSON_GetArrayItem(groups, i); + group_json = cJSON_Print(group); + if(strcmp(group_json, "\"rootcheck\"") == 0) { + free(group_json); + return 1; + } + free(group_json); + } + return 0; +} + + +// Getting security compliance field from rootcheck rules benchmarks .txt +void W_JSON_ParseRootcheck(cJSON* root, const Eventinfo* lf, int nested) +{ + regex_t r; + cJSON* rule; + cJSON* compliance; + const char* regex_text; + const char* find_text; + char* token; + char* token2; + char* results[MAX_MATCHES]; + int matches, i, j; + const char delim[2] = ":"; + const char delim2[2] = ","; + char fullog[MAX_STRING]; + + // Allocate memory + for(i = 0; i < MAX_MATCHES; i++) + results[i] = malloc((MAX_STRING_LESS) * sizeof(char)); + + // Getting groups object JSON + if(!nested) + rule = root; + else + rule = cJSON_GetObjectItem(root, "rule"); + + // Getting full log string + strncpy(fullog, lf->full_log, MAX_STRING - 1); + // Searching regex + regex_text = "\\{([A-Za-z0-9_]*: [A-Za-z0-9_., ]*)\\}"; + find_text = fullog; + compile_regex(&r, regex_text); + matches = match_regex(&r, find_text, results); + + if(matches > 0) { + for(i = 0; i < matches; i++) { + token = strtok(results[i], delim); + + trim(token); + cJSON_AddItemToObject(rule, token, compliance = cJSON_CreateArray()); + for(j = 0; token[j]; j++) { + token[j] = tolower(token[j]); + } + if(token) { + token = strtok(0, delim); + trim(token); + token2 = strtok(token, delim2); + while(token2) { + + trim(token2); + cJSON_AddItemToArray(compliance, cJSON_CreateString(token2)); + token2 = strtok(0, delim2); + } + } + } + } + regfree(&r); + for(i = 0; i < MAX_MATCHES; i++) + free(results[i]); +} + + + +// STRTOK every "-" delimiter to get differents groups to our json array. +void W_JSON_ParseGroups(cJSON* root, const Eventinfo* lf, int nested) +{ + cJSON* groups; + cJSON* rule; + int firstPCI, firstCIS, foundCIS, foundPCI; + char delim[2]; + char buffer[MAX_STRING]; + char* token; + + firstPCI = firstCIS = 1; + foundPCI = foundCIS = 0; + delim[0] = ','; + delim[1] = 0; + + if(!nested) + rule = root; + else + rule = cJSON_GetObjectItem(root, "rule"); + + cJSON_AddItemToObject(rule, "groups", groups = cJSON_CreateArray()); + strncpy(buffer, lf->generated_rule->group, sizeof(buffer) - 1); + + token = strtok(buffer, delim); + while(token) { + foundPCI = foundCIS = 0; + foundPCI = add_groupPCI(rule, token, firstPCI); + if(!foundPCI) + foundCIS = add_groupCIS(rule, token, firstCIS); + + if(foundPCI && firstPCI) + firstPCI = 0; + if(foundCIS && firstCIS) + firstCIS = 0; + + if(!foundPCI && !foundCIS) { + cJSON_AddItemToArray(groups, cJSON_CreateString(token)); + } + token = strtok(0, delim); + } +} + + + // Parse groups PCI +int add_groupPCI(cJSON* rule, char* group, int firstPCI) +{ + //char* len = NULL; + cJSON* pci; + char aux[strlen(group)]; + // If group begin with pci_dss_ we have a PCI group + if((startsWith("pci_dss_", group)) == 1) { + // Once we add pci_dss group and create array for PCI_DSS requirements + if(firstPCI == 1) { + pci = cJSON_CreateArray(); + cJSON_AddItemToObject(rule, "PCI_DSS", pci); + } else { + pci = cJSON_GetObjectItem(rule, "PCI_DSS"); + } + // Prepare string and add it to PCI dss array + strncpy(aux, group, strlen(group) - 1 ); + str_cut(aux, 0, 8); + cJSON_AddItemToArray(pci, cJSON_CreateString(aux)); + return 1; + } + return 0; +} + + +int add_groupCIS(cJSON* rule, char* group, int firstCIS) +{ + //char* len = NULL; + cJSON* cis; + char aux[strlen(group)]; + if((startsWith("cis_", group)) == 1) { + if(firstCIS == 1) { + cis = cJSON_CreateArray(); + cJSON_AddItemToObject(rule, "CIS", cis); + } else { + cis = cJSON_GetObjectItem(rule, "CIS"); + } + strncpy(aux, group, strlen(group) - 1); + str_cut(aux, 0, 4); + cJSON_AddItemToArray(cis, cJSON_CreateString(aux)); + return 1; + } + return 0; +} + + +// If hostname being with "(" means that alerts came from an agent, so we will remove the brakets +// ** TODO ** Regex instead str_cut +void W_JSON_ParseHostname(cJSON* root, char* hostname) +{ + if(hostname[0] == '(') { + char* search; + char string[MAX_STRING]; + strncpy(string, hostname, MAX_STRING - 1); + int index; + search = strchr(string, ')'); + if(search) { + index = (int)(search - string); + str_cut(string, index, -1); + str_cut(string, 0, 1); + cJSON_AddStringToObject(root, "agent_name", string); + } + } else { + cJSON_AddStringToObject(root, "agent_name", hostname); + } +} +// Parse timestamp +void W_JSON_ParseTimestamp(cJSON* root, const Eventinfo* lf) +{ + char* dateTimestamp = malloc(21); + sprintf(dateTimestamp, "%d %s %02d %s", lf->year, lf->mon, lf->day, lf->hour); + cJSON_AddStringToObject(root, "timestamp", dateTimestamp); + free(dateTimestamp); +} + + +// The IP of an agent usually comes in "hostname" field, we will extract it. +// ** TODO ** Regex instead str_cut +void W_JSON_ParseAgentIP(cJSON* root, const Eventinfo* lf) +{ + if(lf->hostname[0] == '(') { + char* search; + char string[MAX_STRING]; + strncpy(string, lf->hostname, MAX_STRING - 1); + int index; + search = strchr(string, ')'); + if(search) { + index = (int)(search - string); + str_cut(string, 0, index); + str_cut(string, 0, 2); + search = strchr(string, '-'); + index = (int)(search - string); + str_cut(string, index, -1); + cJSON_AddStringToObject(root, "agentip", string); + } + + } +} + // The file location usually comes with more information about the alert (like hostname or ip) we will extract just the "/var/folder/file.log". +void W_JSON_ParseLocation(cJSON* root, const Eventinfo* lf, int archives) +{ + if (archives != 0) { + debug1("openarmor-analysisd: DEBUG: archives != 0"); + } + if(lf->location[0] == '(') { + char* search; + char string[MAX_STRING]; + strncpy(string, lf->location, MAX_STRING - 1); + int index; + search = strchr(string, '>'); + if(search) { + index = (int)(search - string); + str_cut(string, 0, index); + str_cut(string, 0, 1); + + cJSON_AddStringToObject(root, "logfile", string); + } + } else { + cJSON_AddStringToObject(root, "logfile", lf->location); + } +} + + +#define MAX_ERROR_MSG 0x1000 +// Regex compilator +int compile_regex(regex_t* r, const char* regex_text) +{ + int status = regcomp(r, regex_text, REG_EXTENDED | REG_NEWLINE); + if(status != 0) { + char error_message[MAX_ERROR_MSG]; + regerror(status, r, error_message, MAX_ERROR_MSG); + debug1("Regex error compiling '%s': %s\n", regex_text, error_message); + return 1; + } + return 0; +} + +int match_regex(regex_t* r, const char* to_match, char* results[MAX_MATCHES]) +{ + const char* p = to_match; + const int n_matches = 10; + regmatch_t m[n_matches]; + int totalResults = 0; + while(1) { + int i = 0; + int nomatch = regexec(r, p, n_matches, m, 0); + if(nomatch) { + //printf ("No more matches.\n"); + return totalResults; + } + for(i = 0; i < n_matches; i++) { + int start; + int finish; + if(m[i].rm_so == -1) { + + break; + } + start = m[i].rm_so + (p - to_match); + finish = m[i].rm_eo + (p - to_match); + if(i > 0) { + sprintf(results[totalResults], "%.*s", (finish - start), to_match + start); + totalResults = totalResults + 1; + } + + } + p += m[0].rm_eo; + } + return 0; +} + +int str_cut(char* str, int begin, int len) +{ + int l = strlen(str); + + if(len < 0) + len = l - begin; + if(begin + len > l) + len = l - begin; + memmove(str + begin, str + begin + len, l - len + 1); + + return len; +} + +void trim(char* s) +{ + char* p = s; + int l = strlen(p); + + while(isspace(p[l - 1])) + p[--l] = 0; + while(*p && isspace(*p)) + ++p, --l; + + memmove(s, p, l + 1); +} + +int startsWith(const char *pre, const char *str) +{ + size_t lenpre = strlen(pre), + lenstr = strlen(str); + return lenstr < lenpre ? 0 : strncmp(pre, str, lenpre) == 0; +} + diff --git a/src/analysisd/format/json_extended.h b/src/analysisd/format/json_extended.h new file mode 100644 index 000000000..706d36b79 --- /dev/null +++ b/src/analysisd/format/json_extended.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2015 Wazuh Inc + * All rights reserved. + * + */ + +#ifndef __JSON_EXTENDED_H__ +#define __JSON_EXTENDED_H__ + +#include "eventinfo.h" +#include "cJSON.h" +#include + +#define MAX_MATCHES 10 + +// Main function, call the others parsers. +void W_ParseJSON(cJSON *root, const Eventinfo *lf); +// Parse hostname +void W_JSON_ParseHostname(cJSON *root, char *hostname); +// Parse Timestamp +void W_JSON_ParseTimestamp(cJSON *root, const Eventinfo *lf); +// Parse AgentIP +void W_JSON_ParseAgentIP(cJSON *root, const Eventinfo *lf); +// Parse Location +void W_JSON_ParseLocation(cJSON *root, const Eventinfo *lf, int archives); +// Parse Groups +void W_JSON_ParseGroups(cJSON *root, const Eventinfo *lf, int nested); +// Parse Groups Compliance +void W_JSON_ParseGroupsCompliance(cJSON *root, int nested); +// Parse Rootcheck compliance +void W_JSON_ParseRootcheck(cJSON *root, const Eventinfo *lf, int nested); +// Detecting if an alert comes from rootcheck +int W_isRootcheck(cJSON *root, int nested); +// Parsing PCI Compliance groups^M +int add_groupPCI(cJSON *rule, char * group, int firstPCI); +// Parsing CIS Compliance groups^M +int add_groupCIS(cJSON *rule, char * group, int firstCIS); +// Aux functions +int str_cut(char *str, int begin, int len); +int compile_regex (regex_t * r, const char * regex_text); +int match_regex (regex_t * r, const char * to_match, char * results[MAX_MATCHES]); +void trim(char * s); +void removeChar( char * string, char letter ); +int startsWith(const char *pre, const char *str); + +#endif diff --git a/src/analysisd/format/to_json.c b/src/analysisd/format/to_json.c new file mode 100644 index 000000000..62b89b0ce --- /dev/null +++ b/src/analysisd/format/to_json.c @@ -0,0 +1,383 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "to_json.h" +#include "json_extended.h" +#include "shared.h" +#include "rules.h" +#include "cJSON.h" +#include "config.h" +#include + + + +/* Convert Eventinfo to json */ +char *Eventinfo_to_jsonstr(const Eventinfo *lf) +{ + cJSON *root; + cJSON *rule; + cJSON *file_diff; + char *out; + int i; + + extern long int __crt_ftell; + + root = cJSON_CreateObject(); + + cJSON_AddItemToObject(root, "rule", rule = cJSON_CreateObject()); + + if ( lf->time ) { + + char alert_id[23]; + double timestamp_ms; + timestamp_ms = ((double)lf->time)*1000; + alert_id[22] = '\0'; + if((snprintf(alert_id, 22, "%ld.%ld", (long int)lf->time, __crt_ftell)) < 0) { + merror("snprintf failed"); + } + + cJSON_AddStringToObject(root, "id", alert_id); + cJSON_AddNumberToObject(root, "TimeStamp", timestamp_ms); + } + + + if(lf->generated_rule){ + if(lf->generated_rule->level) { + cJSON_AddNumberToObject(rule, "level", lf->generated_rule->level); + } + if(lf->generated_rule->comment) { + cJSON_AddStringToObject(rule, "comment", lf->generated_rule->comment); + } + if(lf->generated_rule->sigid) { + cJSON_AddNumberToObject(rule, "sidid", lf->generated_rule->sigid); + } + if(lf->generated_rule->cve) { + cJSON_AddStringToObject(rule, "cve", lf->generated_rule->cve); + } + if(lf->generated_rule->info) { + cJSON_AddStringToObject(rule, "info", lf->generated_rule->info); + } + if(lf->generated_rule->frequency){ + cJSON_AddNumberToObject(rule, "frequency", lf->generated_rule->frequency); + } + if(lf->generated_rule->firedtimes){ + cJSON_AddNumberToObject(rule, "firedtimes", lf->generated_rule->firedtimes); + } + } + + if( lf->decoder_info->name ) { + cJSON_AddStringToObject(root, "decoder", lf->decoder_info->name); + } + if( lf->decoder_info->parent ) { + cJSON_AddStringToObject(root, "decoder_parent", lf->decoder_info->parent); + } + + if (lf->action) { + cJSON_AddStringToObject(root, "action", lf->action); + } + if (lf->protocol) { + cJSON_AddStringToObject(root, "protocol", lf->protocol); + } + if (lf->srcip) { + cJSON_AddStringToObject(root, "srcip", lf->srcip); + } + +#ifdef LIBGEOIP_ENABLED + if (lf->srcgeoip && Config.geoip_jsonout) { + cJSON_AddStringToObject(root, "srcgeoip", lf->srcgeoip); + } +#endif + + if (lf->srcport) { + cJSON_AddStringToObject(root, "srcport", lf->srcport); + } + if (lf->srcuser) { + cJSON_AddStringToObject(root, "srcuser", lf->srcuser); + } + if (lf->dstip) { + cJSON_AddStringToObject(root, "dstip", lf->dstip); + } +#ifdef LIBGEOIP_ENABLED + if (lf->dstgeoip && Config.geoip_jsonout) { + cJSON_AddStringToObject(root, "dstgeoip", lf->dstgeoip); + } +#endif + + if (lf->dstport) { + cJSON_AddStringToObject(root, "dstport", lf->dstport); + } + if (lf->dstuser) { + cJSON_AddStringToObject(root, "dstuser", lf->dstuser); + } + if (lf->location) { + cJSON_AddStringToObject(root, "location", lf->location); + } + if (lf->full_log) { + cJSON_AddStringToObject(root, "full_log", lf->full_log); + } + if (lf->generated_rule->last_events && lf->generated_rule->last_events[1] && lf->generated_rule->last_events[1][0]) { + cJSON_AddStringToObject(root, "previous_output", lf->generated_rule->last_events[1]); + } + + if (lf->filename) { + file_diff = cJSON_CreateObject(); + cJSON_AddItemToObject(root, "SyscheckFile", file_diff); + + cJSON_AddStringToObject(file_diff, "path", lf->filename); + + if (lf->md5_before && lf->md5_after && strcmp(lf->md5_before, lf->md5_after) != 0 ) { + cJSON_AddStringToObject(file_diff, "md5_before", lf->md5_before); + cJSON_AddStringToObject(file_diff, "md5_after", lf->md5_after); + } + if(lf->sha1_before && lf->sha1_after && strcmp(lf->sha1_before, lf->sha1_after) != 0) { + cJSON_AddStringToObject(file_diff, "sha1_before", lf->sha1_before); + cJSON_AddStringToObject(file_diff, "sha1_after", lf->sha1_after); + } + if(lf->owner_before && lf->owner_after && strcmp(lf->owner_before, lf->owner_after) != 0) { + cJSON_AddStringToObject(file_diff, "owner_before", lf->owner_before); + cJSON_AddStringToObject(file_diff, "owner_after", lf->owner_after); + } + if(lf->gowner_before && lf->gowner_after && strcmp(lf->gowner_before, lf->gowner_after) != 0) { + cJSON_AddStringToObject(file_diff, "gowner_before", lf->gowner_before); + cJSON_AddStringToObject(file_diff, "gowner_after", lf->gowner_after); + } + if(lf->perm_before && lf->perm_after && (lf->perm_before != lf->perm_after)) { + cJSON_AddNumberToObject(file_diff, "perm_before", lf->perm_before); + cJSON_AddNumberToObject(file_diff, "perm_after", lf->perm_after); + } + } + if ( lf->hostname ) { + cJSON_AddStringToObject(root, "hostname", lf->hostname); + } + if ( lf->program_name ) { + cJSON_AddStringToObject(root, "program_name", lf->program_name); + } + if ( lf->status ) { + cJSON_AddStringToObject(root, "status", lf->status); + } + if(lf->command) + cJSON_AddStringToObject(root, "command", lf->command); + + if ( lf->url ) { + cJSON_AddStringToObject(root, "url", lf->url); + } + if ( lf->data ) { + cJSON_AddStringToObject(root, "data", lf->data); + } + if ( lf->systemname ) { + cJSON_AddStringToObject(root, "systemname", lf->systemname); + } + + // DecoderInfo + if(lf->decoder_info){ + cJSON *decoder; + // Dynamic fields + if (lf->decoder_info->fields) { + for (i = 0; i < Config.decoder_order_size; i++) { + if (lf->decoder_info->fields[i] && lf->fields[i]) { + cJSON_AddStringToObject(root, lf->decoder_info->fields[i], lf->fields[i]); + } + } + } + + cJSON_AddItemToObject(root, "decoder_desc", decoder = cJSON_CreateObject()); + + if (lf->decoder_info->fts) + cJSON_AddNumberToObject(decoder, "fts", lf->decoder_info->fts); + if (lf->decoder_info->accumulate) + cJSON_AddNumberToObject(decoder, "accumulate", lf->decoder_info->accumulate); + + if (lf->decoder_info->parent) + cJSON_AddStringToObject(decoder, "parent", lf->decoder_info->parent); + if (lf->decoder_info->name) + cJSON_AddStringToObject(decoder, "name", lf->decoder_info->name); + if (lf->decoder_info->ftscomment) + cJSON_AddStringToObject(decoder, "ftscomment", lf->decoder_info->ftscomment); + + } + + + W_ParseJSON(root, lf); + + out = cJSON_PrintUnformatted(root); + cJSON_Delete(root); + return out; +} + +/* Convert Archiveinfo to json */ +char *Archiveinfo_to_jsonstr(const Eventinfo *lf) +{ + cJSON *root; + char *out; + int i; + + root = cJSON_CreateObject(); + + if(lf->program_name) + cJSON_AddStringToObject(root, "program_name", lf->program_name); + + if(lf->log) + cJSON_AddStringToObject(root, "log", lf->log); + + if(lf->srcip) + cJSON_AddStringToObject(root, "srcip", lf->srcip); + + if(lf->dstip) + cJSON_AddStringToObject(root, "dstip", lf->dstip); + + if(lf->srcport) + cJSON_AddStringToObject(root, "srcport", lf->srcport); + + if(lf->dstport) + cJSON_AddStringToObject(root, "dstport", lf->dstport); + + if(lf->protocol) + cJSON_AddStringToObject(root, "protocol", lf->protocol); + + if(lf->action) + cJSON_AddStringToObject(root, "action", lf->action); + + if(lf->srcuser) + cJSON_AddStringToObject(root, "srcuser", lf->srcuser); + + if(lf->dstuser) + cJSON_AddStringToObject(root, "dstuser", lf->dstuser); + + if(lf->id) + cJSON_AddStringToObject(root, "id", lf->id); + + if(lf->status) + cJSON_AddStringToObject(root, "status", lf->status); + + if(lf->command) + cJSON_AddStringToObject(root, "command", lf->command); + + if(lf->url) + cJSON_AddStringToObject(root, "url", lf->url); + + if(lf->data) + cJSON_AddStringToObject(root, "data", lf->data); + + if(lf->systemname) + cJSON_AddStringToObject(root, "systemname", lf->systemname); + + + if (lf->filename) { + cJSON_AddStringToObject(root, "filename", lf->filename); + + if (lf->md5_before && lf->md5_after && (strcmp(lf->md5_before, lf->md5_after) != 0)) { + cJSON_AddStringToObject(root, "md5_before", lf->md5_before); + cJSON_AddStringToObject(root, "md5_after", lf->md5_after); + } + if (lf->sha1_before && lf->sha1_after && !(strcmp(lf->sha1_before, lf->sha1_after) != 0)) { + cJSON_AddStringToObject(root, "sha1_before", lf->sha1_before); + cJSON_AddStringToObject(root, "sha1_after", lf->sha1_after); + } + if (lf->owner_before && lf->owner_after && !(strcmp(lf->owner_before, lf->owner_after) != 0)) { + cJSON_AddStringToObject(root, "owner_before", lf->owner_before); + cJSON_AddStringToObject(root, "owner_after", lf->owner_after); + } + if (lf->gowner_before && lf->gowner_after && !(strcmp(lf->gowner_before, lf->gowner_after) != 0)) { + cJSON_AddStringToObject(root, "gowner_before", lf->gowner_before); + cJSON_AddStringToObject(root, "gowner_after", lf->gowner_after); + } + if (lf->perm_before && lf->perm_after && lf->perm_before != lf->perm_after) { + cJSON_AddNumberToObject(root, "perm_before", lf->perm_before); + cJSON_AddNumberToObject(root, "perm_after", lf->perm_after); + } + } + + + // RuleInfo + if(lf->generated_rule){ + cJSON *rule; + + cJSON_AddItemToObject(root, "rule", rule = cJSON_CreateObject()); + + if (lf->generated_rule->level) + cJSON_AddNumberToObject(rule, "level", lf->generated_rule->level); + + if (lf->generated_rule->comment) + cJSON_AddStringToObject(rule, "comment", lf->generated_rule->comment); + + if (lf->generated_rule->sigid) + cJSON_AddNumberToObject(rule, "sidid", lf->generated_rule->sigid); + + if (lf->generated_rule->cve) + cJSON_AddStringToObject(rule, "cve", lf->generated_rule->cve); + + if (lf->generated_rule->info) + cJSON_AddStringToObject(rule, "info", lf->generated_rule->info); + + if (lf->generated_rule->frequency) + cJSON_AddNumberToObject(rule, "frequency", lf->generated_rule->frequency); + + if (lf->generated_rule->firedtimes) + cJSON_AddNumberToObject(rule, "firedtimes", lf->generated_rule->firedtimes); + + if (lf->generated_rule->group) { + W_JSON_ParseGroups(root,lf,1); + } + + if (lf->full_log && W_isRootcheck(root,1)) { + W_JSON_ParseRootcheck(root,lf,1); + } + + } + + // DecoderInfo + if(lf->decoder_info){ + cJSON *decoder; + // Dynamic fields + if (lf->decoder_info->fields) { + for (i = 0; i < Config.decoder_order_size; i++) { + if (lf->decoder_info->fields[i] && lf->fields[i]) { + cJSON_AddStringToObject(root, lf->decoder_info->fields[i], lf->fields[i]); + } + } + } + + cJSON_AddItemToObject(root, "decoder", decoder = cJSON_CreateObject()); + + if (lf->decoder_info->fts) + cJSON_AddNumberToObject(decoder, "fts", lf->decoder_info->fts); + if (lf->decoder_info->accumulate) + cJSON_AddNumberToObject(decoder, "accumulate", lf->decoder_info->accumulate); + + if (lf->decoder_info->parent) + cJSON_AddStringToObject(decoder, "parent", lf->decoder_info->parent); + if (lf->decoder_info->name) + cJSON_AddStringToObject(decoder, "name", lf->decoder_info->name); + if (lf->decoder_info->ftscomment) + cJSON_AddStringToObject(decoder, "ftscomment", lf->decoder_info->ftscomment); + + } + + + if (lf->full_log) + cJSON_AddStringToObject(root, "full_log", lf->full_log); + + if(lf->year && strnlen(lf->mon, 4) && lf->day && strnlen(lf->hour, 10)) + W_JSON_ParseTimestamp(root, lf); + + if(lf->hostname){ + W_JSON_ParseHostname(root, lf->hostname); + W_JSON_ParseAgentIP(root, lf); + } + + if (lf->location) + W_JSON_ParseLocation(root,lf,0); + + + + + out = cJSON_PrintUnformatted(root); + cJSON_Delete(root); + return out; +} diff --git a/src/analysisd/format/to_json.h b/src/analysisd/format/to_json.h new file mode 100644 index 000000000..91c2393cf --- /dev/null +++ b/src/analysisd/format/to_json.h @@ -0,0 +1,16 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef __TO_JSON_H__ +#define __TO_JSON_H__ + +#include "eventinfo.h" +char *Eventinfo_to_jsonstr(const Eventinfo *lf); +char *Archiveinfo_to_jsonstr(const Eventinfo *lf); +#endif /* __TO_JSON_H__ */ diff --git a/src/analysisd/fts.c b/src/analysisd/fts.c new file mode 100644 index 000000000..67e338c7a --- /dev/null +++ b/src/analysisd/fts.c @@ -0,0 +1,297 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* First time seen functions */ + +#include "fts.h" +#include "eventinfo.h" + +/* Local variables */ +static unsigned int fts_minsize_for_str = 0; + +static OSList *fts_list = NULL; +static OSHash *fts_store = NULL; + +static FILE *fp_list = NULL; +static FILE *fp_ignore = NULL; + + +/* Start the FTS module */ +int FTS_Init() +{ + int fts_list_size; + char _line[OS_FLSIZE + 1]; + + _line[OS_FLSIZE] = '\0'; + + fts_list = OSList_Create(); + if (!fts_list) { + merror(LIST_ERROR, ARGV0); + return (0); + } + + /* Create store data */ + fts_store = OSHash_Create(); + if (!fts_store) { + merror(LIST_ERROR, ARGV0); + return (0); + } + if (!OSHash_setSize(fts_store, 2048)) { + merror(LIST_ERROR, ARGV0); + return (0); + } + + /* Get default list size */ + fts_list_size = getDefine_Int("analysisd", + "fts_list_size", + 12, 512); + + /* Get minimum string size */ + fts_minsize_for_str = (unsigned int) getDefine_Int("analysisd", + "fts_min_size_for_str", + 6, 128); + + if (!OSList_SetMaxSize(fts_list, fts_list_size)) { + merror(LIST_SIZE_ERROR, ARGV0); + return (0); + } + + /* Create fts list */ + fp_list = fopen(FTS_QUEUE, "r+"); + if (!fp_list) { + /* Create the file if we cant open it */ + fp_list = fopen(FTS_QUEUE, "w+"); + if (fp_list) { + fclose(fp_list); + } + + if (chmod(FTS_QUEUE, 0640) == -1) { + merror(CHMOD_ERROR, ARGV0, FTS_QUEUE, errno, strerror(errno)); + return 0; + } + + uid_t uid = Privsep_GetUser(USER); + gid_t gid = Privsep_GetGroup(GROUPGLOBAL); + if (uid != (uid_t) - 1 && gid != (gid_t) - 1) { + if (chown(FTS_QUEUE, uid, gid) == -1) { + merror(CHOWN_ERROR, ARGV0, FTS_QUEUE, errno, strerror(errno)); + return (0); + } + } + + fp_list = fopen(FTS_QUEUE, "r+"); + if (!fp_list) { + merror(FOPEN_ERROR, ARGV0, FTS_QUEUE, errno, strerror(errno)); + return (0); + } + } + + /* Add content from the files to memory */ + fseek(fp_list, 0, SEEK_SET); + while (fgets(_line, OS_FLSIZE , fp_list) != NULL) { + char *tmp_s; + + /* Remove newlines */ + tmp_s = strchr(_line, '\n'); + if (tmp_s) { + *tmp_s = '\0'; + } + + os_strdup(_line, tmp_s); + if (OSHash_Add(fts_store, tmp_s, tmp_s) <= 0) { + free(tmp_s); + merror(LIST_ADD_ERROR, ARGV0); + } + } + + /* Create ignore list */ + fp_ignore = fopen(IG_QUEUE, "r+"); + if (!fp_ignore) { + /* Create the file if we cannot open it */ + fp_ignore = fopen(IG_QUEUE, "w+"); + if (fp_ignore) { + fclose(fp_ignore); + } + + if (chmod(IG_QUEUE, 0640) == -1) { + merror(CHMOD_ERROR, ARGV0, IG_QUEUE, errno, strerror(errno)); + return (0); + } + + uid_t uid = Privsep_GetUser(USER); + gid_t gid = Privsep_GetGroup(GROUPGLOBAL); + if (uid != (uid_t) - 1 && gid != (gid_t) - 1) { + if (chown(IG_QUEUE, uid, gid) == -1) { + merror(CHOWN_ERROR, ARGV0, IG_QUEUE, errno, strerror(errno)); + return (0); + } + } + + fp_ignore = fopen(IG_QUEUE, "r+"); + if (!fp_ignore) { + merror(FOPEN_ERROR, ARGV0, IG_QUEUE, errno, strerror(errno)); + return (0); + } + } + + debug1("%s: DEBUG: FTSInit completed.", ARGV0); + + return (1); +} + +/* Add a pattern to be ignored */ +void AddtoIGnore(Eventinfo *lf) +{ + fseek(fp_ignore, 0, SEEK_END); + +#ifdef TESTRULE + return; +#endif + + /* Assign the values to the FTS */ + fprintf(fp_ignore, "%s %s %s %s %s %s %s %s\n", + (lf->decoder_info->name && (lf->generated_rule->ignore & FTS_NAME)) ? + lf->decoder_info->name : "", + (lf->id && (lf->generated_rule->ignore & FTS_ID)) ? lf->id : "", + (lf->dstuser && (lf->generated_rule->ignore & FTS_DSTUSER)) ? + lf->dstuser : "", + (lf->srcip && (lf->generated_rule->ignore & FTS_SRCIP)) ? + lf->srcip : "", + (lf->dstip && (lf->generated_rule->ignore & FTS_DSTIP)) ? + lf->dstip : "", + (lf->data && (lf->generated_rule->ignore & FTS_DATA)) ? + lf->data : "", + (lf->systemname && (lf->generated_rule->ignore & FTS_SYSTEMNAME)) ? + lf->systemname : "", + (lf->generated_rule->ignore & FTS_LOCATION) ? lf->location : ""); + + fflush(fp_ignore); + + return; +} + +/* Check if the event is to be ignored. + * Only after an event is matched (generated_rule must be set). + */ +int IGnore(Eventinfo *lf) +{ + char _line[OS_FLSIZE + 1]; + char _fline[OS_FLSIZE + 1]; + + _line[OS_FLSIZE] = '\0'; + + /* Assign the values to the FTS */ + snprintf(_line, OS_FLSIZE, "%s %s %s %s %s %s %s %s\n", + (lf->decoder_info->name && (lf->generated_rule->ckignore & FTS_NAME)) ? + lf->decoder_info->name : "", + (lf->id && (lf->generated_rule->ckignore & FTS_ID)) ? lf->id : "", + (lf->dstuser && (lf->generated_rule->ckignore & FTS_DSTUSER)) ? + lf->dstuser : "", + (lf->srcip && (lf->generated_rule->ckignore & FTS_SRCIP)) ? + lf->srcip : "", + (lf->dstip && (lf->generated_rule->ckignore & FTS_DSTIP)) ? + lf->dstip : "", + (lf->data && (lf->generated_rule->ignore & FTS_DATA)) ? + lf->data : "", + (lf->systemname && (lf->generated_rule->ignore & FTS_SYSTEMNAME)) ? + lf->systemname : "", + (lf->generated_rule->ckignore & FTS_LOCATION) ? lf->location : ""); + + _fline[OS_FLSIZE] = '\0'; + + /** Check if the ignore is present **/ + /* Point to the beginning of the file */ + fseek(fp_ignore, 0, SEEK_SET); + while (fgets(_fline, OS_FLSIZE , fp_ignore) != NULL) { + if (strcmp(_fline, _line) != 0) { + continue; + } + + /* If we match, we can return 1 */ + return (1); + } + + return (0); +} + +/* Check if the word "msg" is present on the "queue". + * If it is not, write it there. + */ +int FTS(Eventinfo *lf) +{ + int number_of_matches = 0; + char _line[OS_FLSIZE + 1]; + char *line_for_list = NULL; + OSListNode *fts_node; + + _line[OS_FLSIZE] = '\0'; + + /* Assign the values to the FTS */ + snprintf(_line, OS_FLSIZE, "%s %s %s %s %s %s %s %s %s", + lf->decoder_info->name, + (lf->id && (lf->decoder_info->fts & FTS_ID)) ? lf->id : "", + (lf->dstuser && (lf->decoder_info->fts & FTS_DSTUSER)) ? lf->dstuser : "", + (lf->srcuser && (lf->decoder_info->fts & FTS_SRCUSER)) ? lf->srcuser : "", + (lf->srcip && (lf->decoder_info->fts & FTS_SRCIP)) ? lf->srcip : "", + (lf->dstip && (lf->decoder_info->fts & FTS_DSTIP)) ? lf->dstip : "", + (lf->data && (lf->decoder_info->fts & FTS_DATA)) ? lf->data : "", + (lf->systemname && (lf->decoder_info->fts & FTS_SYSTEMNAME)) ? lf->systemname : "", + (lf->decoder_info->fts & FTS_LOCATION) ? lf->location : ""); + + /** Check if FTS is already present **/ + if (OSHash_Get(fts_store, _line)) { + return (0); + } + + /* Check if from the last FTS events, we had at least 3 "similars" before. + * If yes, we just ignore it. + */ + if (lf->decoder_info->type == IDS) { + fts_node = OSList_GetLastNode(fts_list); + while (fts_node) { + if (OS_StrHowClosedMatch((char *)fts_node->data, _line) > + fts_minsize_for_str) { + number_of_matches++; + + /* We go and add this new entry to the list */ + if (number_of_matches > 2) { + _line[fts_minsize_for_str] = '\0'; + break; + } + } + + fts_node = OSList_GetPrevNode(fts_list); + } + + os_strdup(_line, line_for_list); + OSList_AddData(fts_list, line_for_list); + } + + /* Store new entry */ + if (line_for_list == NULL) { + os_strdup(_line, line_for_list); + } + + if (OSHash_Add(fts_store, line_for_list, line_for_list) <= 1) { + return (0); + } + + +#ifdef TESTRULE + return (1); +#endif + + /* Save to fts fp */ + fseek(fp_list, 0, SEEK_END); + fprintf(fp_list, "%s\n", _line); + fflush(fp_list); + + return (1); +} + diff --git a/src/analysisd/fts.h b/src/analysisd/fts.h new file mode 100644 index 000000000..8de7ee912 --- /dev/null +++ b/src/analysisd/fts.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __FTS_H +#define __FTS_H + +#include "eventinfo.h" + +/* FTS queues */ +#ifdef TESTRULE +#define FTS_QUEUE "queue/fts/fts-queue" +#define IG_QUEUE "queue/fts/ig-queue" +#else +#define FTS_QUEUE "/queue/fts/fts-queue" +#define IG_QUEUE "/queue/fts/ig-queue" +#endif + +int FTS_Init(void); +void AddtoIGnore(Eventinfo *lf); +int IGnore(Eventinfo *lf); +int FTS(Eventinfo *lf); + +#endif /* __FTS_H */ + diff --git a/src/analysisd/lists.c b/src/analysisd/lists.c new file mode 100644 index 000000000..fb9e44857 --- /dev/null +++ b/src/analysisd/lists.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 3) as published by the FSF - Free Software + * Foundation. + */ + +#include "config.h" +#include "eventinfo.h" + + +/* Initialize the cdb lookup lists */ +void Lists_OP_CreateLists() +{ + OS_CreateListsList(); + return; +} + +int Lists_OP_LoadList(char *listfile) +{ + /* XXX Jeremy: I hate this. I think I'm missing something dumb here */ + char *holder; + char a_filename[OS_MAXSTR]; + char b_filename[OS_MAXSTR]; + ListNode *tmp_listnode_pt = NULL; + + a_filename[OS_MAXSTR - 2] = '\0'; + b_filename[OS_MAXSTR - 2] = '\0'; + + tmp_listnode_pt = (ListNode *)calloc(1, sizeof(ListNode)); + if (tmp_listnode_pt == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + snprintf(a_filename, OS_MAXSTR - 1, "%s", listfile); + if ((strchr(a_filename, '/') == NULL)) { + /* default to rules/ if a path is not given */ + snprintf(b_filename, OS_MAXSTR - 1, "rules/%s", a_filename); + snprintf(a_filename, OS_MAXSTR - 1, "%s", b_filename); + } + if ((holder = strstr(a_filename, ".cdb"))) { + snprintf(b_filename, (size_t)(holder - a_filename) + 1, "%s", a_filename); + snprintf(a_filename, OS_MAXSTR - 1, "%s", b_filename); + } + + snprintf(b_filename, OS_MAXSTR - 1, "%s.cdb", a_filename); + + os_strdup(a_filename, tmp_listnode_pt->txt_filename); + os_strdup(b_filename, tmp_listnode_pt->cdb_filename); + + tmp_listnode_pt->loaded = 0; + + OS_AddList(tmp_listnode_pt); + + return 0; +} + diff --git a/src/analysisd/lists.h b/src/analysisd/lists.h new file mode 100644 index 000000000..c89a086f1 --- /dev/null +++ b/src/analysisd/lists.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 3) as published by the FSF - Free Software + * Foundation + */ + +/* Rules are needed for lists */ + +#ifndef __LISTS_H +#define __LISTS_H + +#include "cdb/cdb.h" +#include "cdb/uint32.h" + +#define LR_STRING_MATCH 0 +#define LR_STRING_NOT_MATCH 1 +#define LR_STRING_MATCH_VALUE 2 + +#define LR_ADDRESS_MATCH 10 +#define LR_ADDRESS_NOT_MATCH 11 +#define LR_ADDRESS_MATCH_VALUE 12 + +typedef struct ListNode { + int loaded; + char *cdb_filename; + char *txt_filename; + struct cdb cdb; + struct ListNode *next; +} ListNode; + +typedef struct ListRule { + int loaded; + int field; + int lookup_type; + OSMatch *matcher; + char *filename; + ListNode *db; + struct ListRule *next; +} ListRule; + +/* Create the rule list */ +void OS_CreateListsList(void); + +/* Add rule information to the list */ +int OS_AddList( ListNode *new_listnode ); + +int Lists_OP_LoadList(char *listfile); + +int OS_DBSearchKey(ListRule *lrule, char *key); + +int OS_DBSearch(ListRule *lrule, char *key); + +void OS_ListLoadRules(void); + +ListRule *OS_AddListRule(ListRule *first_rule_list, int lookup_type, int field, char *listname, OSMatch *matcher); + +ListNode *OS_GetFirstList(void); + +ListNode *OS_FindList(const char *listname); + +void Lists_OP_CreateLists(void); + +#endif /* __LISTS_H */ + diff --git a/src/analysisd/lists_list.c b/src/analysisd/lists_list.c new file mode 100644 index 000000000..cf3e9f00c --- /dev/null +++ b/src/analysisd/lists_list.c @@ -0,0 +1,304 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 3) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rules.h" +#include "cdb/cdb.h" +#include +#include +#include +#include + +/* Local variables */ +static ListNode *global_listnode; +static ListRule *global_listrule; + + +/* Create the ListRule */ +void OS_CreateListsList() +{ + global_listnode = NULL; + global_listrule = NULL; + + return; +} + +/* Get first listnode */ +ListNode *OS_GetFirstList() +{ + ListNode *listnode_pt = global_listnode; + + return (listnode_pt); +} + +void OS_ListLoadRules() +{ + ListRule *lrule = global_listrule; + while (lrule != NULL) { + if (!lrule->loaded) { + lrule->db = OS_FindList(lrule->filename); + lrule->loaded = 1; + } + lrule = lrule->next; + } +} + +/* External AddList */ +int OS_AddList(ListNode *new_listnode) +{ + if (global_listnode == NULL) { + /* First list */ + global_listnode = new_listnode; + } else { + /* Add new list to the end */ + ListNode *last_list_node = global_listnode; + + while (last_list_node->next != NULL) { + last_list_node = last_list_node->next; + } + last_list_node->next = new_listnode; + + } + return 0; +} + +ListNode *OS_FindList(const char *listname) +{ + ListNode *last_list_node = OS_GetFirstList(); + if (last_list_node != NULL) { + do { + if (strcmp(last_list_node->txt_filename, listname) == 0 || + strcmp(last_list_node->cdb_filename, listname) == 0) { + /* Found first match returning */ + return (last_list_node); + } + last_list_node = last_list_node->next; + } while (last_list_node != NULL); + } + return (NULL); +} + +ListRule *OS_AddListRule(ListRule *first_rule_list, + int lookup_type, + int field, + char *listname, + OSMatch *matcher) +{ + ListRule *new_rulelist_pt = NULL; + new_rulelist_pt = (ListRule *)calloc(1, sizeof(ListRule)); + if (!new_rulelist_pt) { + return (NULL); + } + + new_rulelist_pt->field = field; + new_rulelist_pt->next = NULL; + new_rulelist_pt->matcher = matcher; + new_rulelist_pt->lookup_type = lookup_type; + new_rulelist_pt->filename = listname; + if ((new_rulelist_pt->db = OS_FindList(listname)) == NULL) { + new_rulelist_pt->loaded = 0; + } else { + new_rulelist_pt->loaded = 1; + } + if (first_rule_list == NULL) { + debug1("Adding First rulelist item: filename: %s field: %d lookup_type: %d", + new_rulelist_pt->filename, + new_rulelist_pt->field, + new_rulelist_pt->lookup_type); + first_rule_list = new_rulelist_pt; + } else { + while (first_rule_list->next) { + first_rule_list = first_rule_list->next; + } + debug1("Adding rulelist item: filename: %s field: %d lookup_type: %d", + new_rulelist_pt->filename, + new_rulelist_pt->field, + new_rulelist_pt->lookup_type); + first_rule_list->next = new_rulelist_pt; + } + return first_rule_list; +} + +static int _OS_CDBOpen(ListNode *lnode) +{ + int fd; + if (lnode->loaded != 1) { + if ((fd = open(lnode->cdb_filename, O_RDONLY)) == -1) { + merror(OPEN_ERROR, ARGV0, lnode->cdb_filename, errno, strerror (errno)); + return -1; + } + cdb_init(&lnode->cdb, fd); + lnode->loaded = 1; + } + return 0; +} + +static int OS_DBSearchKeyValue(ListRule *lrule, char *key) +{ + int result = -1; + char *val; + unsigned vlen, vpos; + if (lrule->db != NULL) { + if (_OS_CDBOpen(lrule->db) == -1) { + return 0; + } + if (cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) { + vpos = cdb_datapos(&lrule->db->cdb); + vlen = cdb_datalen(&lrule->db->cdb); + val = (char *) calloc(vlen + 1, sizeof(char)); + if(val == NULL) { + merror("%s: malloc failed: %s", ARGV0, strerror(errno)); + return(0); + } + cdb_read(&lrule->db->cdb, val, vlen, vpos); + result = OSMatch_Execute(val, vlen, lrule->matcher); + free(val); + return result; + } else { + return 0; + } + } + return 0; +} + +static int OS_DBSeachKey(ListRule *lrule, char *key) +{ + if (lrule->db != NULL) { + if (_OS_CDBOpen(lrule->db) == -1) { + return -1; + } + if ( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) { + return 1; + } + } + return 0; +} + +static int OS_DBSeachKeyAddress(ListRule *lrule, char *key) +{ + if (lrule->db != NULL) { + if (_OS_CDBOpen(lrule->db) == -1) { + return -1; + } + + if ( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) { + return 1; + } else { + char *tmpkey; + os_strdup(key, tmpkey); + while (strlen(tmpkey) > 0) { + if (tmpkey[strlen(tmpkey) - 1] == '.') { + if ( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) { + free(tmpkey); + return 1; + } + } + tmpkey[strlen(tmpkey) - 1] = '\0'; + } + free(tmpkey); + } + } + return 0; +} + +static int OS_DBSearchKeyAddressValue(ListRule *lrule, char *key) +{ + int result = -1; + char *val; + unsigned vlen, vpos; + if (lrule->db != NULL) { + if (_OS_CDBOpen(lrule->db) == -1) { + return 0; + } + + /* First lookup for a single IP address */ + if (cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) { + vpos = cdb_datapos(&lrule->db->cdb); + vlen = cdb_datalen(&lrule->db->cdb); + val = (char *) malloc(vlen); + if(val == NULL) { + merror("%s: malloc failed", ARGV0); + return(0); + } + cdb_read(&lrule->db->cdb, val, vlen, vpos); + result = OSMatch_Execute(val, vlen, lrule->matcher); + free(val); + return result; + } else { + /* IP address not found, look for matching subnets */ + char *tmpkey; + os_strdup(key, tmpkey); + while (strlen(tmpkey) > 0) { + if (tmpkey[strlen(tmpkey) - 1] == '.') { + if ( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) { + vpos = cdb_datapos(&lrule->db->cdb); + vlen = cdb_datalen(&lrule->db->cdb); + val = (char *) malloc(vlen); + cdb_read(&lrule->db->cdb, val, vlen, vpos); + result = OSMatch_Execute(val, vlen, lrule->matcher); + free(val); + free(tmpkey); + return result; + } + } + tmpkey[strlen(tmpkey) - 1] = '\0'; + } + free(tmpkey); + return 0; + } + } + return 0; +} + +int OS_DBSearch(ListRule *lrule, char *key) +{ + //XXX - god damn hack!!! Jeremy Rossi + if (lrule->loaded == 0) { + lrule->db = OS_FindList(lrule->filename); + lrule->loaded = 1; + } + switch (lrule->lookup_type) { + case LR_STRING_MATCH: + //debug1("LR_STRING_MATCH"); + if (OS_DBSeachKey(lrule, key) == 1) { + return 1; + } + return 0; + case LR_STRING_NOT_MATCH: + //debug1("LR_STRING_NOT_MATCH"); + if (OS_DBSeachKey(lrule, key) == 1) { + return 0; + } + return 1; + case LR_STRING_MATCH_VALUE: + //debug1("LR_STRING_MATCH_VALUE"); + if (OS_DBSearchKeyValue(lrule, key) == 1) { + return 1; + } + return 0; + case LR_ADDRESS_MATCH: + //debug1("LR_ADDRESS_MATCH"); + return OS_DBSeachKeyAddress(lrule, key); + case LR_ADDRESS_NOT_MATCH: + //debug1("LR_ADDRESS_NOT_MATCH"); + if (OS_DBSeachKeyAddress(lrule, key) == 0) { + return 1; + } + return 0; + case LR_ADDRESS_MATCH_VALUE: + //debug1("LR_ADDRESS_MATCH_VALUE"); + if (OS_DBSearchKeyAddressValue(lrule, key) == 0) { + return 1; + } + return 0; + default: + debug1("lists_list.c::OS_DBSearch should never hit default"); + return 0; + } +} diff --git a/src/analysisd/lists_make.c b/src/analysisd/lists_make.c new file mode 100644 index 000000000..d6c603df9 --- /dev/null +++ b/src/analysisd/lists_make.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 3) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rules.h" +#include "cdb/cdb.h" +#include "cdb/cdb_make.h" +#include +#include +#include +#include +#include "lists_make.h" + + +void Lists_OP_MakeAll(int force) +{ + ListNode *lnode = OS_GetFirstList(); + while (lnode) { + Lists_OP_MakeCDB(lnode->txt_filename, + lnode->cdb_filename, + force); + lnode = lnode->next; + } +} + +void Lists_OP_MakeCDB(const char *txt_filename, const char *cdb_filename, int force) +{ + struct cdb_make cdbm; + FILE *tmp_fd; + FILE *txt_fd; + char *tmp_str; + char *key, *val; + char str[OS_MAXSTR + 1]; + + str[OS_MAXSTR] = '\0'; + char tmp_filename[OS_MAXSTR]; + tmp_filename[OS_MAXSTR - 2] = '\0'; + snprintf(tmp_filename, OS_MAXSTR - 2, "%s.tmp", txt_filename); + + if (File_DateofChange(txt_filename) > File_DateofChange(cdb_filename) || + force) { + printf(" * File %s needs to be updated\n", cdb_filename); + tmp_fd = fopen(tmp_filename, "w+"); + cdb_make_start(&cdbm, tmp_fd); + if (!(txt_fd = fopen(txt_filename, "r"))) { + merror(FOPEN_ERROR, ARGV0, txt_filename, errno, strerror(errno)); + return; + } + while ((fgets(str, OS_MAXSTR - 1, txt_fd)) != NULL) { + /* Remove newlines and carriage returns */ + tmp_str = strchr(str, '\r'); + if (tmp_str) { + *tmp_str = '\0'; + } + tmp_str = strchr(str, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + if ((val = strchr(str, ':'))) { + *val = '\0'; + val++; + } else { + continue; + } + key = str; + cdb_make_add(&cdbm, key, strlen(key), val, strlen(val)); + if (force) { + print_out(" * adding - key: %s value: %s", key, val); + } + } + + fclose(txt_fd); + + cdb_make_finish(&cdbm); + if (rename(tmp_filename, cdb_filename) == -1) { + merror(RENAME_ERROR, ARGV0, tmp_filename, cdb_filename, errno, strerror(errno)); + return; + } + } else { + printf(" * File %s does not need to be compiled\n", cdb_filename); + } +} + diff --git a/src/analysisd/lists_make.h b/src/analysisd/lists_make.h new file mode 100644 index 000000000..7ea2c0214 --- /dev/null +++ b/src/analysisd/lists_make.h @@ -0,0 +1,17 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 3) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __LISTSMAKE_H +#define __LISTSMAKE_H + +void Lists_OP_MakeCDB(const char *txt_filename, const char *cdb_filename, int force); +void Lists_OP_MakeAll(int force); + +#endif /* __LISTSMAKE_H */ + diff --git a/src/analysisd/makelists.c b/src/analysisd/makelists.c new file mode 100644 index 000000000..ad8e5b0a1 --- /dev/null +++ b/src/analysisd/makelists.c @@ -0,0 +1,183 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef ARGV0 +#undef ARGV0 +#define ARGV0 "openarmor-testrule" +#endif + +#include "shared.h" +#include "active-response.h" +#include "config.h" +#include "rules.h" +#include "stats.h" +#include "lists_make.h" +#include "eventinfo.h" +#include "analysisd.h" + +/** Global definitions **/ +int today; +int thishour; +int prev_year; +char prev_month[4]; +int __crt_hour; +int __crt_wday; +time_t c_time; +char __shost[512]; +OSDecoderInfo *NULL_Decoder; + +#ifdef LIBGEOIP_ENABLED +GeoIP *geoipdb; +#endif + +/* print help statement */ +__attribute__((noreturn)) +static void help_makelists(void) +{ + print_header(); + print_out(" %s: -[VhdtF] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -F Force rebuild of all databases"); + print_out(" -u User to run as (default: %s)", USER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int test_config = 0; + int c = 0; + const char *dir = DEFAULTDIR; + const char *user = USER; + const char *group = GROUPGLOBAL; + uid_t uid; + gid_t gid; + int force = 0; + + const char *cfg = DEFAULTCPATH; + + /* Set the name */ + OS_SetName(ARGV0); + + thishour = 0; + today = 0; + prev_year = 0; + memset(prev_month, '\0', 4); + + while ((c = getopt(argc, argv, "VdhFtu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_makelists(); + break; + case 'd': + nowDebug(); + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 'F': + force = 1; + break; + case 't': + test_config = 1; + break; + default: + help_makelists(); + break; + } + } + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Found user */ + debug1(FOUND_USER, ARGV0); + + /* Read configuration file */ + if (GlobalConf(cfg) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + debug1(READ_CONFIG, ARGV0); + + /* Set the group */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + nowChroot(); + + if (test_config == 1) { + exit(0); + } + + /* Create the lists for use in rules */ + Lists_OP_CreateLists(); + + /* Read the lists */ + { + char **listfiles; + listfiles = Config.lists; + while (listfiles && *listfiles) { + if (Lists_OP_LoadList(*listfiles) < 0) { + ErrorExit(LISTS_ERROR, ARGV0, *listfiles); + } + free(*listfiles); + listfiles++; + } + free(Config.lists); + Config.lists = NULL; + } + + Lists_OP_MakeAll(force); + + exit(0); +} + diff --git a/src/analysisd/output/jsonout.c b/src/analysisd/output/jsonout.c new file mode 100644 index 000000000..237be3d02 --- /dev/null +++ b/src/analysisd/output/jsonout.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "jsonout.h" +#include "alerts/getloglocation.h" +#include "format/to_json.h" + +void jsonout_output_event(const Eventinfo *lf) +{ + char *json_alert = Eventinfo_to_jsonstr(lf); + + fprintf(_jflog, + "%s\n", + json_alert); + + fflush(_jflog); + free(json_alert); + return; +} +void jsonout_output_archive(const Eventinfo *lf) +{ + char *json_alert = Archiveinfo_to_jsonstr(lf); + + fprintf(_ejflog, + "%s\n", + json_alert); + + fflush(_ejflog); + free(json_alert); + return; +} diff --git a/src/analysisd/output/jsonout.h b/src/analysisd/output/jsonout.h new file mode 100644 index 000000000..8a1a02b24 --- /dev/null +++ b/src/analysisd/output/jsonout.h @@ -0,0 +1,18 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _JSONOUT_H_ +#define _JSONOUT_H_ + +#include "eventinfo.h" + +void jsonout_output_event(const Eventinfo *lf); +void jsonout_output_archive(const Eventinfo *lf); + +#endif /* _JSONOUT_H_ */ diff --git a/src/analysisd/output/prelude.c b/src/analysisd/output/prelude.c new file mode 100644 index 000000000..8eaa803de --- /dev/null +++ b/src/analysisd/output/prelude.c @@ -0,0 +1,524 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* + * openarmor to Prelude + */ + +#ifdef PRELUDE_OUTPUT_ENABLED + +#include +#include +#include + +#include "prelude.h" + +#include "shared.h" +#include "rules.h" + +#define DEFAULT_ANALYZER_NAME "openarmor" +#define ANALYZER_CLASS "Host IDS, File Integrity Checker, Log Analyzer" +#define ANALYZER_MODEL "openarmor" +#define ANALYZER_MANUFACTURER __site +#define ANALYZER_VERSION __openarmor_version + +/** openarmor to prelude severity mapping. **/ +static const char *(openarmor2prelude_sev[]) = {"info", "info", "info", "info", + "low", "low", "low", "low", + "medium", "medium", "medium", "medium", + "high", "high", "high", "high", "high" + }; + +/* Prelude client */ +static prelude_client_t *prelude_client; + + +/*void prelude_idmef_debug(idmef_message_t *idmef) +{ + prelude_io_t *pio; + + prelude_io_new(&pio); + prelude_io_set_file_io(pio, stderr); + idmef_message_print(idmef, pio); + prelude_io_destroy(pio); +}*/ + +static int +add_idmef_object(idmef_message_t *msg, const char *object, const char *value) +{ + int ret = 0; + idmef_value_t *val; + idmef_path_t *path; + + if (value == NULL) { + return (0); + } + + ret = idmef_path_new_fast(&path, object); + if (ret < 0) { + return (-1); + } + + ret = idmef_value_new_from_path(&val, path, value); + if (ret < 0) { + idmef_path_destroy(path); + return (-1); + } + + ret = idmef_path_set(path, msg, val); + if (ret < 0) { + merror("%s: openarmor2Prelude: IDMEF: Cannot add object '%s': %s.", + ARGV0, object, prelude_strerror(ret)); + } + + idmef_value_destroy(val); + idmef_path_destroy(path); + + return (ret); +} + +static int +setup_analyzer(idmef_analyzer_t *analyzer) +{ + int ret; + prelude_string_t *string; + + ret = idmef_analyzer_new_model(analyzer, &string); + if ( ret < 0 ) { + goto err; + } + prelude_string_set_constant(string, ANALYZER_MODEL); + + ret = idmef_analyzer_new_class(analyzer, &string); + if ( ret < 0 ) { + goto err; + } + prelude_string_set_constant(string, ANALYZER_CLASS); + + ret = idmef_analyzer_new_manufacturer(analyzer, &string); + if ( ret < 0 ) { + goto err; + } + prelude_string_set_constant(string, ANALYZER_MANUFACTURER); + + ret = idmef_analyzer_new_version(analyzer, &string); + if ( ret < 0 ) { + goto err; + } + prelude_string_set_constant(string, ANALYZER_VERSION); + + return 0; + +err: + merror("%s: openarmor2Prelude: %s: IDMEF error: %s.", + ARGV0, prelude_strsource(ret), prelude_strerror(ret)); + + return -1; +} + +void prelude_start(const char *profile, int argc, char **argv) +{ + int ret; + prelude_client = NULL; + + ret = prelude_init(&argc, argv); + if (ret < 0) { + merror("%s: %s: Unable to initialize the Prelude library: %s.", + ARGV0, prelude_strsource(ret), prelude_strerror(ret)); + return; + } + + ret = prelude_client_new(&prelude_client, + profile != NULL ? profile : DEFAULT_ANALYZER_NAME); + if (!prelude_client) { + merror("%s: %s: Unable to create a prelude client object: %s.", + ARGV0, prelude_strsource(ret), prelude_strerror(ret)); + + return; + } + + ret = setup_analyzer(prelude_client_get_analyzer(prelude_client)); + if (ret < 0) { + merror("%s: %s: Unable to setup analyzer: %s", + ARGV0, prelude_strsource(ret), prelude_strerror(ret)); + + prelude_client_destroy(prelude_client, + PRELUDE_CLIENT_EXIT_STATUS_FAILURE); + + return; + } + + ret = prelude_client_set_flags(prelude_client, + prelude_client_get_flags(prelude_client) + | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER); + if (ret < 0) { + merror("%s: %s: Unable to set prelude client flags: %s.", + ARGV0, prelude_strsource(ret), prelude_strerror(ret)); + } + + /* Set uid and gid of openarmor */ + prelude_client_profile_set_uid(prelude_client_get_profile(prelude_client), + Privsep_GetUser(USER)); + prelude_client_profile_set_gid(prelude_client_get_profile(prelude_client), + Privsep_GetGroup(GROUPGLOBAL)); + + ret = prelude_client_start(prelude_client); + if (ret < 0) { + merror("%s: %s: Unable to initialize prelude client: %s.", + ARGV0, prelude_strsource(ret), prelude_strerror(ret)); + + prelude_client_destroy(prelude_client, + PRELUDE_CLIENT_EXIT_STATUS_FAILURE); + + return; + } + + return; +} + +static void FileAccess_PreludeLog(idmef_message_t *idmef, + const char *category, + const char *filename, + const char *md5, + const char *sha1, + const char *owner, + const char *gowner, + int perm) +{ + + debug1("%s: DEBUG: filename = %s.", ARGV0, filename); + debug1("%s: DEBUG: category = %s.", ARGV0, category); + add_idmef_object(idmef, "alert.target(0).file(>>).name", filename); + add_idmef_object(idmef, "alert.target(0).file(-1).category", category); + + /* Add the hashes */ + if (md5) { + add_idmef_object(idmef, "alert.target(0).file(-1).checksum(>>).algorithm", "MD5"); + add_idmef_object(idmef, "alert.target(0).file(-1).checksum(-1).value", md5); + } + if (sha1) { + add_idmef_object(idmef, "alert.target(0).file(-1).checksum(>>).algorithm", "SHA1"); + add_idmef_object(idmef, "alert.target(0).file(-1).checksum(-1).value", sha1); + } + + /* Add the owner */ + if (owner) { + debug1("%s: DEBUG: owner = %s.", ARGV0, owner); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(>>).user_id.number", owner); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).user_id.type", "user-privs"); + + if (perm) { + /* Add the permissions */ + if (perm & S_IWUSR) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "write"); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "delete"); + } + if (perm & S_IXUSR) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "execute"); + } + if (perm & S_IRUSR ) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "read"); + } + if (perm & S_ISUID) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "executeAs"); + } + } + } + + /* Add the group owner */ + if (gowner) { + debug1("%s: DEBUG: gowner = %s.", ARGV0, gowner); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(>>).user_id.number", gowner); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).user_id.type", "group-privs"); + + if (perm) { + /* Add the permissions */ + if (perm & S_IWGRP) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "write"); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "delete"); + } + if (perm & S_IXGRP) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "execute"); + } + if (perm & S_IRGRP ) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "read"); + } + if (perm & S_ISGID) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "executeAs"); + } + } + } + + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(>>).user_id.type", "other-privs"); + + if (perm) { + /* Add the permissions */ + if (perm & S_IWOTH) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "write"); + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "delete"); + } + if (perm & S_IXOTH) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "execute"); + } + if (perm & S_IROTH ) { + add_idmef_object(idmef, "alert.target(0).file(-1).file_access(-1).permission(>>)", "read"); + } + } + return; +} + +void OS_PreludeLog(const Eventinfo *lf) +{ + int ret; + char _prelude_data[256]; + char *origin; + idmef_message_t *idmef; + RuleInfoDetail *last_info_detail; + + /* Generate prelude alert */ + ret = idmef_message_new(&idmef); + if ( ret < 0 ) { + merror("%s: openarmor2Prelude: Cannot create IDMEF message", ARGV0); + return; + } + + add_idmef_object(idmef, "alert.assessment.impact.description", + lf->generated_rule->comment); + + add_idmef_object(idmef, "alert.assessment.impact.severity", + (lf->generated_rule->level > 15) ? "high" : + openarmor2prelude_sev[lf->generated_rule->level]); + + add_idmef_object(idmef, "alert.assessment.impact.completion", "succeeded"); + + if (lf->action) { + switch (*lf->action) { + /* discard, drop, deny, */ + case 'd': + case 'D': + /* reject, */ + case 'r': + case 'R': + /* block */ + case 'b': + case 'B': + snprintf(_prelude_data, 256, "DROP: %s", lf->action); + break; + /* Closed */ + case 'c': + case 'C': + /* Teardown */ + case 't': + case 'T': + snprintf(_prelude_data, 256, "CLOSED: %s", lf->action); + break; + /* allow, accept, */ + case 'a': + case 'A': + /* pass/permitted */ + case 'p': + case 'P': + /* open */ + case 'o': + case 'O': + snprintf(_prelude_data, 256, "ALLOW: %s", lf->action); + break; + default: + snprintf(_prelude_data, 256, "%s", lf->action); + break; + } + add_idmef_object(idmef, "alert.assessment.action(0).category", "3"); + add_idmef_object(idmef, "alert.assessment.action(0).description", _prelude_data); + } + + /* Begin Classification Infomations */ + { + add_idmef_object(idmef, "alert.classification.text", + lf->generated_rule->comment); + + /* The Common Vulnerabilities and Exposures (CVE) (http://www.cve.mitre.org/) + * infomation if present in the triggering rule + */ + if (lf->generated_rule->cve) { + add_idmef_object(idmef, "alert.classification.reference(>>).origin", "cve"); + add_idmef_object(idmef, "alert.classification.reference(-1).name", lf->generated_rule->cve); + + snprintf(_prelude_data, 256, "CVE:%s", lf->generated_rule->cve); + add_idmef_object(idmef, "alert.classification.reference(-1).meaning", _prelude_data); + } + + /* Rule sid is used to create a link to the rule on the openarmor wiki */ + if (lf->generated_rule->sigid) { + add_idmef_object(idmef, "alert.classification.reference(>>).origin", "vendor-specific"); + + snprintf(_prelude_data, 256, "Rule:%d", lf->generated_rule->sigid); + add_idmef_object(idmef, "alert.classification.reference(-1).name", _prelude_data); + add_idmef_object(idmef, "alert.classification.reference(-1).meaning", "openarmor Rule Wiki Documentation"); + + snprintf(_prelude_data, 256, "http://www.theopenarmor.org/wiki/Rule:%d", + lf->generated_rule->sigid); + add_idmef_object(idmef, "alert.classification.reference(-1).url", _prelude_data); + } + + /* Extended Info Details */ + for (last_info_detail = lf->generated_rule->info_details; + last_info_detail != NULL; + last_info_detail = last_info_detail->next) { + if (last_info_detail->type == RULEINFODETAIL_LINK) { + add_idmef_object(idmef, "alert.classification.reference(>>).origin", "vendor-specific"); + + snprintf(_prelude_data, 256, "Rule:%d link", lf->generated_rule->sigid); + add_idmef_object(idmef, "alert.classification.reference(-1).name", _prelude_data); + add_idmef_object(idmef, "alert.classification.reference(-1).url", last_info_detail->data); + + } else if (last_info_detail->type == RULEINFODETAIL_TEXT) { + add_idmef_object(idmef, "alert.classification.reference(>>).origin", "vendor-specific"); + + snprintf(_prelude_data, 256, "Rule:%d info", lf->generated_rule->sigid); + add_idmef_object(idmef, "alert.classification.reference(-1).name", _prelude_data); + + add_idmef_object(idmef, "alert.classification.reference(-1).meaning", last_info_detail->data); + + } else { + switch (last_info_detail->type) { + case RULEINFODETAIL_CVE: + origin = "cve"; + break; + case RULEINFODETAIL_OSVDB: + origin = "osvdb"; + break; + case RULEINFODETAIL_BUGTRACK: + origin = "bugtraqid"; + break; + default: + origin = "vendor-specific"; + break; + } + add_idmef_object(idmef, "alert.classification.reference(>>).origin", origin); + add_idmef_object(idmef, "alert.classification.reference(-1).name", last_info_detail->data); + } + } + + /* Break up the list of groups on the "," boundary + * For each section create a prelude reference classification + * that points back to the the openarmor wiki for more infomation. + */ + if (lf->generated_rule->group) { + char *copy_group; + char new_generated_rule_group[256]; + new_generated_rule_group[255] = '\0'; + strncpy(new_generated_rule_group, lf->generated_rule->group, 255); + copy_group = strtok(new_generated_rule_group, ","); + while (copy_group) { + add_idmef_object(idmef, "alert.classification.reference(>>).origin", "vendor-specific"); + + snprintf(_prelude_data, 256, "Group:%s", copy_group); + add_idmef_object(idmef, "alert.classification.reference(-1).name", _prelude_data); + + add_idmef_object(idmef, "alert.classification.reference(-1).meaning", "openarmor Group Wiki Documentation"); + + snprintf(_prelude_data, 256, "http://www.theopenarmor.org/wiki/Group:%s", + copy_group); + add_idmef_object(idmef, "alert.classification.reference(-1).url", _prelude_data); + + copy_group = strtok(NULL, ","); + } + } + } /* end classification block */ + + /* Begin Node infomation block */ + { + /* Set source info */ + add_idmef_object(idmef, "alert.source(0).spoofed", "no"); + add_idmef_object(idmef, "alert.source(0).node.address(0).address", + lf->srcip); + add_idmef_object(idmef, "alert.source(0).service.port", lf->srcport); + + if (lf->srcuser) { + add_idmef_object(idmef, "alert.source(0).user.user_id(0).name", lf->srcuser); + } + + /* Set target */ + add_idmef_object(idmef, "alert.target(0).service.name", lf->program_name); + add_idmef_object(idmef, "alert.target(0).spoofed", "no"); + + if (lf->dstip) { + add_idmef_object(idmef, "alert.target(0).node.address(0).address", + lf->dstip); + } else { + char *tmp_str; + char new_prelude_target[256]; + + new_prelude_target[255] = '\0'; + strncpy(new_prelude_target, lf->hostname, 255); + + /* The messages can have the file, so we need to remove it + * Formats can be: + * enigma->/var/log/authlog + * (esqueleto2) 192.168.2.99->/var/log/squid/access.log + */ + tmp_str = strstr(new_prelude_target, "->"); + if (tmp_str) { + *tmp_str = '\0'; + } + add_idmef_object(idmef, "alert.target(0).node.address(0).address", + new_prelude_target); + } + add_idmef_object(idmef, "alert.target(0).service.name", lf->hostname); + add_idmef_object(idmef, "alert.target(0).service.port", lf->dstport); + + if (lf->dstuser) { + add_idmef_object(idmef, "alert.target(0).user.category", "2"); + add_idmef_object(idmef, "alert.target(0).user.user_id(0).name", lf->dstuser); + } + } /* end Node infomation block */ + + /* Set source file */ + add_idmef_object(idmef, "alert.additional_data(0).type", "string"); + add_idmef_object(idmef, "alert.additional_data(0).meaning", "Source file"); + add_idmef_object(idmef, "alert.additional_data(0).data", lf->location); + + /* Set full log */ + add_idmef_object(idmef, "alert.additional_data(1).type", "string"); + add_idmef_object(idmef, "alert.additional_data(1).meaning", "Full Log"); + add_idmef_object(idmef, "alert.additional_data(1).data", lf->full_log); + + idmef_alert_set_analyzer(idmef_message_get_alert(idmef), + idmef_analyzer_ref + (prelude_client_get_analyzer(prelude_client)), + IDMEF_LIST_PREPEND); + debug1("%s: DEBUG: lf->filename = %s.", ARGV0, lf->filename); + if (lf->filename) { + FileAccess_PreludeLog(idmef, + "original", + lf->filename, + lf->md5_before, + lf->sha1_before, + lf->owner_before, + lf->gowner_before, + lf->perm_before); + FileAccess_PreludeLog(idmef, + "current", + lf->filename, + lf->md5_after, + lf->sha1_after, + lf->owner_after, + lf->gowner_after, + lf->perm_after); + debug1("%s: DEBUG: done with alert.target(0).file(1)", ARGV0); + } + + debug1("%s: DEBUG: Sending IDMEF alert", ARGV0); + prelude_client_send_idmef(prelude_client, idmef); + debug1("%s: DEBUG: destroying IDMEF alert", ARGV0); + idmef_message_destroy(idmef); +} + +#endif /* PRELUDE_OUTPUT_ENABLED */ + diff --git a/src/analysisd/output/prelude.h b/src/analysisd/output/prelude.h new file mode 100644 index 000000000..9f3c14f14 --- /dev/null +++ b/src/analysisd/output/prelude.h @@ -0,0 +1,25 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef PRELUDE_OUTPUT_ENABLED + +#ifndef _PRELUDE_H_ +#define _PRELUDE_H_ + +#include "eventinfo.h" + +/* Start Prelude client */ +void prelude_start(const char *profile, int argc, char **argv); + +/* Log to Prelude */ +void OS_PreludeLog(const Eventinfo *lf); + +#endif /* _PRELUDE_H_ */ + +#endif /* PRELUDE_OUTPUT_ENABLED */ diff --git a/src/analysisd/output/zeromq.c b/src/analysisd/output/zeromq.c new file mode 100644 index 000000000..054c2054e --- /dev/null +++ b/src/analysisd/output/zeromq.c @@ -0,0 +1,135 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef ZEROMQ_OUTPUT_ENABLED + +#include "zeromq.h" + +#include "shared.h" +#include "rules.h" +#include "format/to_json.h" + + +/* Global variables */ +#if CZMQ_VERSION_MAJOR == 2 +static zctx_t *zeromq_context; +static void *zeromq_pubsocket; +#elif CZMQ_VERSION_MAJOR >= 3 +zsock_t *zeromq_pubsocket; +zactor_t *auth; +#endif + +#if CZMQ_VERSION_MAJOR == 2 +void zeromq_output_start(const char *uri) +{ + int rc; + + debug1("%s: DEBUG: New ZeroMQ Context", ARGV0); + zeromq_context = zctx_new(); + if (zeromq_context == NULL) { + merror("%s: Unable to initialize ZeroMQ library", ARGV0); + return; + } + + debug1("%s: DEBUG: New ZeroMQ Socket: ZMQ_PUB", ARGV0); + zeromq_pubsocket = zsocket_new(zeromq_context, ZMQ_PUB); + if (zeromq_pubsocket == NULL) { + merror("%s: Unable to initialize ZeroMQ Socket", ARGV0); + return; + } + + debug1("%s: DEBUG: Listening on ZeroMQ Socket: %s", ARGV0, uri); + rc = zsocket_bind(zeromq_pubsocket, "%s", uri); + if (rc) { + merror("%s: Unable to bind the ZeroMQ Socket: %s.", ARGV0, uri); + return; + } +} +#elif CZMQ_VERSION_MAJOR >= 3 +void zeromq_output_start(const char *uri, const char *client_cert_path, const char *server_cert_path) +{ + int rc; + + debug1("%s: DEBUG: New ZeroMQ Socket: ZMQ_PUB", ARGV0); + zeromq_pubsocket = zsock_new(ZMQ_PUB); + if (zeromq_pubsocket == NULL) { + merror("%s: Unable to initialize ZeroMQ Socket", ARGV0); + return; + } + + if (zsys_has_curve()) { + if (client_cert_path && server_cert_path) { + debug1("%s: DEBUG: Initiating CURVE for ZeroMQ Socket", ARGV0); + auth = zactor_new(zauth, NULL); + if (!auth) { + merror("%s: Unable to start auth for ZeroMQ Sock", ARGV0); + } + zstr_sendx(auth, "CURVE", client_cert_path, NULL); + zsock_wait(auth); + + zcert_t *server_cert = zcert_load(server_cert_path); + if (!server_cert) { + merror("%s: Unable to load server certificate: %s.", ARGV0, server_cert_path); + } + + zcert_apply(server_cert, zeromq_pubsocket); + zsock_set_curve_server(zeromq_pubsocket, 1); + + zcert_destroy(&server_cert); + } + } + + debug1("%s: DEBUG: Listening on ZeroMQ Socket: %s", ARGV0, uri); + rc = zsock_bind(zeromq_pubsocket, "%s", uri); + if (rc) { + merror("%s: Unable to bind the ZeroMQ Socket: %s.", ARGV0, uri); + return; + } +} +#endif + +#if CZMQ_VERSION_MAJOR == 2 +void zeromq_output_end() +{ + zsocket_destroy(zeromq_context, zeromq_pubsocket); + zctx_destroy(&zeromq_context); +} +#elif CZMQ_VERSION_MAJOR >= 3 +void zeromq_output_end() +{ + zsock_destroy(&zeromq_pubsocket); + zactor_destroy(&auth); +} +#endif + +#if CZMQ_VERSION_MAJOR == 2 +void zeromq_output_event(const Eventinfo *lf) +{ + char *json_alert = Eventinfo_to_jsonstr(lf); + + zmsg_t *msg = zmsg_new(); + zmsg_addstr(msg, "openarmor.alerts"); + zmsg_addstr(msg, json_alert); + zmsg_send(&msg, zeromq_pubsocket); + free(json_alert); +} +#elif ZMQ_VERSION_MAJOR >= 3 +void zeromq_output_event(const Eventinfo *lf) +{ + char *json_alert = Eventinfo_to_jsonstr(lf); + + zmsg_t *msg = zmsg_new(); + zmsg_addstr(msg, "openarmor.alerts"); + zmsg_addstr(msg, json_alert); + zmsg_send(&msg, zeromq_pubsocket); + free(json_alert); +} +#endif + +#endif diff --git a/src/analysisd/output/zeromq.h b/src/analysisd/output/zeromq.h new file mode 100644 index 000000000..2f3569650 --- /dev/null +++ b/src/analysisd/output/zeromq.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2015 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef ZEROMQ_OUTPUT_ENABLED + +#ifndef _ZEROMQ_H_ +#define _ZEROMQ_H_ + +#include "eventinfo.h" +#include + +void zeromq_output_event(const Eventinfo *lf); +#if CZMQ_VERSION_MAJOR == 2 +void zeromq_output_start(const char *uri); +#elif CZMQ_VERSION_MAJOR >= 3 +void zeromq_output_start(const char *uri, const char *client_cert_path, const char *server_cert_path); +#endif +void zeromq_output_end(void); + + +#endif /* _ZEROMQ_H_ */ + +#endif /* ZEROMQ_OUTPUT_ENABLED */ diff --git a/src/analysisd/rules.c b/src/analysisd/rules.c new file mode 100644 index 000000000..45ee169c2 --- /dev/null +++ b/src/analysisd/rules.c @@ -0,0 +1,2100 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "rules.h" +#include "config.h" +#include "eventinfo.h" +#include "compiled_rules/compiled_rules.h" + +/* Global definition */ +RuleInfo *currently_rule; + +/* Change path for test rule */ +#ifdef TESTRULE +#undef RULEPATH +#define RULEPATH "rules/" +#endif + +/* Prototypes */ +static int getattributes(char **attributes, + char **values, + int *id, int *level, + int *maxsize, int *timeframe, + int *frequency, int *accuracy, + int *noalert, int *ignore_time, int *overwrite); +static int doesRuleExist(int sid, RuleNode *r_node); +static void Rule_AddAR(RuleInfo *config_rule); +static char *loadmemory(char *at, const char *str); +static void printRuleinfo(const RuleInfo *rule, int node); + +/* Will initialize the rules list */ +void Rules_OP_CreateRules() +{ + /* Initialize the rule list */ + OS_CreateRuleList(); + + return; +} + +/* Read the log rules */ +int Rules_OP_ReadRules(const char *rulefile) +{ + OS_XML xml; + XML_NODE node = NULL; + + /* XML variables */ + /* These are the available options for the rule configuration */ + + const char *xml_group = "group"; + const char *xml_rule = "rule"; + + const char *xml_regex = "regex"; + const char *xml_pcre2 = "pcre2"; + const char *xml_match = "match"; + const char *xml_match_pcre2 = "match_pcre2"; + const char *xml_decoded = "decoded_as"; + const char *xml_category = "category"; + const char *xml_cve = "cve"; + const char *xml_info = "info"; + const char *xml_day_time = "time"; + const char *xml_week_day = "weekday"; + const char *xml_comment = "description"; + const char *xml_ignore = "ignore"; + const char *xml_check_if_ignored = "check_if_ignored"; + + const char *xml_srcip = "srcip"; + const char *xml_srcgeoip = "srcgeoip"; + const char *xml_srcport = "srcport"; + const char *xml_srcgeoip_pcre2 = "srcgeoip_pcre2"; + const char *xml_srcport_pcre2 = "srcport_pcre2"; + const char *xml_dstip = "dstip"; + const char *xml_dstgeoip = "dstgeoip"; + const char *xml_dstport = "dstport"; + const char *xml_user = "user"; + const char *xml_url = "url"; + const char *xml_id = "id"; + const char *xml_data = "extra_data"; + const char *xml_hostname = "hostname"; + const char *xml_program_name = "program_name"; + const char *xml_status = "status"; + const char *xml_dstgeoip_pcre2 = "dstgeoip_pcre2"; + const char *xml_dstport_pcre2 = "dstport_pcre2"; + const char *xml_user_pcre2 = "user_pcre2"; + const char *xml_url_pcre2 = "url_pcre2"; + const char *xml_id_pcre2 = "id_pcre2"; + const char *xml_data_pcre2 = "extra_data_pcre2"; + const char *xml_hostname_pcre2 = "hostname_pcre2"; + const char *xml_program_name_pcre2 = "program_name_pcre2"; + const char *xml_status_pcre2 = "status_pcre2"; + const char *xml_action = "action"; + const char *xml_compiled = "compiled_rule"; + const char *xml_field = "field"; + const char *xml_name = "name"; + + + const char *xml_list = "list"; + const char *xml_list_lookup = "lookup"; + const char *xml_list_field = "field"; + const char *xml_list_cvalue = "check_value"; + const char *xml_match_key = "match_key"; + const char *xml_not_match_key = "not_match_key"; + const char *xml_match_key_value = "match_key_value"; + const char *xml_address_key = "address_match_key"; + const char *xml_not_address_key = "not_address_match_key"; + const char *xml_address_key_value = "address_match_key_value"; + + const char *xml_if_sid = "if_sid"; + const char *xml_if_group = "if_group"; + const char *xml_if_level = "if_level"; + const char *xml_fts = "if_fts"; + + const char *xml_if_matched_regex = "if_matched_regex"; + const char *xml_if_matched_group = "if_matched_group"; + const char *xml_if_matched_sid = "if_matched_sid"; + + const char *xml_same_source_ip = "same_source_ip"; + const char *xml_same_src_port = "same_src_port"; + const char *xml_same_dst_port = "same_dst_port"; + const char *xml_same_user = "same_user"; + const char *xml_same_location = "same_location"; + const char *xml_same_id = "same_id"; + const char *xml_dodiff = "check_diff"; + + const char *xml_different_url = "different_url"; + const char *xml_different_srcip = "different_srcip"; + const char *xml_different_srcgeoip = "different_srcgeoip"; + + const char *xml_notsame_source_ip = "not_same_source_ip"; + const char *xml_notsame_user = "not_same_user"; + const char *xml_notsame_agent = "not_same_agent"; + const char *xml_notsame_id = "not_same_id"; + + const char *xml_options = "options"; + + char *rulepath; + + size_t i; + int default_timeframe = 360; + + /* If no directory in the rulefile, add the default */ + if ((strchr(rulefile, '/')) == NULL) { + /* Build the rule file name + path */ + i = strlen(RULEPATH) + strlen(rulefile) + 2; + rulepath = (char *)calloc(i, sizeof(char)); + if (!rulepath) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + snprintf(rulepath, i, "%s/%s", RULEPATH, rulefile); + } else { + os_strdup(rulefile, rulepath); + debug1("%s is the rulefile", rulefile); + debug1("Not modifing the rule path"); + } + + i = 0; + + /* Read the XML */ + if (OS_ReadXML(rulepath, &xml) < 0) { + merror(XML_ERROR, ARGV0, rulepath, xml.err, xml.err_line); + free(rulepath); + return (-1); + } + debug2("%s: DEBUG: read xml for rule.", ARGV0); + + /* Apply any variable found */ + if (OS_ApplyVariables(&xml) != 0) { + merror(XML_ERROR_VAR, ARGV0, rulepath, xml.err); + free(rulepath); + return (-1); + } + debug2("%s: DEBUG: XML Variables applied.", ARGV0); + + /* Get the root elements */ + node = OS_GetElementsbyNode(&xml, NULL); + if (!node) { + merror(CONFIG_ERROR, ARGV0, rulepath); + OS_ClearXML(&xml); + free(rulepath); + return (-1); + } + + /* Zero the rule memory -- not used anymore */ + free(rulepath); + + /* Get default time frame */ + default_timeframe = getDefine_Int("analysisd", + "default_timeframe", + 60, MAX_TIMEFRAME); + + /* Check if there is any invalid global option */ + while (node[i]) { + if (node[i]->element) { + if (strcasecmp(node[i]->element, xml_group) != 0) { + merror("rules_op: Invalid root element \"%s\"." + "Only \"group\" is allowed", node[i]->element); + OS_ClearXML(&xml); + return (-1); + } + if ((!node[i]->attributes) || (!node[i]->values) || + (!node[i]->values[0]) || (!node[i]->attributes[0]) || + (strcasecmp(node[i]->attributes[0], "name") != 0) || + (node[i]->attributes[1])) { + merror("rules_op: Invalid root element '%s'." + "Only the group name is allowed", node[i]->element); + OS_ClearXML(&xml); + return (-1); + } + } else { + merror(XML_READ_ERROR, ARGV0); + OS_ClearXML(&xml); + return (-1); + } + i++; + } + + /* Get the rules */ + i = 0; + while (node[i]) { + XML_NODE rule = NULL; + + int j = 0; + + /* Get all rules for a global group */ + rule = OS_GetElementsbyNode(&xml, node[i]); + if (rule == NULL) { + merror("%s: Group '%s' without any rule.", + ARGV0, node[i]->element); + OS_ClearXML(&xml); + return (-1); + } + + while (rule[j]) { + RuleInfo *config_ruleinfo = NULL; + + /* Check if the rule element is correct */ + if ((!rule[j]->element) || + (strcasecmp(rule[j]->element, xml_rule) != 0)) { + if (rule[j]->element != NULL) { + merror("%s: Invalid configuration. '%s' is not " + "a valid element.", ARGV0, rule[j]->element); + } else { + merror("%s: Invalid configuration. Unknown invalid element.", ARGV0); + } + OS_ClearXML(&xml); + return (-1); + } + + /* Check for the attributes of the rule */ + if ((!rule[j]->attributes) || (!rule[j]->values)) { + merror("%s: Invalid rule '%d'. You must specify" + " an ID and a level at least.", ARGV0, j); + OS_ClearXML(&xml); + return (-1); + } + + /* Attribute block */ + { + int id = -1, level = -1, maxsize = 0, timeframe = 0; + int frequency = 0, accuracy = 1, noalert = 0, ignore_time = 0; + int overwrite = 0; + + /* Get default timeframe */ + timeframe = default_timeframe; + + if (getattributes(rule[j]->attributes, rule[j]->values, + &id, &level, &maxsize, &timeframe, + &frequency, &accuracy, &noalert, + &ignore_time, &overwrite) < 0) { + merror("%s: Invalid attribute for rule.", ARGV0); + OS_ClearXML(&xml); + return (-1); + } + + if ((id == -1) || (level == -1)) { + merror("%s: No rule id or level specified for " + "rule '%d'.", ARGV0, j); + OS_ClearXML(&xml); + return (-1); + } + + if (overwrite != 1 && doesRuleExist(id, NULL)) { + merror("%s: Duplicate rule ID:%d", ARGV0, id); + OS_ClearXML(&xml); + return (-1); + } + + /* Allocate memory and initialize structure */ + config_ruleinfo = zerorulemember(id, level, maxsize, + frequency, timeframe, + noalert, ignore_time, overwrite); + + /* If rule is 0, set it to level 99 to have high priority. + * Set it to 0 again later. + */ + if (config_ruleinfo->level == 0) { + config_ruleinfo->level = 99; + } + + /* Each level now is going to be multiplied by 100. + * If the accuracy is set to 0 we don't multiply, + * so it will be at the end of the list. We will + * divide by 100 later. + */ + if (accuracy) { + config_ruleinfo->level *= 100; + } + + if (config_ruleinfo->maxsize > 0) { + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } + + } /* end attributes/memory allocation block */ + + /* Here we can assign the group name to the rule. + * The level is correct so the rule is probably going to + * be fine + */ + os_strdup(node[i]->values[0], config_ruleinfo->group); + + /* Rule elements block */ + { + int k = 0; + int ifield = 0; + int info_type = 0; + int count_info_detail = 0; + RuleInfoDetail *last_info_detail = NULL; + char *regex = NULL; + char *match = NULL; + char *pcre2 = NULL; + char *match_pcre2 = NULL; + char *url = NULL; + char *url_pcre2 = NULL; + char *if_matched_regex = NULL; + char *if_matched_group = NULL; + char *user = NULL; + char *id = NULL; + char *srcport = NULL; + char *dstport = NULL; + char *srcgeoip = NULL; + char *dstgeoip = NULL; + + char *status = NULL; + char *hostname = NULL; + char *extra_data = NULL; + char *program_name = NULL; + + char *user_pcre2 = NULL; + char *id_pcre2 = NULL; + char *srcport_pcre2 = NULL; + char *dstport_pcre2 = NULL; + char *srcgeoip_pcre2 = NULL; + char *dstgeoip_pcre2 = NULL; + + char *status_pcre2 = NULL; + char *hostname_pcre2 = NULL; + char *extra_data_pcre2 = NULL; + char *program_name_pcre2 = NULL; + + XML_NODE rule_opt = NULL; + rule_opt = OS_GetElementsbyNode(&xml, rule[j]); + if (rule_opt == NULL) { + merror("%s: Rule '%d' without any option. " + "It may lead to false positives and some " + "other problems for the system. Exiting.", + ARGV0, config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + + while (rule_opt[k]) { + if ((!rule_opt[k]->element) || (!rule_opt[k]->content)) { + break; + } else if (strcasecmp(rule_opt[k]->element, xml_regex) == 0) { + regex = + loadmemory(regex, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_pcre2) == 0) { + pcre2 = + loadmemory(pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_match) == 0) { + match = + loadmemory(match, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_match_pcre2) == 0) { + match_pcre2 = + loadmemory(match_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_decoded) == 0) { + config_ruleinfo->decoded_as = + getDecoderfromlist(rule_opt[k]->content); + + if (config_ruleinfo->decoded_as == 0) { + merror("%s: Invalid decoder name: '%s'.", + ARGV0, rule_opt[k]->content); + OS_ClearXML(&xml); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, xml_cve) == 0) { + if (config_ruleinfo->info_details == NULL) { + config_ruleinfo->info_details = zeroinfodetails(RULEINFODETAIL_CVE, + rule_opt[k]->content); + } else { + for (last_info_detail = config_ruleinfo->info_details; + last_info_detail->next != NULL; + last_info_detail = last_info_detail->next) { + count_info_detail++; + } + /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */ + if (count_info_detail <= MAX_RULEINFODETAIL) { + last_info_detail->next = zeroinfodetails(RULEINFODETAIL_CVE, + rule_opt[k]->content); + } + } + + /* keep old methods for now */ + config_ruleinfo->cve = + loadmemory(config_ruleinfo->cve, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_info) == 0) { + + info_type = get_info_attributes(rule_opt[k]->attributes, + rule_opt[k]->values); + debug1("info_type = %d", info_type); + + if (config_ruleinfo->info_details == NULL) { + config_ruleinfo->info_details = zeroinfodetails(info_type, + rule_opt[k]->content); + } else { + for (last_info_detail = config_ruleinfo->info_details; + last_info_detail->next != NULL; + last_info_detail = last_info_detail->next) { + count_info_detail++; + } + /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */ + if (count_info_detail <= MAX_RULEINFODETAIL) { + last_info_detail->next = zeroinfodetails(info_type, rule_opt[k]->content); + } + } + + + /* keep old methods for now */ + config_ruleinfo->info = + loadmemory(config_ruleinfo->info, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_day_time) == 0) { + config_ruleinfo->day_time = + OS_IsValidTime(rule_opt[k]->content); + if (!config_ruleinfo->day_time) { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_week_day) == 0) { + config_ruleinfo->week_day = + OS_IsValidDay(rule_opt[k]->content); + + if (!config_ruleinfo->week_day) { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_group) == 0) { + config_ruleinfo->group = + loadmemory(config_ruleinfo->group, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_comment) == 0) { + char *newline; + + newline = strchr(rule_opt[k]->content, '\n'); + if (newline) { + *newline = ' '; + } + + config_ruleinfo->comment = + loadmemory(config_ruleinfo->comment, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcip) == 0) { + unsigned int ip_s = 0; + + /* Getting size of source ip list */ + while (config_ruleinfo->srcip && + config_ruleinfo->srcip[ip_s]) { + ip_s++; + } + + config_ruleinfo->srcip = + (os_ip **) realloc(config_ruleinfo->srcip, + (ip_s + 2) * sizeof(os_ip *)); + + + /* Allocating memory for the individual entries */ + os_calloc(1, sizeof(os_ip), + config_ruleinfo->srcip[ip_s]); + config_ruleinfo->srcip[ip_s + 1] = NULL; + + + /* Checking if the ip is valid */ + if (!OS_IsValidIP(rule_opt[k]->content, + config_ruleinfo->srcip[ip_s])) { + merror(INVALID_IP, ARGV0, rule_opt[k]->content); + return (-1); + } + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstip) == 0) { + unsigned int ip_s = 0; + + /* Getting size of source ip list */ + while (config_ruleinfo->dstip && + config_ruleinfo->dstip[ip_s]) { + ip_s++; + } + + config_ruleinfo->dstip = + (os_ip **) realloc(config_ruleinfo->dstip, + (ip_s + 2) * sizeof(os_ip *)); + + + /* Allocating memory for the individual entries */ + os_calloc(1, sizeof(os_ip), + config_ruleinfo->dstip[ip_s]); + config_ruleinfo->dstip[ip_s + 1] = NULL; + + + /* Checking if the ip is valid */ + if (!OS_IsValidIP(rule_opt[k]->content, + config_ruleinfo->dstip[ip_s])) { + merror(INVALID_IP, ARGV0, rule_opt[k]->content); + return (-1); + } + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_user) == 0) { + user = + loadmemory(user, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if(strcasecmp(rule_opt[k]->element,xml_srcgeoip)==0) { + srcgeoip = + loadmemory(srcgeoip, + rule_opt[k]->content); + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if(strcasecmp(rule_opt[k]->element,xml_dstgeoip)==0) { + dstgeoip = + loadmemory(dstgeoip, + rule_opt[k]->content); + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if (strcasecmp(rule_opt[k]->element, xml_id) == 0) { + id = + loadmemory(id, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcport) == 0) { + srcport = + loadmemory(srcport, + rule_opt[k]->content); + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstport) == 0) { + dstport = + loadmemory(dstport, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_status) == 0) { + status = + loadmemory(status, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_hostname) == 0) { + hostname = + loadmemory(hostname, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_data) == 0) { + extra_data = + loadmemory(extra_data, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_program_name) == 0) { + program_name = + loadmemory(program_name, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_user_pcre2) == 0) { + user_pcre2 = + loadmemory(user_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if(strcasecmp(rule_opt[k]->element,xml_srcgeoip_pcre2)==0) { + srcgeoip_pcre2 = + loadmemory(srcgeoip_pcre2, + rule_opt[k]->content); + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if(strcasecmp(rule_opt[k]->element,xml_dstgeoip_pcre2)==0) { + dstgeoip_pcre2 = + loadmemory(dstgeoip_pcre2, + rule_opt[k]->content); + + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } else if (strcasecmp(rule_opt[k]->element, xml_id_pcre2) == 0) { + id_pcre2 = + loadmemory(id_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcport_pcre2) == 0) { + srcport_pcre2 = + loadmemory(srcport_pcre2, + rule_opt[k]->content); + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstport_pcre2) == 0) { + dstport_pcre2 = + loadmemory(dstport_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_status_pcre2) == 0) { + status_pcre2 = + loadmemory(status_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_hostname_pcre2) == 0) { + hostname_pcre2 = + loadmemory(hostname_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_data_pcre2) == 0) { + extra_data_pcre2 = + loadmemory(extra_data_pcre2, + rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_program_name_pcre2) == 0) { + program_name_pcre2 = + loadmemory(program_name_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_action) == 0) { + config_ruleinfo->action = + loadmemory(config_ruleinfo->action, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_field) == 0) { + if (rule_opt[k]->attributes[0]) { + os_calloc(1, sizeof(FieldInfo), config_ruleinfo->fields[ifield]); + + if (strcasecmp(rule_opt[k]->attributes[0], xml_name) == 0) { + config_ruleinfo->fields[ifield]->name = loadmemory(config_ruleinfo->fields[ifield]->name, rule_opt[k]->values[0]); + } else { + merror("%s: Bad attribute '%s' for field.", ARGV0, rule_opt[k]->attributes[0]); + return -1; + } + } else { + merror("%s: No such attribute '%s' for field.", ARGV0, xml_name); + return (-1); + } + + os_calloc(1, sizeof(OSRegex), config_ruleinfo->fields[ifield]->regex); + + if (!OSRegex_Compile(rule_opt[k]->content, config_ruleinfo->fields[ifield]->regex, 0)) { + merror(REGEX_COMPILE, ARGV0, rule_opt[k]->content, config_ruleinfo->fields[ifield]->regex->error); + return -1; + } + + ifield++; + + } else if (strcasecmp(rule_opt[k]->element, xml_list) == 0) { + debug1("-> %s == %s", rule_opt[k]->element, xml_list); + if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content) { + int list_att_num = 0; + int rule_type = 0; + OSMatch *matcher = NULL; + int lookup_type = LR_STRING_MATCH; + while (rule_opt[k]->attributes[list_att_num]) { + if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0) { + if (strcasecmp(rule_opt[k]->values[list_att_num], xml_match_key) == 0) { + lookup_type = LR_STRING_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_not_match_key) == 0) { + lookup_type = LR_STRING_NOT_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_match_key_value) == 0) { + lookup_type = LR_STRING_MATCH_VALUE; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_address_key) == 0) { + lookup_type = LR_ADDRESS_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_not_address_key) == 0) { + lookup_type = LR_ADDRESS_NOT_MATCH; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_address_key_value) == 0) { + lookup_type = LR_ADDRESS_MATCH_VALUE; + } else { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror("%s: List match lookup=\"%s\" is not valid.", + ARGV0, rule_opt[k]->values[list_att_num]); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field) == 0) { + if (strcasecmp(rule_opt[k]->values[list_att_num], xml_srcip) == 0) { + rule_type = RULE_SRCIP; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_srcport) == 0) { + rule_type = RULE_SRCPORT; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_dstip) == 0) { + rule_type = RULE_DSTIP; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_dstport) == 0) { + rule_type = RULE_DSTPORT; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_user) == 0) { + rule_type = RULE_USER; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_url) == 0) { + rule_type = RULE_URL; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_id) == 0) { + rule_type = RULE_ID; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_hostname) == 0) { + rule_type = RULE_HOSTNAME; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_program_name) == 0) { + rule_type = RULE_PROGRAM_NAME; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_status) == 0) { + rule_type = RULE_STATUS; + } else if (strcasecmp(rule_opt[k]->values[list_att_num], xml_action) == 0) { + rule_type = RULE_ACTION; + } else { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror("%s: List match field=\"%s\" is not valid.", + ARGV0, rule_opt[k]->values[list_att_num]); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue) == 0) { + os_calloc(1, sizeof(OSMatch), matcher); + if (!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0)) { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror(REGEX_COMPILE, + ARGV0, + rule_opt[k]->values[list_att_num], + matcher->error); + return (-1); + } + } else { + merror("%s:List field=\"%s\" is not valid", ARGV0, + rule_opt[k]->values[list_att_num]); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return (-1); + } + list_att_num++; + } + if (rule_type == 0) { + merror("%s:List requires the field=\"\" Attrubute", ARGV0); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return (-1); + } + + /* Wow it's all ready - this seems too complex to get to this point */ + config_ruleinfo->lists = OS_AddListRule(config_ruleinfo->lists, + lookup_type, + rule_type, + rule_opt[k]->content, + matcher); + if (config_ruleinfo->lists == NULL) { + merror("%s: List error: Could not load %s", ARGV0, rule_opt[k]->content); + return (-1); + } + } else { + merror("%s:List must have a correctly formatted field attribute", + ARGV0); + merror(INVALID_CONFIG, + ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + /* xml_list eval is done */ + } else if (strcasecmp(rule_opt[k]->element, xml_url) == 0) { + url = + loadmemory(url, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_url_pcre2) == 0) { + url_pcre2 = + loadmemory(url_pcre2, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_compiled) == 0) { + int it_id = 0; + + while (compiled_rules_name[it_id]) { + if (strcmp(compiled_rules_name[it_id], + rule_opt[k]->content) == 0) { + break; + } + it_id++; + } + + /* Checking if the name is valid */ + if (!compiled_rules_name[it_id]) { + merror("%s: ERROR: Compiled rule not found: '%s'", + ARGV0, rule_opt[k]->content); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return (-1); + + } + + config_ruleinfo->compiled_rule = (void *(*)(void *)) compiled_rules_list[it_id]; + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } + + else if (strcasecmp(rule_opt[k]->element, xml_category) == 0) { + if (strcmp(rule_opt[k]->content, "firewall") == 0) { + config_ruleinfo->category = FIREWALL; + } else if (strcmp(rule_opt[k]->content, "ids") == 0) { + config_ruleinfo->category = IDS; + } else if (strcmp(rule_opt[k]->content, "syslog") == 0) { + config_ruleinfo->category = SYSLOG; + } else if (strcmp(rule_opt[k]->content, "web-log") == 0) { + config_ruleinfo->category = WEBLOG; + } else if (strcmp(rule_opt[k]->content, "squid") == 0) { + config_ruleinfo->category = SQUID; + } else if (strcmp(rule_opt[k]->content, "windows") == 0) { + config_ruleinfo->category = DECODER_WINDOWS; + } else if (strcmp(rule_opt[k]->content, "openarmor") == 0) { + config_ruleinfo->category = openarmor_RL; + } else { + merror(INVALID_CAT, ARGV0, rule_opt[k]->content); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, xml_if_sid) == 0) { + config_ruleinfo->if_sid = + loadmemory(config_ruleinfo->if_sid, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_if_level) == 0) { + if (!OS_StrIsNum(rule_opt[k]->content)) { + merror(INVALID_CONFIG, ARGV0, + "if_level", + rule_opt[k]->content); + return (-1); + } + + config_ruleinfo->if_level = + loadmemory(config_ruleinfo->if_level, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_if_group) == 0) { + config_ruleinfo->if_group = + loadmemory(config_ruleinfo->if_group, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_regex) == 0) { + config_ruleinfo->context = 1; + if_matched_regex = + loadmemory(if_matched_regex, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_group) == 0) { + config_ruleinfo->context = 1; + if_matched_group = + loadmemory(if_matched_group, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_sid) == 0) { + config_ruleinfo->context = 1; + if (!OS_StrIsNum(rule_opt[k]->content)) { + merror(INVALID_CONFIG, ARGV0, + "if_matched_sid", + rule_opt[k]->content); + return (-1); + } + config_ruleinfo->if_matched_sid = + atoi(rule_opt[k]->content); + + } else if (strcasecmp(rule_opt[k]->element, + xml_same_source_ip) == 0) { + config_ruleinfo->context_opts |= SAME_SRCIP; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_src_port) == 0) { + config_ruleinfo->context_opts |= SAME_SRCPORT; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_dodiff) == 0) { + config_ruleinfo->context = 1; + config_ruleinfo->context_opts |= SAME_DODIFF; + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_same_dst_port) == 0) { + config_ruleinfo->context_opts |= SAME_DSTPORT; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_source_ip) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_SRCIP; + } else if (strcmp(rule_opt[k]->element, xml_same_id) == 0) { + config_ruleinfo->context_opts |= SAME_ID; + } else if (strcmp(rule_opt[k]->element, + xml_different_url) == 0) { + config_ruleinfo->context_opts |= DIFFERENT_URL; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if(strcmp(rule_opt[k]->element, + xml_different_srcip) == 0) { + config_ruleinfo->context_opts|= DIFFERENT_SRCIP; + + if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } else if(strcmp(rule_opt[k]->element, + xml_different_srcgeoip) == 0) { + config_ruleinfo->context_opts|= DIFFERENT_SRCGEOIP; + + if(!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } else if (strcmp(rule_opt[k]->element, xml_notsame_id) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_ID; + } else if (strcasecmp(rule_opt[k]->element, + xml_fts) == 0) { + config_ruleinfo->alert_opts |= DO_FTS; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_user) == 0) { + config_ruleinfo->context_opts |= SAME_USER; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_user) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_USER; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_location) == 0) { + config_ruleinfo->context_opts |= SAME_LOCATION; + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_agent) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_AGENT; + } else if (strcasecmp(rule_opt[k]->element, + xml_options) == 0) { + if (strcmp("alert_by_email", + rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & DO_MAILALERT)) { + config_ruleinfo->alert_opts |= DO_MAILALERT; + } + } else if (strcmp("no_email_alert", + rule_opt[k]->content) == 0) { + if (config_ruleinfo->alert_opts & DO_MAILALERT) { + config_ruleinfo->alert_opts &= 0xfff - DO_MAILALERT; + } + } else if (strcmp("log_alert", + rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & DO_LOGALERT)) { + config_ruleinfo->alert_opts |= DO_LOGALERT; + } + } else if (strcmp("no_log", rule_opt[k]->content) == 0) { + if (config_ruleinfo->alert_opts & DO_LOGALERT) { + config_ruleinfo->alert_opts &= 0xfff - DO_LOGALERT; + } + } else if (strcmp("no_ar", rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & NO_AR)) { + config_ruleinfo->alert_opts |= NO_AR; + } + } else { + merror(XML_VALUEERR, ARGV0, xml_options, + rule_opt[k]->content); + + merror("%s: Invalid option '%s' for " + "rule '%d'.", ARGV0, rule_opt[k]->element, + config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, + xml_ignore) == 0) { + if (strstr(rule_opt[k]->content, "user") != NULL) { + config_ruleinfo->ignore |= FTS_DSTUSER; + } + if (strstr(rule_opt[k]->content, "srcip") != NULL) { + config_ruleinfo->ignore |= FTS_SRCIP; + } + if (strstr(rule_opt[k]->content, "dstip") != NULL) { + config_ruleinfo->ignore |= FTS_DSTIP; + } + if (strstr(rule_opt[k]->content, "id") != NULL) { + config_ruleinfo->ignore |= FTS_ID; + } + if (strstr(rule_opt[k]->content, "location") != NULL) { + config_ruleinfo->ignore |= FTS_LOCATION; + } + if (strstr(rule_opt[k]->content, "data") != NULL) { + config_ruleinfo->ignore |= FTS_DATA; + } + if (strstr(rule_opt[k]->content, "name") != NULL) { + config_ruleinfo->ignore |= FTS_NAME; + + } + if (!config_ruleinfo->ignore) { + merror("%s: Wrong ignore option: '%s'", + ARGV0, + rule_opt[k]->content); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, + xml_check_if_ignored) == 0) { + if (strstr(rule_opt[k]->content, "user") != NULL) { + config_ruleinfo->ckignore |= FTS_DSTUSER; + } + if (strstr(rule_opt[k]->content, "srcip") != NULL) { + config_ruleinfo->ckignore |= FTS_SRCIP; + } + if (strstr(rule_opt[k]->content, "dstip") != NULL) { + config_ruleinfo->ckignore |= FTS_DSTIP; + } + if (strstr(rule_opt[k]->content, "id") != NULL) { + config_ruleinfo->ckignore |= FTS_ID; + } + if (strstr(rule_opt[k]->content, "location") != NULL) { + config_ruleinfo->ckignore |= FTS_LOCATION; + } + if (strstr(rule_opt[k]->content, "data") != NULL) { + config_ruleinfo->ckignore |= FTS_DATA; + } + if (strstr(rule_opt[k]->content, "name") != NULL) { + config_ruleinfo->ckignore |= FTS_NAME; + + } + if (!config_ruleinfo->ckignore) { + merror("%s: Wrong check_if_ignored option: '%s'", + ARGV0, + rule_opt[k]->content); + return (-1); + } + } else { + merror("%s: Invalid option '%s' for " + "rule '%d'.", ARGV0, rule_opt[k]->element, + config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + k++; + } + + /* Check for valid use of frequency */ + if ((config_ruleinfo->context_opts || + config_ruleinfo->frequency) && + !config_ruleinfo->context) { + merror("%s: Invalid use of frequency/context options. " + "Missing if_matched on rule '%d'.", + ARGV0, config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + + /* If if_matched_group we must have a if_sid or if_group */ + if (if_matched_group) { + if (!config_ruleinfo->if_sid && !config_ruleinfo->if_group) { + os_strdup(if_matched_group, + config_ruleinfo->if_group); + } + } + + /* If_matched_sid, we need to get the if_sid */ + if (config_ruleinfo->if_matched_sid && + !config_ruleinfo->if_sid && + !config_ruleinfo->if_group) { + os_calloc(16, sizeof(char), config_ruleinfo->if_sid); + snprintf(config_ruleinfo->if_sid, 15, "%d", + config_ruleinfo->if_matched_sid); + } + + /* Check the regexes */ + if (regex) { + os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex); + if (!OSRegex_Compile(regex, config_ruleinfo->regex, 0)) { + merror(REGEX_COMPILE, ARGV0, regex, + config_ruleinfo->regex->error); + return (-1); + } + free(regex); + regex = NULL; + } + + if (pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->pcre2); + if (!OSPcre2_Compile(pcre2, config_ruleinfo->pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, pcre2, + config_ruleinfo->pcre2->error); + return (-1); + } + free(pcre2); + pcre2 = NULL; + } + + /* Add in match */ + if (match) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->match); + if (!OSMatch_Compile(match, config_ruleinfo->match, 0)) { + merror(REGEX_COMPILE, ARGV0, match, + config_ruleinfo->match->error); + return (-1); + } + free(match); + match = NULL; + } + else if (match_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->match_pcre2); + if (!OSPcre2_Compile(match_pcre2, config_ruleinfo->match_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, match_pcre2, + config_ruleinfo->match_pcre2->error); + return (-1); + } + free(match_pcre2); + match_pcre2 = NULL; + } + + /* Add in id */ + if (id) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->id); + if (!OSMatch_Compile(id, config_ruleinfo->id, 0)) { + merror(REGEX_COMPILE, ARGV0, id, + config_ruleinfo->id->error); + return (-1); + } + free(id); + id = NULL; + } + if (id_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->id_pcre2); + if (!OSPcre2_Compile(id_pcre2, config_ruleinfo->id_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, id, + config_ruleinfo->id_pcre2->error); + return (-1); + } + free(id_pcre2); + id_pcre2 = NULL; + } + + /* Add srcport */ + if (srcport) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport); + if (!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0)) { + merror(REGEX_COMPILE, ARGV0, srcport, + config_ruleinfo->id->error); + return (-1); + } + free(srcport); + srcport = NULL; + } + if (srcport_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->srcport_pcre2); + if (!OSPcre2_Compile(srcport_pcre2, config_ruleinfo->srcport_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, srcport_pcre2, + config_ruleinfo->id->error); + return (-1); + } + free(srcport_pcre2); + srcport_pcre2 = NULL; + } + + /* Add dstport */ + if (dstport) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport); + if (!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0)) { + merror(REGEX_COMPILE, ARGV0, dstport, + config_ruleinfo->id->error); + return (-1); + } + free(dstport); + dstport = NULL; + } + else if (dstport_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->dstport_pcre2); + if (!OSPcre2_Compile(dstport_pcre2, config_ruleinfo->dstport_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, dstport_pcre2, + config_ruleinfo->id->error); + return (-1); + } + free(dstport_pcre2); + dstport_pcre2 = NULL; + } + + /* Add in status */ + if (status) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->status); + if (!OSMatch_Compile(status, config_ruleinfo->status, 0)) { + merror(REGEX_COMPILE, ARGV0, status, + config_ruleinfo->status->error); + return (-1); + } + free(status); + status = NULL; + } + else if (status_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->status_pcre2); + if (!OSPcre2_Compile(status_pcre2, config_ruleinfo->status_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, status_pcre2, + config_ruleinfo->status_pcre2->error); + return (-1); + } + free(status_pcre2); + status_pcre2 = NULL; + } + + /* Add in hostname */ + if (hostname) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname); + if (!OSMatch_Compile(hostname, config_ruleinfo->hostname, 0)) { + merror(REGEX_COMPILE, ARGV0, hostname, + config_ruleinfo->hostname->error); + return (-1); + } + free(hostname); + hostname = NULL; + } + else if (hostname_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->hostname_pcre2); + if (!OSPcre2_Compile(hostname_pcre2, config_ruleinfo->hostname_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, hostname_pcre2, + config_ruleinfo->hostname_pcre2->error); + return (-1); + } + free(hostname_pcre2); + hostname_pcre2 = NULL; + } + + /* Add extra data */ + if (extra_data) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data); + if (!OSMatch_Compile(extra_data, + config_ruleinfo->extra_data, 0)) { + merror(REGEX_COMPILE, ARGV0, extra_data, + config_ruleinfo->extra_data->error); + return (-1); + } + free(extra_data); + extra_data = NULL; + } + else if (extra_data_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->extra_data_pcre2); + if (!OSPcre2_Compile(extra_data_pcre2, + config_ruleinfo->extra_data_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, extra_data_pcre2, + config_ruleinfo->extra_data_pcre2->error); + return (-1); + } + free(extra_data_pcre2); + extra_data_pcre2 = NULL; + } + + /* Add in program name */ + if (program_name) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->program_name); + if (!OSMatch_Compile(program_name, + config_ruleinfo->program_name, 0)) { + merror(REGEX_COMPILE, ARGV0, program_name, + config_ruleinfo->program_name->error); + return (-1); + } + free(program_name); + program_name = NULL; + } + else if (program_name_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->program_name_pcre2); + if (!OSPcre2_Compile(program_name_pcre2, + config_ruleinfo->program_name_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, program_name_pcre2, + config_ruleinfo->program_name_pcre2->error); + return (-1); + } + free(program_name_pcre2); + program_name_pcre2 = NULL; + } + + /* Add in user */ + if (user) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->user); + if (!OSMatch_Compile(user, config_ruleinfo->user, 0)) { + merror(REGEX_COMPILE, ARGV0, user, + config_ruleinfo->user->error); + return (-1); + } + free(user); + user = NULL; + } + else if (user_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->user_pcre2); + if (!OSPcre2_Compile(user_pcre2, config_ruleinfo->user_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, user_pcre2, + config_ruleinfo->user_pcre2->error); + return (-1); + } + free(user_pcre2); + user_pcre2 = NULL; + } + + /* Adding in srcgeoip */ + if(srcgeoip) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcgeoip); + if(!OSMatch_Compile(srcgeoip, config_ruleinfo->srcgeoip, 0)) { + merror(REGEX_COMPILE, ARGV0, srcgeoip, + config_ruleinfo->srcgeoip->error); + return(-1); + } + free(srcgeoip); + srcgeoip = NULL; + } + else if(srcgeoip_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->srcgeoip_pcre2); + if(!OSPcre2_Compile(srcgeoip_pcre2, config_ruleinfo->srcgeoip_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, srcgeoip_pcre2, + config_ruleinfo->srcgeoip_pcre2->error); + return(-1); + } + free(srcgeoip_pcre2); + srcgeoip_pcre2 = NULL; + } + + + /* Adding in dstgeoip */ + if(dstgeoip) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstgeoip); + if(!OSMatch_Compile(dstgeoip, config_ruleinfo->dstgeoip, 0)) { + merror(REGEX_COMPILE, ARGV0, dstgeoip, + config_ruleinfo->dstgeoip->error); + return(-1); + } + free(dstgeoip); + dstgeoip = NULL; + } + else if(dstgeoip_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->dstgeoip_pcre2); + if(!OSPcre2_Compile(dstgeoip_pcre2, config_ruleinfo->dstgeoip_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, dstgeoip_pcre2, + config_ruleinfo->dstgeoip_pcre2->error); + return(-1); + } + free(dstgeoip_pcre2); + dstgeoip_pcre2 = NULL; + } + + + /* Add in URL */ + if (url) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->url); + if (!OSMatch_Compile(url, config_ruleinfo->url, 0)) { + merror(REGEX_COMPILE, ARGV0, url, + config_ruleinfo->url->error); + return (-1); + } + free(url); + url = NULL; + } + else if (url_pcre2) { + os_calloc(1, sizeof(OSPcre2), config_ruleinfo->url_pcre2); + if (!OSPcre2_Compile(url_pcre2, config_ruleinfo->url_pcre2, PCRE2_CASELESS)) { + merror(REGEX_COMPILE, ARGV0, url_pcre2, + config_ruleinfo->url_pcre2->error); + return (-1); + } + free(url_pcre2); + url_pcre2 = NULL; + } + + /* Add matched_group */ + if (if_matched_group) { + os_calloc(1, sizeof(OSMatch), + config_ruleinfo->if_matched_group); + + if (!OSMatch_Compile(if_matched_group, + config_ruleinfo->if_matched_group, + 0)) { + merror(REGEX_COMPILE, ARGV0, if_matched_group, + config_ruleinfo->if_matched_group->error); + return (-1); + } + free(if_matched_group); + if_matched_group = NULL; + } + + /* Add matched_regex */ + if (if_matched_regex) { + os_calloc(1, sizeof(OSRegex), + config_ruleinfo->if_matched_regex); + if (!OSRegex_Compile(if_matched_regex, + config_ruleinfo->if_matched_regex, 0)) { + merror(REGEX_COMPILE, ARGV0, if_matched_regex, + config_ruleinfo->if_matched_regex->error); + return (-1); + } + free(if_matched_regex); + if_matched_regex = NULL; + } + OS_ClearNode(rule_opt); + } /* end of elements block */ + + /* Assign an active response to the rule */ + Rule_AddAR(config_ruleinfo); + + j++; /* next rule */ + + /* Create the last_events if necessary */ + if (config_ruleinfo->context) { + int ii = 0; + os_calloc(MAX_LAST_EVENTS + 1, sizeof(char *), + config_ruleinfo->last_events); + + /* Zero each entry */ + for (; ii <= MAX_LAST_EVENTS; ii++) { + config_ruleinfo->last_events[ii] = NULL; + } + } + + /* Add the rule to the rules list. + * Only the template rules are supposed + * to be at the top level. All others + * will be a "child" of someone. + */ + if (config_ruleinfo->sigid < 10) { + OS_AddRule(config_ruleinfo); + } else if (config_ruleinfo->alert_opts & DO_OVERWRITE) { + if (!OS_AddRuleInfo(NULL, config_ruleinfo, + config_ruleinfo->sigid)) { + merror("%s: Overwrite rule '%d' not found.", + ARGV0, config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + } else { + OS_AddChild(config_ruleinfo); + } + + /* Clean what we do not need */ + if (config_ruleinfo->if_group) { + free(config_ruleinfo->if_group); + config_ruleinfo->if_group = NULL; + } + + /* Set the event_search pointer */ + if (config_ruleinfo->if_matched_sid) { + config_ruleinfo->event_search = (void *(*)(void *, void *)) + Search_LastSids; + + /* Mark rules that match this id */ + OS_MarkID(NULL, config_ruleinfo); + } + + /* Mark the rules that match if_matched_group */ + else if (config_ruleinfo->if_matched_group) { + /* Create list */ + config_ruleinfo->group_search = OSList_Create(); + if (!config_ruleinfo->group_search) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Mark rules that match this group */ + OS_MarkGroup(NULL, config_ruleinfo); + + /* Set function pointer */ + config_ruleinfo->event_search = (void *(*)(void *, void *)) + Search_LastGroups; + } else if (config_ruleinfo->context) { + if ((config_ruleinfo->context == 1) && + (config_ruleinfo->context_opts & SAME_DODIFF)) { + config_ruleinfo->context = 0; + } else { + config_ruleinfo->event_search = (void *(*)(void *, void *)) + Search_LastEvents; + } + } + + } /* while(rule[j]) */ + OS_ClearNode(rule); + i++; + + } /* while (node[i]) */ + + /* Clean global node */ + OS_ClearNode(node); + OS_ClearXML(&xml); + +#ifdef DEBUG + { + RuleNode *dbg_node = OS_GetFirstRule(); + while (dbg_node) { + if (dbg_node->child) { + RuleNode *child_node = dbg_node->child; + + printf("** Child Node for %d **\n", dbg_node->ruleinfo->sigid); + while (child_node) { + child_node = child_node->next; + } + } + dbg_node = dbg_node->next; + } + } +#endif + + /* Done over here */ + return (0); +} + +/* Allocate memory at "*at" and copy *str to it. + * If *at already exist, realloc the memory and cat str on it. + * Returns the new string + */ +static char *loadmemory(char *at, const char *str) +{ + if (at == NULL) { + size_t strsize = 0; + if ((strsize = strlen(str)) < OS_SIZE_2048) { + at = (char *) calloc(strsize + 1, sizeof(char)); + if (at == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + strncpy(at, str, strsize); + return (at); + } else { + merror(SIZE_ERROR, ARGV0, str); + return (NULL); + } + } else { + /* at is not null. Need to reallocate its memory and copy str to it */ + size_t strsize = strlen(str); + size_t atsize = strlen(at); + size_t finalsize = atsize + strsize + 1; + + if ((atsize > OS_SIZE_2048) || (strsize > OS_SIZE_2048)) { + merror(SIZE_ERROR, ARGV0, str); + return (NULL); + } + + at = (char *) realloc(at, (finalsize) * sizeof(char)); + + if (at == NULL) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + + strncat(at, str, strsize); + at[finalsize - 1] = '\0'; + + return (at); + } + return (NULL); +} + +RuleInfoDetail *zeroinfodetails(int type, const char *data) +{ + RuleInfoDetail *info_details_pt = NULL; + + info_details_pt = (RuleInfoDetail *)calloc(1, sizeof(RuleInfoDetail)); + + if (info_details_pt == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + info_details_pt->type = type; + os_strdup(data, info_details_pt->data); + info_details_pt->next = NULL; + + return (info_details_pt); +} + +RuleInfo *zerorulemember(int id, int level, + int maxsize, int frequency, + int timeframe, int noalert, + int ignore_time, int overwrite) +{ + RuleInfo *ruleinfo_pt = NULL; + + /* Allocate memory for structure */ + ruleinfo_pt = (RuleInfo *)calloc(1, sizeof(RuleInfo)); + + if (ruleinfo_pt == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Default values */ + ruleinfo_pt->level = level; + + /* Default category is syslog */ + ruleinfo_pt->category = SYSLOG; + + ruleinfo_pt->ar = NULL; + + ruleinfo_pt->context = 0; + + ruleinfo_pt->sigid = id; + ruleinfo_pt->firedtimes = 0; + ruleinfo_pt->maxsize = maxsize; + ruleinfo_pt->frequency = frequency; + if (ruleinfo_pt->frequency > _max_freq) { + _max_freq = ruleinfo_pt->frequency; + } + ruleinfo_pt->ignore_time = ignore_time; + ruleinfo_pt->timeframe = timeframe; + ruleinfo_pt->time_ignored = 0; + + ruleinfo_pt->context_opts = 0; + ruleinfo_pt->alert_opts = 0; + ruleinfo_pt->ignore = 0; + ruleinfo_pt->ckignore = 0; + + if (noalert) { + ruleinfo_pt->alert_opts |= NO_ALERT; + } + if (Config.mailbylevel <= level) { + ruleinfo_pt->alert_opts |= DO_MAILALERT; + } + if (Config.logbylevel <= level) { + ruleinfo_pt->alert_opts |= DO_LOGALERT; + } + + /* Overwrite a rule */ + if (overwrite) { + ruleinfo_pt->alert_opts |= DO_OVERWRITE; + } + + ruleinfo_pt->day_time = NULL; + ruleinfo_pt->week_day = NULL; + + ruleinfo_pt->group = NULL; + ruleinfo_pt->regex = NULL; + ruleinfo_pt->match = NULL; + ruleinfo_pt->decoded_as = 0; + + ruleinfo_pt->comment = NULL; + ruleinfo_pt->info = NULL; + ruleinfo_pt->cve = NULL; + ruleinfo_pt->info_details = NULL; + + ruleinfo_pt->if_sid = NULL; + ruleinfo_pt->if_group = NULL; + ruleinfo_pt->if_level = NULL; + + ruleinfo_pt->if_matched_regex = NULL; + ruleinfo_pt->if_matched_group = NULL; + ruleinfo_pt->if_matched_sid = 0; + + ruleinfo_pt->user = NULL; + ruleinfo_pt->srcip = NULL; + ruleinfo_pt->srcport = NULL; + ruleinfo_pt->dstip = NULL; + ruleinfo_pt->dstport = NULL; + ruleinfo_pt->url = NULL; + ruleinfo_pt->id = NULL; + ruleinfo_pt->status = NULL; + ruleinfo_pt->hostname = NULL; + ruleinfo_pt->program_name = NULL; + ruleinfo_pt->action = NULL; + os_calloc(Config.decoder_order_size, sizeof(FieldInfo*), ruleinfo_pt->fields); + + + /* Zero last matched events */ + ruleinfo_pt->__frequency = 0; + ruleinfo_pt->last_events = NULL; + + /* Zeroing the list of previous matches */ + ruleinfo_pt->sid_prev_matched = NULL; + ruleinfo_pt->group_prev_matched = NULL; + + ruleinfo_pt->sid_search = NULL; + ruleinfo_pt->group_search = NULL; + + ruleinfo_pt->event_search = NULL; + ruleinfo_pt->compiled_rule = NULL; + ruleinfo_pt->lists = NULL; + + return (ruleinfo_pt); +} + +int get_info_attributes(char **attributes, char **values) +{ + const char *xml_type = "type"; + int k = 0; + + if (!attributes) { + return (RULEINFODETAIL_TEXT); + } + + while (attributes[k]) { + if (!values[k]) { + merror("rules_op: Entry info type \"%s\" does not have a value", + attributes[k]); + return (-1); + } else if (strcasecmp(attributes[k], xml_type) == 0) { + if (strcmp(values[k], "text") == 0) { + return (RULEINFODETAIL_TEXT); + } else if (strcmp(values[k], "link") == 0) { + return (RULEINFODETAIL_LINK); + } else if (strcmp(values[k], "cve") == 0) { + return (RULEINFODETAIL_CVE); + } else if (strcmp(values[k], "osvdb") == 0) { + return (RULEINFODETAIL_OSVDB); + } + } + } + return (RULEINFODETAIL_TEXT); +} + +/* Get the attributes */ +static int getattributes(char **attributes, char **values, + int *id, int *level, + int *maxsize, int *timeframe, + int *frequency, int *accuracy, + int *noalert, int *ignore_time, int *overwrite) +{ + int k = 0; + + const char *xml_id = "id"; + const char *xml_level = "level"; + const char *xml_maxsize = "maxsize"; + const char *xml_timeframe = "timeframe"; + const char *xml_frequency = "frequency"; + const char *xml_accuracy = "accuracy"; + const char *xml_noalert = "noalert"; + const char *xml_ignore_time = "ignore"; + const char *xml_overwrite = "overwrite"; + + /* Get attributes */ + while (attributes[k]) { + if (!values[k]) { + merror("rules_op: Attribute \"%s\" without value." + , attributes[k]); + return (-1); + } + /* Get rule id */ + else if (strcasecmp(attributes[k], xml_id) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%6d", id); + } else { + merror("rules_op: Invalid rule id: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Get level */ + else if (strcasecmp(attributes[k], xml_level) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", level); + } else { + merror("rules_op: Invalid level: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Get maxsize */ + else if (strcasecmp(attributes[k], xml_maxsize) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", maxsize); + } else { + merror("rules_op: Invalid maxsize: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Get timeframe */ + else if (strcasecmp(attributes[k], xml_timeframe) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%5d", timeframe); + } else { + merror("rules_op: Invalid timeframe: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Get frequency */ + else if (strcasecmp(attributes[k], xml_frequency) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", frequency); + } else { + merror("rules_op: Invalid frequency: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Rule accuracy */ + else if (strcasecmp(attributes[k], xml_accuracy) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%4d", accuracy); + } else { + merror("rules_op: Invalid accuracy: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Rule ignore_time */ + else if (strcasecmp(attributes[k], xml_ignore_time) == 0) { + if (OS_StrIsNum(values[k])) { + sscanf(values[k], "%6d", ignore_time); + } else { + merror("rules_op: Invalid ignore_time: %s. " + "Must be integer" , + values[k]); + return (-1); + } + } + /* Rule noalert */ + else if (strcasecmp(attributes[k], xml_noalert) == 0) { + *noalert = 1; + } else if (strcasecmp(attributes[k], xml_overwrite) == 0) { + if (strcmp(values[k], "yes") == 0) { + *overwrite = 1; + } else if (strcmp(values[k], "no") == 0) { + *overwrite = 0; + } else { + merror("rules_op: Invalid overwrite: %s. " + "Can only by 'yes' or 'no'.", values[k]); + return (-1); + } + } else { + merror("rules_op: Invalid attribute \"%s\". " + "Only id, level, maxsize, accuracy, noalert and timeframe " + "are allowed.", attributes[k]); + return (-1); + } + k++; + } + return (0); +} + +/* Bind active responses to a rule */ +static void Rule_AddAR(RuleInfo *rule_config) +{ + unsigned int rule_ar_size = 0; + int mark_to_ar = 0; + int rule_real_level = 0; + + OSListNode *my_ars_node; + + /* Set the correct levels + * We play internally with the rules, to set + * the priorities... Rules with 0 of accuracy, + * receive a low level and go down in the list + */ + if (rule_config->level == 9900) { + rule_real_level = 0; + } + + else if (rule_config->level >= 100) { + rule_real_level = rule_config->level / 100; + } + + /* No AR for ignored rules */ + if (rule_real_level == 0) { + return; + } + + /* No AR when options no_ar is set */ + if (rule_config->alert_opts & NO_AR) { + return; + } + + if (!active_responses) { + return; + } + + /* Loop on all AR */ + my_ars_node = OSList_GetFirstNode(active_responses); + while (my_ars_node) { + active_response *my_ar; + + + my_ar = (active_response *)my_ars_node->data; + mark_to_ar = 0; + + /* Check if the level for the ar is higher */ + if (my_ar->level) { + if (rule_real_level >= my_ar->level) { + mark_to_ar = 1; + } + } + + /* Check if group matches */ + if (my_ar->rules_group) { + if (OS_Regex(my_ar->rules_group, rule_config->group)) { + mark_to_ar = 1; + } + } + + /* Check if rule id matches */ + if (my_ar->rules_id) { + int r_id = 0; + char *str_pt = my_ar->rules_id; + + while (*str_pt != '\0') { + /* We allow spaces in between */ + if (*str_pt == ' ') { + str_pt++; + continue; + } + + /* If is digit, we get the value + * and search for the next digit + * available + */ + else if (isdigit((int)*str_pt)) { + r_id = atoi(str_pt); + + /* mark to ar if id matches */ + if (r_id == rule_config->sigid) { + mark_to_ar = 1; + } + + str_pt = strchr(str_pt, ','); + if (str_pt) { + str_pt++; + } else { + break; + } + } + + /* Check for duplicate commas */ + else if (*str_pt == ',') { + str_pt++; + continue; + } + + else { + break; + } + } + } /* eof of rules_id */ + + /* Bind AR to the rule */ + if (mark_to_ar == 1) { + rule_ar_size++; + + rule_config->ar = (active_response **) realloc(rule_config->ar, + (rule_ar_size + 1) + * sizeof(active_response *)); + + /* Always set the last node to NULL */ + rule_config->ar[rule_ar_size - 1] = my_ar; + rule_config->ar[rule_ar_size] = NULL; + } + + my_ars_node = OSList_GetNextNode(active_responses); + } + + return; +} + +static void printRuleinfo(const RuleInfo *rule, int node) +{ + debug1("%d : rule:%d, level %d, timeout: %d", + node, + rule->sigid, + rule->level, + rule->ignore_time); +} + +/* Add rule to hash */ +int AddHash_Rule(RuleNode *node) +{ + while (node) { + char id_key[15]; + + snprintf(id_key, 14, "%d", node->ruleinfo->sigid); + + /* Add key to hash */ + OSHash_Add(Config.g_rules_hash, id_key, node->ruleinfo); + if (node->child) { + AddHash_Rule(node->child); + } + + node = node->next; + } + + return (0); +} + +int _setlevels(RuleNode *node, int nnode) +{ + int l_size = 0; + while (node) { + if (node->ruleinfo->level == 9900) { + node->ruleinfo->level = 0; + } + + if (node->ruleinfo->level >= 100) { + node->ruleinfo->level /= 100; + } + + l_size++; + + /* Rule information */ + printRuleinfo(node->ruleinfo, nnode); + + if (node->child) { + int chl_size = 0; + chl_size = _setlevels(node->child, nnode + 1); + + l_size += chl_size; + } + + node = node->next; + } + + return (l_size); +} + +/* Test if a rule id exists + * return 1 if exists, otherwise 0 + */ +static int doesRuleExist(int sid, RuleNode *r_node) +{ + /* Start from the beginning of the list by default */ + if (!r_node) { + r_node = OS_GetFirstRule(); + } + + while (r_node) { + /* Check if the sigid matches */ + if (r_node->ruleinfo->sigid == sid) { + return (1); + } + + /* Check if the rule has a child */ + if (r_node->child) { + /* Check recursively */ + if (doesRuleExist(sid, r_node->child)) { + return (1); + } + } + + /* Go to the next rule */ + r_node = r_node->next; + } + + return (0); +} diff --git a/src/analysisd/rules.h b/src/analysisd/rules.h new file mode 100644 index 000000000..ccf035ce0 --- /dev/null +++ b/src/analysisd/rules.h @@ -0,0 +1,266 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _OS_RULES +#define _OS_RULES + +#define MAX_LAST_EVENTS 11 + +#define MAX_TIMEFRAME 604800 + +#include "shared.h" +#include "active-response.h" +#include "lists.h" + +/* Event context - stored on a uint8 */ +#define SAME_USER 0x001 /* 1 */ +#define SAME_SRCIP 0x002 /* 2 */ +#define SAME_ID 0x004 /* 4 */ +#define SAME_LOCATION 0x008 /* 8 */ +#define DIFFERENT_URL 0x010 /* */ +#define DIFFERENT_SRCIP 0x200 +#define DIFFERENT_SRCGEOIP 0x400 +#define SAME_SRCPORT 0x020 +#define SAME_DSTPORT 0x040 +#define SAME_DODIFF 0x100 +#define NOT_SAME_USER 0xffe /* 0xfff - 0x001 */ +#define NOT_SAME_SRCIP 0xffd /* 0xfff - 0x002 */ +#define NOT_SAME_ID 0xffb /* 0xfff - 0x004 */ +#define NOT_SAME_AGENT 0xff7 /* 0xfff - 0x008 */ + +/* Alert options - store on a uint8 */ +#define DO_FTS 0x001 +#define DO_MAILALERT 0x002 +#define DO_LOGALERT 0x004 +#define NO_AR 0x008 +#define NO_ALERT 0x010 +#define DO_OVERWRITE 0x020 +#define DO_PACKETINFO 0x040 +#define DO_EXTRAINFO 0x100 +#define SAME_EXTRAINFO 0x200 + +#define RULE_MASTER 1 +#define RULE_SRCIP 2 +#define RULE_SRCPORT 4 +#define RULE_DSTIP 8 +#define RULE_DSTPORT 16 +#define RULE_USER 32 +#define RULE_URL 64 +#define RULE_ID 128 +#define RULE_HOSTNAME 256 +#define RULE_PROGRAM_NAME 512 +#define RULE_STATUS 1024 +#define RULE_ACTION 2048 + +#define RULEINFODETAIL_TEXT 0 +#define RULEINFODETAIL_LINK 1 +#define RULEINFODETAIL_CVE 2 +#define RULEINFODETAIL_OSVDB 3 +#define RULEINFODETAIL_BUGTRACK 4 + +#define MAX_RULEINFODETAIL 32 + +typedef struct _FieldInfo { + char *name; + OSRegex *regex; +} FieldInfo; + + +typedef struct _RuleInfoDetail { + int type; + char *data; + struct _RuleInfoDetail *next; +} RuleInfoDetail; + +typedef struct _RuleInfo { + int sigid; /* id attribute -- required*/ + int level; /* level attribute --required */ + size_t maxsize; + int frequency; + int timeframe; + + u_int8_t context; /* Not an user option */ + + int firedtimes; /* Not an user option */ + time_t time_ignored; /* Not an user option */ + int ignore_time; + int ignore; + int ckignore; + unsigned int group_prev_matched_sz; + + int __frequency; + char **last_events; + + /* Not an option in the rule */ + u_int16_t alert_opts; + + /* Context options */ + u_int16_t context_opts; + + /* Category */ + u_int8_t category; + + /* Decoded as */ + u_int16_t decoded_as; + + /* List of previously matched events */ + OSList *sid_prev_matched; + + /* Pointer to a list (points to sid_prev_matched of if_matched_sid */ + OSList *sid_search; + + /* List of previously matched events in this group. + * Every rule that has if_matched_group will have this + * list. Every rule that matches this group, it going to + * have a pointer to it (group_search). + */ + OSList **group_prev_matched; + + /* Pointer to group_prev_matched */ + OSList *group_search; + + /* Function pointer to the event_search */ + void *(*event_search)(void *lf, void *rule); + + char *group; + OSMatch *match; + OSPcre2 *match_pcre2; + OSRegex *regex; + OSPcre2 *pcre2; + + /* Policy-based rules */ + char *day_time; + char *week_day; + + os_ip **srcip; + os_ip **dstip; + OSMatch *srcgeoip; + OSMatch *dstgeoip; + OSMatch *srcport; + OSMatch *dstport; + OSMatch *user; + OSMatch *url; + OSMatch *id; + OSMatch *status; + OSMatch *hostname; + OSMatch *program_name; + OSMatch *extra_data; + FieldInfo **fields; + + + OSPcre2 *srcgeoip_pcre2; + OSPcre2 *dstgeoip_pcre2; + OSPcre2 *srcport_pcre2; + OSPcre2 *dstport_pcre2; + OSPcre2 *user_pcre2; + OSPcre2 *url_pcre2; + OSPcre2 *id_pcre2; + OSPcre2 *status_pcre2; + OSPcre2 *hostname_pcre2; + OSPcre2 *program_name_pcre2; + OSPcre2 *extra_data_pcre2; + char *action; + + char *comment; /* description in the xml */ + char *info; + char *cve; + RuleInfoDetail *info_details; + ListRule *lists; + + char *if_sid; + char *if_level; + char *if_group; + + OSRegex *if_matched_regex; + OSMatch *if_matched_group; + int if_matched_sid; + + void *(*compiled_rule)(void *lf); + active_response **ar; + +} RuleInfo; + + +typedef struct _RuleNode { + RuleInfo *ruleinfo; + struct _RuleNode *next; + struct _RuleNode *child; +} RuleNode; + + +extern RuleInfo *currently_rule; + +RuleInfoDetail *zeroinfodetails(int type, const char *data); +int get_info_attributes(char **attributes, char **values); + +/* RuleInfo functions */ +RuleInfo *zerorulemember(int id, + int level, + int maxsize, + int frequency, + int timeframe, + int noalert, + int ignore_time, + int overwrite); + + +/** Rule_list Functions **/ + +/* create the rule list */ +void OS_CreateRuleList(void); + +/* Add rule information to the list */ +int OS_AddRule(RuleInfo *read_rule); + +/* Add rule information as a child */ +int OS_AddChild(RuleInfo *read_rule); + +/* Add an overwrite rule */ +int OS_AddRuleInfo(RuleNode *r_node, RuleInfo *newrule, int sid); + +/* Mark groups (if_matched_group) */ +int OS_MarkGroup(RuleNode *r_node, RuleInfo *orig_rule); + +/* Mark IDs (if_matched_sid) */ +int OS_MarkID(RuleNode *r_node, RuleInfo *orig_rule); + +/* Get first rule */ +RuleNode *OS_GetFirstRule(void); + +void Rules_OP_CreateRules(void); + +int Rules_OP_ReadRules(const char *rulefile); + +int AddHash_Rule(RuleNode *node); + +int _setlevels(RuleNode *node, int nnode); + +/** Definition of the internal rule IDS ** + ** These SIGIDs cannot be used ** + ** **/ + +#define STATS_MODULE 11 +#define FTS_MODULE 12 +#define SYSCHECK_MODULE 13 +#define HOSTINFO_MODULE 15 + +#define ROOTCHECK_MOD "rootcheck" +#define HOSTINFO_NEW "hostinfo_new" +#define HOSTINFO_MOD "hostinfo_modified" +#define SYSCHECK_MOD "syscheck_integrity_changed" +#define SYSCHECK_MOD2 "syscheck_integrity_changed_2nd" +#define SYSCHECK_MOD3 "syscheck_integrity_changed_3rd" +#define SYSCHECK_NEW "syscheck_new_entry" +#define SYSCHECK_DEL "syscheck_deleted" + +/* Global variables */ +extern int _max_freq; + +#endif /* _OS_RULES */ + diff --git a/src/analysisd/rules_list.c b/src/analysisd/rules_list.c new file mode 100644 index 000000000..f8bd8a713 --- /dev/null +++ b/src/analysisd/rules_list.c @@ -0,0 +1,414 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rules.h" + +/* Rulenode local */ +static RuleNode *rulenode; + +/* _OS_Addrule: Internal AddRule */ +static RuleNode *_OS_AddRule(RuleNode *_rulenode, RuleInfo *read_rule); +static int _AddtoRule(int sid, int level, int none, const char *group, + RuleNode *r_node, RuleInfo *read_rule); + + +/* Create the RuleList */ +void OS_CreateRuleList() +{ + rulenode = NULL; + return; +} + +/* Get first node from rule */ +RuleNode *OS_GetFirstRule() +{ + RuleNode *rulenode_pt = rulenode; + return (rulenode_pt); +} + +/* Search all rules, including children */ +static int _AddtoRule(int sid, int level, int none, const char *group, + RuleNode *r_node, RuleInfo *read_rule) +{ + int r_code = 0; + + /* If we don't have the first node, start from + * the beginning of the list + */ + if (!r_node) { + r_node = OS_GetFirstRule(); + } + + while (r_node) { + /* Check if the sigid matches */ + if (sid) { + if (r_node->ruleinfo->sigid == sid) { + /* Assign the category of this rule to the child + * as they must match + */ + read_rule->category = r_node->ruleinfo->category; + + /* If no context for rule, check if the parent has context + * and use that + */ + if (!read_rule->last_events && r_node->ruleinfo->last_events) { + read_rule->last_events = r_node->ruleinfo->last_events; + } + + r_node->child = + _OS_AddRule(r_node->child, read_rule); + return (1); + } + } + + /* Check if the group matches */ + else if (group) { + if (OS_WordMatch(group, r_node->ruleinfo->group) && + (r_node->ruleinfo->sigid != read_rule->sigid)) { + /* If no context for rule, check if the parent has context + * and use that + */ + if (!read_rule->last_events && r_node->ruleinfo->last_events) { + read_rule->last_events = r_node->ruleinfo->last_events; + } + + /* Loop over all rules until we find it */ + r_node->child = + _OS_AddRule(r_node->child, read_rule); + r_code = 1; + } + } + + /* Check if the level matches */ + else if (level) { + if ((r_node->ruleinfo->level >= level) && + (r_node->ruleinfo->sigid != read_rule->sigid)) { + r_node->child = + _OS_AddRule(r_node->child, read_rule); + r_code = 1; + } + } + + /* If we are not searching for the sid/group, the category must + * be the same + */ + else if (read_rule->category != r_node->ruleinfo->category) { + r_node = r_node->next; + continue; + } + + /* If none of them are set, add for the category */ + else { + /* Set the parent category to it */ + read_rule->category = r_node->ruleinfo->category; + r_node->child = + _OS_AddRule(r_node->child, read_rule); + return (1); + } + + /* Check if the child has a rule */ + if (r_node->child) { + if (_AddtoRule(sid, level, none, group, r_node->child, read_rule)) { + r_code = 1; + } + } + + r_node = r_node->next; + } + + return (r_code); +} + +/* Add a child */ +int OS_AddChild(RuleInfo *read_rule) +{ + if (!read_rule) { + merror("rules_list: Passing a NULL rule. Inconsistent state"); + return (1); + } + + /* Adding for if_sid */ + if (read_rule->if_sid) { + int val = 0; + const char *sid; + + sid = read_rule->if_sid; + + /* Loop to read all the rules (comma or space separated) */ + do { + int rule_id = 0; + if ((*sid == ',') || (*sid == ' ')) { + val = 0; + continue; + } else if ((isdigit((int)*sid)) || (*sid == '\0')) { + if (val == 0) { + rule_id = atoi(sid); + if (!_AddtoRule(rule_id, 0, 0, NULL, NULL, read_rule)) { + ErrorExit("rules_list: Signature ID '%d' not " + "found. Invalid 'if_sid'.", rule_id); + } + val = 1; + } + } else { + ErrorExit("rules_list: Signature ID must be an integer. " + "Exiting..."); + } + } while (*sid++ != '\0'); + } + + /* Adding for if_level */ + else if (read_rule->if_level) { + int ilevel = 0; + + ilevel = atoi(read_rule->if_level); + if (ilevel == 0) { + merror("%s: Invalid level (atoi)", ARGV0); + return (1); + } + + ilevel *= 100; + + if (!_AddtoRule(0, ilevel, 0, NULL, NULL, read_rule)) { + ErrorExit("rules_list: Level ID '%d' not " + "found. Invalid 'if_level'.", ilevel); + } + } + + /* Adding for if_group */ + else if (read_rule->if_group) { + if (!_AddtoRule(0, 0, 0, read_rule->if_group, NULL, read_rule)) { + ErrorExit("rules_list: Group '%s' not " + "found. Invalid 'if_group'.", read_rule->if_group); + } + } + + /* Just add based on the category */ + else { + if (!_AddtoRule(0, 0, 0, NULL, NULL, read_rule)) { + ErrorExit("rules_list: Category '%d' not " + "found. Invalid 'category'.", read_rule->category); + } + } + + /* done over here */ + return (0); +} + +/* Add a rule in the chain */ +static RuleNode *_OS_AddRule(RuleNode *_rulenode, RuleInfo *read_rule) +{ + RuleNode *tmp_rulenode = _rulenode; + + if (tmp_rulenode != NULL) { + int middle_insertion = 0; + RuleNode *prev_rulenode = NULL; + RuleNode *new_rulenode = NULL; + + while (tmp_rulenode != NULL) { + if (read_rule->level > tmp_rulenode->ruleinfo->level) { + middle_insertion = 1; + break; + } + prev_rulenode = tmp_rulenode; + tmp_rulenode = tmp_rulenode->next; + } + + new_rulenode = (RuleNode *)calloc(1, sizeof(RuleNode)); + + if (!new_rulenode) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + if (middle_insertion == 1) { + if (prev_rulenode == NULL) { + _rulenode = new_rulenode; + } else { + prev_rulenode->next = new_rulenode; + } + + new_rulenode->next = tmp_rulenode; + new_rulenode->ruleinfo = read_rule; + new_rulenode->child = NULL; + } else { + prev_rulenode->next = new_rulenode; + prev_rulenode->next->ruleinfo = read_rule; + prev_rulenode->next->next = NULL; + prev_rulenode->next->child = NULL; + } + } else { + _rulenode = (RuleNode *)calloc(1, sizeof(RuleNode)); + if (_rulenode == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + _rulenode->ruleinfo = read_rule; + _rulenode->next = NULL; + _rulenode->child = NULL; + } + + return (_rulenode); +} + +/* External AddRule */ +int OS_AddRule(RuleInfo *read_rule) +{ + rulenode = _OS_AddRule(rulenode, read_rule); + + return (0); +} + +/* Update rule info for overwritten ones */ +int OS_AddRuleInfo(RuleNode *r_node, RuleInfo *newrule, int sid) +{ + /* If no r_node is given, get first node */ + if (r_node == NULL) { + r_node = OS_GetFirstRule(); + } + + if (sid == 0) { + return (0); + } + + while (r_node) { + /* Check if the sigid matches */ + if (r_node->ruleinfo->sigid == sid) { + r_node->ruleinfo->level = newrule->level; + r_node->ruleinfo->maxsize = newrule->maxsize; + r_node->ruleinfo->frequency = newrule->frequency; + r_node->ruleinfo->timeframe = newrule->timeframe; + r_node->ruleinfo->ignore_time = newrule->ignore_time; + + r_node->ruleinfo->group = newrule->group; + r_node->ruleinfo->match = newrule->match; + r_node->ruleinfo->regex = newrule->regex; + r_node->ruleinfo->day_time = newrule->day_time; + r_node->ruleinfo->week_day = newrule->week_day; + r_node->ruleinfo->srcip = newrule->srcip; + r_node->ruleinfo->dstip = newrule->dstip; + r_node->ruleinfo->srcport = newrule->srcport; + r_node->ruleinfo->dstport = newrule->dstport; + r_node->ruleinfo->user = newrule->user; + r_node->ruleinfo->url = newrule->url; + r_node->ruleinfo->id = newrule->id; + r_node->ruleinfo->status = newrule->status; + r_node->ruleinfo->hostname = newrule->hostname; + r_node->ruleinfo->program_name = newrule->program_name; + r_node->ruleinfo->extra_data = newrule->extra_data; + r_node->ruleinfo->action = newrule->action; + r_node->ruleinfo->comment = newrule->comment; + r_node->ruleinfo->info = newrule->info; + r_node->ruleinfo->cve = newrule->cve; + r_node->ruleinfo->if_matched_regex = newrule->if_matched_regex; + r_node->ruleinfo->if_matched_group = newrule->if_matched_group; + r_node->ruleinfo->if_matched_sid = newrule->if_matched_sid; + r_node->ruleinfo->alert_opts = newrule->alert_opts; + r_node->ruleinfo->context_opts = newrule->context_opts; + r_node->ruleinfo->context = newrule->context; + r_node->ruleinfo->decoded_as = newrule->decoded_as; + r_node->ruleinfo->ar = newrule->ar; + r_node->ruleinfo->compiled_rule = newrule->compiled_rule; + if ((newrule->context_opts & SAME_DODIFF) && r_node->ruleinfo->last_events == NULL) { + r_node->ruleinfo->last_events = newrule->last_events; + } + + return (1); + } + + + /* Check if the child has a rule */ + if (r_node->child) { + if (OS_AddRuleInfo(r_node->child, newrule, sid)) { + return (1); + } + } + + r_node = r_node->next; + } + + return (0); +} + +/* Mark rules that match specific id (for if_matched_sid) */ +int OS_MarkID(RuleNode *r_node, RuleInfo *orig_rule) +{ + /* If no r_node is given, get first node */ + if (r_node == NULL) { + r_node = OS_GetFirstRule(); + } + + while (r_node) { + if (r_node->ruleinfo->sigid == orig_rule->if_matched_sid) { + /* If child does not have a list, create one */ + if (!r_node->ruleinfo->sid_prev_matched) { + r_node->ruleinfo->sid_prev_matched = OSList_Create(); + if (!r_node->ruleinfo->sid_prev_matched) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + } + + /* Assign the parent pointer to it */ + orig_rule->sid_search = r_node->ruleinfo->sid_prev_matched; + } + + /* Check if the child has a rule */ + if (r_node->child) { + OS_MarkID(r_node->child, orig_rule); + } + + r_node = r_node->next; + } + + return (0); +} + +/* Mark rules that match specific group (for if_matched_group) */ +int OS_MarkGroup(RuleNode *r_node, RuleInfo *orig_rule) +{ + /* If no r_node is given, get first node */ + if (r_node == NULL) { + r_node = OS_GetFirstRule(); + } + + while (r_node) { + if (OSMatch_Execute(r_node->ruleinfo->group, + strlen(r_node->ruleinfo->group), + orig_rule->if_matched_group)) { + unsigned int rule_g = 0; + if (r_node->ruleinfo->group_prev_matched) { + while (r_node->ruleinfo->group_prev_matched[rule_g]) { + rule_g++; + } + } + + os_realloc(r_node->ruleinfo->group_prev_matched, + (rule_g + 2)*sizeof(OSList *), + r_node->ruleinfo->group_prev_matched); + + r_node->ruleinfo->group_prev_matched[rule_g] = NULL; + r_node->ruleinfo->group_prev_matched[rule_g + 1] = NULL; + + /* Set the size */ + r_node->ruleinfo->group_prev_matched_sz = rule_g + 1; + + r_node->ruleinfo->group_prev_matched[rule_g] = + orig_rule->group_search; + } + + /* Check if the child has a rule */ + if (r_node->child) { + OS_MarkGroup(r_node->child, orig_rule); + } + + r_node = r_node->next; + } + + return (0); +} + diff --git a/src/analysisd/schemas/md5_ignore_sqlite3.schema b/src/analysisd/schemas/md5_ignore_sqlite3.schema new file mode 100644 index 000000000..5245f7fad --- /dev/null +++ b/src/analysisd/schemas/md5_ignore_sqlite3.schema @@ -0,0 +1,6 @@ +CREATE TABLE files ( + md5sum VARCHAR(32), + file VARCHAR(256), + time DATETIME +); +CREATE UNIQUE INDEX files_idx ON files(md5sum); diff --git a/src/analysisd/stats.c b/src/analysisd/stats.c new file mode 100644 index 000000000..19f7d2926 --- /dev/null +++ b/src/analysisd/stats.c @@ -0,0 +1,465 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "analysisd.h" +#include "stats.h" +#include "rules.h" +#include "error_messages/error_messages.h" +#include "headers/file_op.h" +#include "alerts/alerts.h" +#include "headers/debug_op.h" + +/* Global definition */ +char __stats_comment[192]; + +static const char *(weekdays[]) = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday" + }; + +static const char *(l_month[]) = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" + }; + +/* Global variables */ + +/* Hour 25 is internally used */ +static int _RWHour[7][25]; +static int _CWHour[7][25]; + +static int _RHour[25]; +static int _CHour[25]; + +static int _cignorehour = 0; +static int _fired = 0; +static int _daily_errors = 0; +static int maxdiff = 0; +static int mindiff = 0; +static int percent_diff = 20; + +/* Last msgs, to avoid floods */ +static char *_lastmsg; +static char *_prevlast; +static char *_pprevlast; + + +static void print_totals(void) +{ + int i, totals = 0; + char logfile[OS_FLSIZE + 1]; + FILE *flog; + + /* Create the path for the logs */ + snprintf(logfile, OS_FLSIZE, "%s/%d/", STATSAVED, prev_year); + if (IsDir(logfile) == -1) + if (mkdir(logfile, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, logfile, errno, strerror(errno)); + return; + } + + snprintf(logfile, OS_FLSIZE, "%s/%d/%s", STATSAVED, prev_year, prev_month); + + if (IsDir(logfile) == -1) + if (mkdir(logfile, 0770) == -1) { + merror(MKDIR_ERROR, ARGV0, logfile, errno, strerror(errno)); + return; + } + + /* Create the logfile name */ + snprintf(logfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + STATSAVED, + prev_year, + prev_month, + "totals", + today); + + flog = fopen(logfile, "a"); + if (!flog) { + merror(FOPEN_ERROR, ARGV0, logfile, errno, strerror(errno)); + return; + } + + /* Print the hourly stats */ + for (i = 0; i <= 23; i++) { + fprintf(flog, "Hour totals - %d:%d\n", i, _CHour[i]); + totals += _CHour[i]; + } + fprintf(flog, "Total events for day:%d\n", totals); + + fclose(flog); +} + +/* Return the parameter (event_number + 20 % of it) + * If event_number < mindiff, return mindiff + * If event_number > maxdiff, return maxdiff + */ +static int gethour(int event_number) +{ + int event_diff; + + event_diff = (event_number * percent_diff) / 100; + event_diff++; + + if (event_diff < mindiff) { + return (event_number + mindiff); + } else if (event_diff > maxdiff) { + return (event_number + maxdiff); + } + + return (event_number + event_diff); +} + +/* Update_Hour: done daily */ +void Update_Hour() +{ + int i, j; + int inter; + + /* Print total number of logs received per hour */ + print_totals(); + + /* Hourly update */ + _RHour[24]++; + inter = _RHour[24]; + if (inter > 7) { + inter = 7; + } + + for (i = 0; i <= 24; i++) { + char _hourly[128]; /* _hourly file */ + + FILE *fp; + + if (i != 24) { + /* If saved hourly = 0, just copy the current hourly rate */ + if (_CHour[i] == 0) { + continue; + } + + if (_RHour[i] == 0) { + _RHour[i] = _CHour[i] + 20; + } + + else { + /* If we had too many errors this day */ + if (_daily_errors >= 3) { + _RHour[i] = (((3 * _CHour[i]) + (inter * _RHour[i])) / (inter + 3)) + 25; + } + + else { + /* The average is going to be the number of interactions + + * the current hourly rate, divided by 4 */ + _RHour[i] = ((_CHour[i] + (inter * _RHour[i])) / (inter + 1)) + 5; + } + } + } + + snprintf(_hourly, 128, "%s/%d", STATQUEUE, i); + fp = fopen(_hourly, "w"); + if (fp) { + fprintf(fp, "%d", _RHour[i]); + fclose(fp); + } + + else { + merror(FOPEN_ERROR, "logstats", _hourly, errno, strerror(errno)); + } + + _CHour[i] = 0; /* Zero the current hour */ + } + + /* Weekly */ + for (i = 0; i <= 6; i++) { + char _weekly[128]; + FILE *fp; + + _CWHour[i][24]++; + inter = _CWHour[i][24]; + if (inter > 7) { + inter = 7; + } + + for (j = 0; j <= 24; j++) { + if (j != 24) { + if (_CWHour[i][j] == 0) { + continue; + } + + if (_RWHour[i][j] == 0) { + _RWHour[i][j] = _CWHour[i][j] + 20; + } + + else { + if (_daily_errors >= 3) { + _RWHour[i][j] = (((3 * _CWHour[i][j]) + (inter * _RWHour[i][j])) / (inter + 3)) + 25; + } else { + _RWHour[i][j] = ((_CWHour[i][j] + (inter * _RWHour[i][j])) / (inter + 1)) + 5; + } + } + } + + snprintf(_weekly, 128, "%s/%d/%d", STATWQUEUE, i, j); + fp = fopen(_weekly, "w"); + if (fp) { + fprintf(fp, "%d", _RWHour[i][j]); + fclose(fp); + } else { + merror(FOPEN_ERROR, "logstats", _weekly, errno, strerror(errno)); + } + + _CWHour[i][j] = 0; + } + } + + _daily_errors = 0; + return; +} + +/* Check Hourly stats */ +int Check_Hour() +{ + _CHour[__crt_hour]++; + _CWHour[__crt_wday][__crt_hour]++; + + if (_RHour[24] <= 2) { + return (0); + } + + /* Checking if any message was already fired for this hour */ + if ((_daily_errors >= 3) || ((_fired == 1) && (_cignorehour == __crt_hour))) { + return (0); + } + + else if (_cignorehour != __crt_hour) { + _cignorehour = __crt_hour; + _fired = 0; + } + + /* Check if passed the threshold */ + if (_RHour[__crt_hour] != 0) { + if (_CHour[__crt_hour] > (_RHour[__crt_hour])) { + if (_CHour[__crt_hour] > (gethour(_RHour[__crt_hour]))) { + /* snprintf will null terminate */ + snprintf(__stats_comment, 191, + "The average number of logs" + " between %d:00 and %d:00 is %d. We " + "reached %d.", __crt_hour, __crt_hour + 1, + _RHour[__crt_hour], _CHour[__crt_hour]); + + + _fired = 1; + _daily_errors++; + return (1); + } + } + } + + /* We need to have at least 3 days of stats */ + if (_RWHour[__crt_wday][24] <= 2) { + return (0); + } + + /* Check for the hour during a specific day of the week */ + if (_RWHour[__crt_wday][__crt_hour] != 0) { + if (_CWHour[__crt_wday][__crt_hour] > _RWHour[__crt_wday][__crt_hour]) { + if (_CWHour[__crt_wday][__crt_hour] > + gethour(_RWHour[__crt_wday][__crt_hour])) { + snprintf(__stats_comment, 191, + "The average number of logs" + " between %d:00 and %d:00 on %s is %d. We" + " reached %d.", __crt_hour, __crt_hour + 1, + weekdays[__crt_wday], + _RWHour[__crt_wday][__crt_hour], + _CWHour[__crt_wday][__crt_hour]); + + + _fired = 1; + _daily_errors++; + return (1); + } + } + } + return (0); +} + +/* Start hourly stats and other necessary variables */ +int Start_Hour() +{ + int i = 0, j = 0; + struct tm *p; + + /* Current time */ + p = localtime(&c_time); + + /* Other global variables */ + _fired = 0; + _cignorehour = 0; + + today = p->tm_mday; + thishour = p->tm_hour; + prev_year = p->tm_year + 1900; + strncpy(prev_month, l_month[p->tm_mon], 3); + prev_month[3] = '\0'; + + /* Clear some memory */ + memset(__stats_comment, '\0', 192); + + /* Get maximum/minimum diffs */ + maxdiff = getDefine_Int("analysisd", + "stats_maxdiff", + 10, 999999); + + mindiff = getDefine_Int("analysisd", + "stats_mindiff", + 10, 999999); + + percent_diff = getDefine_Int("analysisd", + "stats_percent_diff", + 5, 9999); + + /* Last three messages + * They are used to keep track of the last + * messages received to avoid floods + */ + _lastmsg = NULL; + _prevlast = NULL; + _pprevlast = NULL; + + /* They should not be null */ + os_strdup(" ", _lastmsg); + os_strdup(" ", _prevlast); + os_strdup(" ", _pprevlast); + + /* Create the stat queue directories */ + if (IsDir(STATWQUEUE) == -1) { + if (mkdir(STATWQUEUE, 0770) == -1) { + merror("%s: logstat: Unable to create stat queue: %s", + ARGV0, STATWQUEUE); + return (-1); + } + } + + if (IsDir(STATQUEUE) == -1) { + if (mkdir(STATQUEUE, 0770) == -1) { + merror("%s: logstat: Unable to create stat queue: %s", + ARGV0, STATQUEUE); + return (-1); + } + } + + /* Create store dir */ + if (IsDir(STATSAVED) == -1) { + if (mkdir(STATSAVED, 0770) == -1) { + merror("%s: logstat: Unable to create stat directory: %s", + ARGV0, STATSAVED); + return (-1); + } + } + + /* Create hourly directory (24 hour is the stats) */ + for (i = 0; i <= 24; i++) { + char _hourly[128]; + snprintf(_hourly, 128, "%s/%d", STATQUEUE, i); + + _CHour[i] = 0; + if (File_DateofChange(_hourly) < 0) { + _RHour[i] = 0; + } + + else { + FILE *fp; + fp = fopen(_hourly, "r"); + if (!fp) { + _RHour[i] = 0; + } else { + if (fscanf(fp, "%d", &_RHour[i]) <= 0) { + _RHour[i] = 0; + } + + if (_RHour[i] < 0) { + _RHour[i] = 0; + } + fclose(fp); + } + } + } + + /* Create weekly/hourly directories */ + for (i = 0; i <= 6; i++) { + char _weekly[128]; + snprintf(_weekly, 128, "%s/%d", STATWQUEUE, i); + if (IsDir(_weekly) == -1) + if (mkdir(_weekly, 0770) == -1) { + merror("%s: logstat: Unable to create stat queue: %s", + ARGV0, _weekly); + return (-1); + } + + for (j = 0; j <= 24; j++) { + _CWHour[i][j] = 0; + snprintf(_weekly, 128, "%s/%d/%d", STATWQUEUE, i, j); + if (File_DateofChange(_weekly) < 0) { + _RWHour[i][j] = 0; + } else { + FILE *fp; + fp = fopen(_weekly, "r"); + if (!fp) { + _RWHour[i][j] = 0; + } else { + if (fscanf(fp, "%d", &_RWHour[i][j]) <= 0) { + _RWHour[i][j] = 0; + } + + if (_RWHour[i][j] < 0) { + _RWHour[i][j] = 0; + } + fclose(fp); + } + } + } + } + return (0); +} + +/* Check if the message received is repeated to avoid + * floods of the same message + */ +int LastMsg_Stats(const char *log) +{ + if (strcmp(log, _lastmsg) == 0) { + return (1); + } + + else if (strcmp(log, _prevlast) == 0) { + return (1); + } + + else if (strcmp(log, _pprevlast) == 0) { + return (1); + } + + return (0); +} + +/* If the message is not repeated, rearrange the last + * received messages + */ +void LastMsg_Change(const char *log) +{ + /* Remove the last one */ + free(_pprevlast); + + /* Move the second to third and the last to second */ + _pprevlast = _prevlast; + _prevlast = _lastmsg; + + os_strdup(log, _lastmsg); + return; +} + diff --git a/src/analysisd/stats.h b/src/analysisd/stats.h new file mode 100644 index 000000000..be1503b04 --- /dev/null +++ b/src/analysisd/stats.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _STAT__H +#define _STAT__H + +void LastMsg_Change(const char *log); +int LastMsg_Stats(const char *log); + +extern char __stats_comment[192]; + +void Update_Hour(void); +int Check_Hour(void); +int Start_Hour(void); + +#endif /* _STAT__H */ + diff --git a/src/analysisd/testrule.c b/src/analysisd/testrule.c new file mode 100644 index 000000000..ef6e34d20 --- /dev/null +++ b/src/analysisd/testrule.c @@ -0,0 +1,625 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef ARGV0 +#undef ARGV0 +#define ARGV0 "openarmor-testrule" +#endif + +#include "shared.h" +#include "alerts/alerts.h" +#include "alerts/getloglocation.h" +#include "os_execd/execd.h" +#include "os_regex/os_regex.h" +#include "os_net/os_net.h" +#include "active-response.h" +#include "config.h" +#include "rules.h" +#include "stats.h" +#include "eventinfo.h" +#include "accumulator.h" +#include "analysisd.h" +#include "fts.h" +#include "cleanevent.h" + +/** Internal Functions **/ +void OS_ReadMSG(char *ut_str); + +/* Analysisd function */ +RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node); + +void DecodeEvent(Eventinfo *lf); + +/* Print help statement */ +__attribute__((noreturn)) +static void help_logtest(void) +{ + print_header(); + print_out(" %s: -[Vhdtva] [-c config] [-D dir] [-U rule:alert:decoder]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -a Alerts output"); + print_out(" -v Verbose (full) output/rule debugging"); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" -U Unit test. Refer to contrib/openarmor-testing/runtests.py"); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int test_config = 0; + int c = 0; + char *ut_str = NULL; + const char *dir = DEFAULTDIR; + const char *cfg = DEFAULTCPATH; + const char *user = USER; + const char *group = GROUPGLOBAL; + uid_t uid; + gid_t gid; + int quiet = 0; + + /* Set the name */ + OS_SetName(ARGV0); + + thishour = 0; + today = 0; + prev_year = 0; + full_output = 0; + alert_only = 0; + + active_responses = NULL; + memset(prev_month, '\0', 4); + +#ifdef LIBGEOIP_ENABLED + extern GeoIP *geoipdb; + geoipdb = NULL; +#endif + + while ((c = getopt(argc, argv, "VatvdhU:D:c:q")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 't': + test_config = 1; + break; + case 'h': + help_logtest(); + break; + case 'd': + nowDebug(); + break; + case 'U': + if (!optarg) { + ErrorExit("%s: -U needs an argument", ARGV0); + } + ut_str = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 'a': + alert_only = 1; + break; + case 'q': + quiet = 1; + break; + case 'v': + full_output = 1; + break; + default: + help_logtest(); + break; + } + } + + /* Read configuration file */ + if (GlobalConf(cfg) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + debug1(READ_CONFIG, ARGV0); + +#ifdef LIBGEOIP_ENABLED + Config.geoip_jsonout = getDefine_Int("analysisd", "geoip_jsonout", 0, 1); + + /* Opening GeoIP DB */ + if(Config.geoipdb_file) { + geoipdb = GeoIP_open(Config.geoipdb_file, GEOIP_INDEX_CACHE); + if (geoipdb == NULL) + { + merror("%s: Unable to open GeoIP database from: %s (disabling GeoIP).", ARGV0, Config.geoipdb_file); + } + } +#endif + + /* Get server hostname */ + memset(__shost, '\0', 512); + if (gethostname(__shost, 512 - 1) != 0) { + strncpy(__shost, openarmor_SERVER, 512 - 1); + } else { + char *_ltmp; + + /* Remove domain part if available */ + _ltmp = strchr(__shost, '.'); + if (_ltmp) { + *_ltmp = '\0'; + } + } + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Set the group */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + + Config.decoder_order_size = (size_t)getDefine_Int("analysisd", "decoder_order_size", 8, MAX_DECODER_ORDER_SIZE); + + + /* + * Anonymous Section: Load rules, decoders, and lists + * + * As lists require two pass loading of rules that make use of list lookups + * are created with blank database structs, and need to be filled in after + * completion of all rules and lists. + */ + { + { + /* Load decoders */ + /* Initialize the decoders list */ + OS_CreateOSDecoderList(); + + if (!Config.decoders) { + /* Legacy loading */ + /* Read decoders */ + if (!ReadDecodeXML("etc/decoder.xml")) { + ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER); + } + + /* Read local ones */ + c = ReadDecodeXML("etc/local_decoder.xml"); + if (!c) { + if ((c != -2)) { + ErrorExit(CONFIG_ERROR, ARGV0, XML_LDECODER); + } + } else { + verbose("%s: INFO: Reading local decoder file.", ARGV0); + } + } else { + /* New loaded based on file specified in openarmor.conf */ + char **decodersfiles; + decodersfiles = Config.decoders; + while ( decodersfiles && *decodersfiles) { + + if(!quiet) { + verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles); + } + if (!ReadDecodeXML(*decodersfiles)) { + ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles); + } + + free(*decodersfiles); + decodersfiles++; + } + } + + /* Load decoders */ + SetDecodeXML(); + } + { + /* Load Lists */ + /* Initialize the lists of list struct */ + Lists_OP_CreateLists(); + /* Load each list into list struct */ + { + char **listfiles; + listfiles = Config.lists; + while (listfiles && *listfiles) { + verbose("%s: INFO: Reading the lists file: '%s'", ARGV0, *listfiles); + if (Lists_OP_LoadList(*listfiles) < 0) { + ErrorExit(LISTS_ERROR, ARGV0, *listfiles); + } + free(*listfiles); + listfiles++; + } + free(Config.lists); + Config.lists = NULL; + } + } + { + /* Load Rules */ + /* Create the rules list */ + Rules_OP_CreateRules(); + + /* Read the rules */ + { + char **rulesfiles; + rulesfiles = Config.includes; + while (rulesfiles && *rulesfiles) { + debug1("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles); + if (Rules_OP_ReadRules(*rulesfiles) < 0) { + ErrorExit(RULES_ERROR, ARGV0, *rulesfiles); + } + + free(*rulesfiles); + rulesfiles++; + } + + free(Config.includes); + Config.includes = NULL; + } + + /* Find all rules with that require list lookups and attache the + * the correct list struct to the rule. This keeps rules from + * having to search thought the list of lists for the correct file + * during rule evaluation. + */ + OS_ListLoadRules(); + } + } + + /* Fix the levels/accuracy */ + { + int total_rules; + RuleNode *tmp_node = OS_GetFirstRule(); + + total_rules = _setlevels(tmp_node, 0); + debug1("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules); + } + + /* Creating a rules hash (for reading alerts from other servers) */ + { + RuleNode *tmp_node = OS_GetFirstRule(); + Config.g_rules_hash = OSHash_Create(); + if (!Config.g_rules_hash) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + AddHash_Rule(tmp_node); + } + + if (test_config == 1) { + exit(0); + } + + /* Set the user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, getpid()); + + /* Going to main loop */ + OS_ReadMSG(ut_str); + + exit(0); +} + +/* Receive the messages (events) and analyze them */ +__attribute__((noreturn)) +void OS_ReadMSG(char *ut_str) +{ + char msg[OS_MAXSTR + 1]; + int exit_code = 0; + char *ut_alertlevel = NULL; + char *ut_rulelevel = NULL; + char *ut_decoder_name = NULL; + + if (ut_str) { + /* XXX Break apart string */ + ut_rulelevel = ut_str; + ut_alertlevel = strchr(ut_rulelevel, ':'); + if (!ut_alertlevel) { + ErrorExit("%s: -U requires the matching format to be " + "\"::\"", ARGV0); + } else { + *ut_alertlevel = '\0'; + ut_alertlevel++; + } + ut_decoder_name = strchr(ut_alertlevel, ':'); + if (!ut_decoder_name) { + ErrorExit("%s: -U requires the matching format to be " + "\"::\"", ARGV0); + } else { + *ut_decoder_name = '\0'; + ut_decoder_name++; + } + } + + RuleInfoDetail *last_info_detail; + Eventinfo *lf; + + /* Null global pointer to current rule */ + currently_rule = NULL; + + /* Create the event list */ + OS_CreateEventList(Config.memorysize); + + /* Initiate the FTS list */ + if (!FTS_Init()) { + ErrorExit(FTS_LIST_ERROR, ARGV0); + } + + /* Initialize the Accumulator */ + if (!Accumulate_Init()) { + merror("accumulator: ERROR: Initialization failed"); + exit(1); + } + + __crt_ftell = 1; + + /* Get current time before starting */ + c_time = time(NULL); + + /* Do some cleanup */ + memset(msg, '\0', OS_MAXSTR + 1); + + if (!alert_only) { + print_out("%s: Type one log per line.\n", ARGV0); + } + + /* Daemon loop */ + while (1) { + lf = (Eventinfo *)calloc(1, sizeof(Eventinfo)); + os_calloc(Config.decoder_order_size, sizeof(char*), lf->fields); + + + /* This shouldn't happen */ + if (lf == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Fix the msg */ + snprintf(msg, 15, "1:stdin:"); + + /* Receive message from queue */ + if (fgets(msg + 8, OS_MAXSTR - 8, stdin)) { + RuleNode *rulenode_pt; + + /* Get the time we received the event */ + c_time = time(NULL); + + /* Remov newline */ + if (msg[strlen(msg) - 1] == '\n') { + msg[strlen(msg) - 1] = '\0'; + } + + /* Make sure we ignore blank lines */ + if (strlen(msg) < 10) { + continue; + } + + if (!alert_only) { + print_out("\n"); + } + + /* Default values for the log info */ + Zero_Eventinfo(lf); + + /* Clean the msg appropriately */ + if (OS_CleanMSG(msg, lf) < 0) { + merror(IMSG_ERROR, ARGV0, msg); + + Free_Eventinfo(lf); + + continue; + } + + /* Current rule must be null in here */ + currently_rule = NULL; + + /*** Run decoders ***/ + /* Get log size */ + lf->size = strlen(lf->log); + + /* Decode event */ + DecodeEvent(lf); + + /* Run accumulator */ + if ( lf->decoder_info->accumulate == 1 ) { + print_out("\n**ACCUMULATOR: LEVEL UP!!**\n"); + lf = Accumulate(lf); + } + + /* Loop over all the rules */ + rulenode_pt = OS_GetFirstRule(); + if (!rulenode_pt) { + ErrorExit("%s: Rules in an inconsistent state. Exiting.", + ARGV0); + } + +#ifdef TESTRULE + if (full_output && !alert_only) { + print_out("\n**Rule debugging:"); + } +#endif + + do { + if (lf->decoder_info->type == openarmor_ALERT) { + if (!lf->generated_rule) { + break; + } + + /* Process the alert */ + currently_rule = lf->generated_rule; + } + + /* The categories must match */ + else if (rulenode_pt->ruleinfo->category != + lf->decoder_info->type) { + continue; + } + + /* Check each rule */ + else if ((currently_rule = OS_CheckIfRuleMatch(lf, rulenode_pt)) + == NULL) { + continue; + } + +#ifdef TESTRULE + if (!alert_only) { + const char *(ruleinfodetail_text[]) = {"Text", "Link", "CVE", "OSVDB", "BUGTRACKID"}; + print_out("\n**Phase 3: Completed filtering (rules)."); + print_out(" Rule id: '%d'", currently_rule->sigid); + print_out(" Level: '%d'", currently_rule->level); + print_out(" Description: '%s'", currently_rule->comment); + for (last_info_detail = currently_rule->info_details; last_info_detail != NULL; last_info_detail = last_info_detail->next) { + print_out(" Info - %s: '%s'", ruleinfodetail_text[last_info_detail->type], last_info_detail->data); + } + } +#endif + + /* Ignore level 0 */ + if (currently_rule->level == 0) { + break; + } + + /* Check ignore time */ + if (currently_rule->ignore_time) { + if (currently_rule->time_ignored == 0) { + currently_rule->time_ignored = lf->time; + } + /* If the current time - the time the rule was ignored + * is less than the time it should be ignored, + * do not alert again + */ + else if ((lf->time - currently_rule->time_ignored) + < currently_rule->ignore_time) { + break; + } else { + currently_rule->time_ignored = 0; + } + } + + /* Pointer to the rule that generated it */ + lf->generated_rule = currently_rule; + + + /* Check if we should ignore it */ + if (currently_rule->ckignore && IGnore(lf)) { + lf->generated_rule = NULL; + break; + } + + /* Check if we need to add to ignore list */ + if (currently_rule->ignore) { + AddtoIGnore(lf); + } + + /* Log the alert if configured to */ + if (currently_rule->alert_opts & DO_LOGALERT) { + if (alert_only) { + OS_LogOutput(lf); + __crt_ftell++; + } else { + print_out("**Alert to be generated.\n\n"); + } + } + + /* Copy the structure to the state memory of if_matched_sid */ + if (currently_rule->sid_prev_matched) { + if (!OSList_AddData(currently_rule->sid_prev_matched, lf)) { + merror("%s: Unable to add data to sig list.", ARGV0); + } else { + lf->sid_node_to_delete = + currently_rule->sid_prev_matched->last_node; + } + } + + /* Group list */ + else if (currently_rule->group_prev_matched) { + unsigned int i = 0; + + while (i < currently_rule->group_prev_matched_sz) { + if (!OSList_AddData( + currently_rule->group_prev_matched[i], + lf)) { + merror("%s: Unable to add data to grp list.", ARGV0); + } + i++; + } + } + + OS_AddEvent(lf); + break; + + } while ((rulenode_pt = rulenode_pt->next) != NULL); + + if (ut_str) { + /* Set up exit code if we are doing unit testing */ + char holder[1024]; + holder[1] = '\0'; + exit_code = 3; + print_out("lf->decoder_info->name: '%s'", lf->decoder_info->name); + print_out("ut_decoder_name : '%s'", ut_decoder_name); + if (lf->decoder_info->name != NULL && strcasecmp(ut_decoder_name, lf->decoder_info->name) == 0) { + exit_code--; + + if (!currently_rule) { + merror("%s: currently_rule not set!", ARGV0); + exit(-1); + } + snprintf(holder, 1023, "%d", currently_rule->sigid); + if (strcasecmp(ut_rulelevel, holder) == 0) { + exit_code--; + snprintf(holder, 1023, "%d", currently_rule->level); + if (strcasecmp(ut_alertlevel, holder) == 0) { + exit_code--; + printf("%d\n", exit_code); + } + } + } else if (lf->decoder_info->name != NULL) { + print_out("decoder matched : '%s'", lf->decoder_info->name); + print_out("decoder expected: '%s'", ut_decoder_name); + } else { + print_out("decoder matched : 'NULL'"); + } + } + + /* Only clear the memory if the eventinfo was not + * added to the stateful memory + * -- message is free inside clean event -- + */ + if (lf->generated_rule == NULL) { + Free_Eventinfo(lf); + } + + } else { + exit(exit_code); + } + } + exit(exit_code); +} diff --git a/src/client-agent/COPYRIGHT b/src/client-agent/COPYRIGHT new file mode 100644 index 000000000..cc9057fd3 --- /dev/null +++ b/src/client-agent/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (C) 2009 Trend Micro Inc. + All rights reserved. + This program is a free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License (version 2) as published by the FSF - Free Software + Foundation + +openarmor HIDS, openarmor-agent +Available at http://www.theopenarmor.org/hids/ diff --git a/src/client-agent/VERSION b/src/client-agent/VERSION new file mode 100644 index 000000000..be5863417 --- /dev/null +++ b/src/client-agent/VERSION @@ -0,0 +1 @@ +0.3 diff --git a/src/client-agent/agentd.c b/src/client-agent/agentd.c new file mode 100644 index 000000000..2ff49a682 --- /dev/null +++ b/src/client-agent/agentd.c @@ -0,0 +1,153 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentd.h" +#include "os_net/os_net.h" + + +/* Start the agent daemon */ +void AgentdStart(const char *dir, int uid, int gid, const char *user, const char *group) +{ + int rc = 0; + int maxfd = 0; + fd_set fdset; + struct timeval fdtimeout; + + extern agent *agt; + + available_server = 0; + + /* Initial random numbers must happen before chroot */ + srandom_init(); + + /* Going Daemon */ + if (!run_foreground) { + nowDaemon(); + goDaemon(); + } + + /* Set group ID */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + /* Create the queue and read from it. Exit if fails. */ + if ((agt->m_queue = StartMQ(DEFAULTQUEUE, READ)) < 0) { + ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); + } + + maxfd = agt->m_queue; + agt->sock = -1; + + /* Create PID file */ + if (CreatePID(ARGV0, getpid()) < 0) { + merror(PID_ERROR, ARGV0); + } + + /* Read private keys */ + verbose(ENC_READ, ARGV0); + + OS_ReadKeys(&keys); + OS_StartCounter(&keys); + + os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, + agt->profile); + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + random(); + + /* Connect UDP */ + rc = 0; + while (rc < agt->rip_id) { + verbose("%s: INFO: Server %d: %s", ARGV0, rc+1, agt->rip[rc]); + rc++; + } + + /* Try to connect to the server */ + if (!connect_server(0)) { + ErrorExit(UNABLE_CONN, ARGV0); + } + + /* Set max fd for select */ + if (agt->sock > maxfd) { + maxfd = agt->sock; + } + + /* Connect to the execd queue */ + if (agt->execdq == 0) { + if ((agt->execdq = StartMQ(EXECQUEUE, WRITE)) < 0) { + merror("%s: INFO: Unable to connect to the active response " + "queue (disabled).", ARGV0); + agt->execdq = -1; + } + } + + /* Try to connect to server */ + os_setwait(); + + start_agent(1); + + os_delwait(); + + /* Send integrity message for agent configs */ + intcheck_file(openarmorCONF, dir); + intcheck_file(openarmor_DEFINES, dir); + + /* Send first notification */ + run_notify(); + + /* Maxfd must be higher socket +1 */ + maxfd++; + + /* Monitor loop */ + while (1) { + /* Monitor all available sockets from here */ + FD_ZERO(&fdset); + FD_SET(agt->sock, &fdset); + FD_SET(agt->m_queue, &fdset); + + fdtimeout.tv_sec = 1; + fdtimeout.tv_usec = 0; + + /* Continuously send notifications */ + run_notify(); + + /* Wait with a timeout for any descriptor */ + rc = select(maxfd, &fdset, NULL, NULL, &fdtimeout); + if (rc == -1) { + ErrorExit(SELECT_ERROR, ARGV0, errno, strerror(errno)); + } else if (rc == 0) { + continue; + } + + /* For the receiver */ + if (FD_ISSET(agt->sock, &fdset)) { + receive_msg(); + } + + /* For the forwarder */ + if (FD_ISSET(agt->m_queue, &fdset)) { + EventForward(); + } + } +} + diff --git a/src/client-agent/agentd.h b/src/client-agent/agentd.h new file mode 100644 index 000000000..912c73e5c --- /dev/null +++ b/src/client-agent/agentd.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __AGENTD_H +#define __AGENTD_H + +#include "config/config.h" +#include "config/client-config.h" + +/*** Function Prototypes ***/ + +/* Client configuration */ +int ClientConf(const char *cfgfile); + +/* Agentd init function */ +void AgentdStart(const char *dir, int uid, int gid, const char *user, const char *group) __attribute__((noreturn)); + +/* Event Forwarder */ +void *EventForward(void); + +/* Receiver messages */ +void *receive_msg(void); + +/* Receiver messages for Windows */ +void *receiver_thread(void *none); + +/* Send integrity checking information about a file to the server */ +int intcheck_file(const char *file_name, const char *dir); + +/* Send message to server */ +int send_msg(int agentid, const char *msg); + +/* Extract the shared files */ +char *getsharedfiles(void); + +/* Initialize handshake to server */ +void start_agent(int is_startup); + +/* Connect to the server */ +int connect_server(int initial_id); + +/* Notify server */ +void run_notify(void); + +/*** Global variables ***/ + +/* Global variables. Only modified during startup. */ + +#include "shared.h" +#include "sec.h" + +extern time_t available_server; +extern int run_foreground; +extern keystore keys; +extern agent *agt; + +#endif /* __AGENTD_H */ + diff --git a/src/client-agent/config.c b/src/client-agent/config.c new file mode 100644 index 000000000..a16d279fe --- /dev/null +++ b/src/client-agent/config.c @@ -0,0 +1,42 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_xml/os_xml.h" +#include "os_regex/os_regex.h" +#include "os_net/os_net.h" +#include "agentd.h" + +/* Global variables */ +time_t available_server; +int run_foreground; +keystore keys; +agent *agt; + + +/* Read the config file (for the remote client) */ +int ClientConf(const char *cfgfile) +{ + int modules = 0; + agt->port = DEFAULT_SECURE; + agt->rip = NULL; + agt->lip = NULL; + agt->rip_id = 0; + agt->execdq = 0; + agt->profile = NULL; + + modules |= CCLIENT; + + if (ReadConfig(modules, cfgfile, agt, NULL) < 0) { + return (OS_INVALID); + } + + return (1); +} + diff --git a/src/client-agent/event-forward.c b/src/client-agent/event-forward.c new file mode 100644 index 000000000..f586dd56c --- /dev/null +++ b/src/client-agent/event-forward.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentd.h" +#include "os_net/os_net.h" +#include "sec.h" + + +/* Receive a message locally on the agent and forward it to the manager */ +void *EventForward() +{ + + extern agent *agt; + + ssize_t recv_b; + char msg[OS_MAXSTR + 1]; + + /* Initialize variables */ + msg[0] = '\0'; + msg[OS_MAXSTR] = '\0'; + + while ((recv_b = recv(agt->m_queue, msg, OS_MAXSTR, MSG_DONTWAIT)) > 0) { + msg[recv_b] = '\0'; + + send_msg(0, msg); + + run_notify(); + } + + return (NULL); +} + diff --git a/src/client-agent/intcheck_op.c b/src/client-agent/intcheck_op.c new file mode 100644 index 000000000..395af7d7f --- /dev/null +++ b/src/client-agent/intcheck_op.c @@ -0,0 +1,71 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentd.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/sha1/sha1_op.h" + + +/* Send integrity checking information about a file to the server */ +int intcheck_file(const char *file_name, const char *dir) +{ + struct stat statbuf; + os_md5 mf_sum = ""; + os_sha1 sf_sum = ""; + char newsum[912 + 1]; + + newsum[0] = '\0'; + newsum[912] = '\0'; + + /* Stat the file */ +#ifdef WIN32 + if (stat(file_name, &statbuf) < 0) +#else + if (lstat(file_name, &statbuf) < 0) +#endif + { + snprintf(newsum, 911, "%c:%s:-1 %s%s", SYSCHECK_MQ, SYSCHECK, + dir, file_name); + send_msg(0, newsum); + + return (1); + } + + /* Generate new checksum */ +#ifdef WIN32 + if (S_ISREG(statbuf.st_mode)) +#else + if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) +#endif + { + /* Generate SHA-1 of the file */ + if (OS_SHA1_File(file_name, sf_sum, OS_TEXT) < 0) { + strncpy(sf_sum, "xxx", 4); + } + + /* Generate MD5 of the file */ + if (OS_MD5_File(file_name, mf_sum, OS_TEXT) < 0) { + strncpy(mf_sum, "xxx", 4); + } + } + + snprintf(newsum, 911, "%c:%s:%d:%d:%d:%d:%s:%s %s%s", + SYSCHECK_MQ, SYSCHECK, + (int)statbuf.st_size, + (int)statbuf.st_mode, + (int)statbuf.st_uid, + (int)statbuf.st_gid, + mf_sum, + sf_sum, dir, file_name); + + send_msg(0, newsum); + return (1); +} + diff --git a/src/client-agent/main.c b/src/client-agent/main.c new file mode 100644 index 000000000..6e7a51dfe --- /dev/null +++ b/src/client-agent/main.c @@ -0,0 +1,178 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* agent daemon */ + +#include "shared.h" +#include "agentd.h" + +#ifndef ARGV0 +#define ARGV0 "openarmor-agentd" +#endif + +/* Prototypes */ +static void help_agentd(void) __attribute((noreturn)); + + +/* Print help statement */ +static void help_agentd() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", USER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c = 0; + int test_config = 0; + int debug_level = 0; + + const char *dir = DEFAULTDIR; + const char *user = USER; + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + uid_t uid; + gid_t gid; + + run_foreground = 0; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vtdfhu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_agentd(); + break; + case 'd': + nowDebug(); + debug_level = 1; + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 't': + test_config = 1; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument.", ARGV0); + } + cfg = optarg; + break; + default: + help_agentd(); + break; + } + } + + debug1(STARTED_MSG, ARGV0); + + extern agent *agt; + + agt = (agent *)calloc(1, sizeof(agent)); + if (!agt) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Check current debug_level + * Command line setting takes precedence + */ + if (debug_level == 0) { + /* Get debug level */ + debug_level = getDefine_Int("agent", "debug", 0, 2); + while (debug_level != 0) { + nowDebug(); + debug_level--; + } + } + + /* Read config */ + if (ClientConf(cfg) < 0) { + ErrorExit(CLIENT_ERROR, ARGV0); + } + + if (!agt->rip) { + merror(AG_INV_IP, ARGV0); + ErrorExit(CLIENT_ERROR, ARGV0); + } + + if (agt->notify_time == 0) { + agt->notify_time = NOTIFY_TIME; + } + if (agt->max_time_reconnect_try == 0 ) { + agt->max_time_reconnect_try = NOTIFY_TIME * 3; + } + if (agt->max_time_reconnect_try <= agt->notify_time) { + agt->max_time_reconnect_try = (agt->notify_time * 3); + verbose("%s: INFO: Max time to reconnect can't be less than notify_time(%d), using notify_time*3 (%d)", ARGV0, agt->notify_time, agt->max_time_reconnect_try); + } + verbose("%s: INFO: Using notify time: %d and max time to reconnect: %d", ARGV0, agt->notify_time, agt->max_time_reconnect_try); + + /* Check auth keys */ + if (!OS_CheckKeys()) { + ErrorExit(AG_NOKEYS_EXIT, ARGV0); + } + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Exit if test config */ + if (test_config) { + exit(0); + } + + /* Start the signal manipulation */ + StartSIG(ARGV0); + + /* Agentd Start */ + AgentdStart(dir, uid, gid, user, group); + + return (0); +} + diff --git a/src/client-agent/notify.c b/src/client-agent/notify.c new file mode 100644 index 000000000..93fec325c --- /dev/null +++ b/src/client-agent/notify.c @@ -0,0 +1,142 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_crypto/md5/md5_op.h" +#include "os_net/os_net.h" +#include "agentd.h" + + +#ifndef WIN32 +static time_t g_saved_time = 0; +static char *rand_keepalive_str2(char *dst, int size); + +static char *rand_keepalive_str2(char *dst, int size) +{ + static const char text[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "!@#$%^&*()_+-=;'[],./?"; + int i, len = rand() % (size - 1); + for ( i = 0; i < len; ++i ) { + dst[i] = text[(unsigned)rand() % (sizeof text - 1)]; + } + dst[i] = '\0'; + return dst; +} +#endif + +/* Return the names of the files in a directory */ +char *getsharedfiles() +{ + unsigned int m_size = 512; + char *ret; + os_md5 md5sum; + + if (OS_MD5_File(SHAREDCFG_FILE, md5sum, OS_TEXT) != 0) { + md5sum[0] = 'x'; + md5sum[1] = '\0'; + } + + /* We control these files, max size is m_size */ + ret = (char *)calloc(m_size + 1, sizeof(char)); + if (!ret) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (NULL); + } + + snprintf(ret, m_size, "%s merged.mg\n", md5sum); + + return (ret); +} + +#ifndef WIN32 + +/* Periodically send notification to server */ +void run_notify() +{ + char keep_alive_random[1024]; + char tmp_msg[OS_SIZE_1024 + 1]; + char *uname; + char *shared_files; + os_md5 md5sum; + time_t curr_time; + + extern agent *agt; + + keep_alive_random[0] = '\0'; + curr_time = time(0); + +#ifndef ONEWAY_ENABLED + /* Check if the server has responded */ + if ((curr_time - available_server) > agt->max_time_reconnect_try) { + /* If response is not available, set lock and wait for it */ + verbose(SERVER_UNAV, ARGV0); + os_setwait(); + + /* Send sync message */ + start_agent(0); + + verbose(SERVER_UP, ARGV0); + os_delwait(); + } +#endif + + /* Check if time has elapsed */ + if ((curr_time - g_saved_time) < agt->notify_time) { + return; + } + g_saved_time = curr_time; + + debug1("%s: DEBUG: Sending agent notification.", ARGV0); + + /* Send the message + * Message is going to be the uname\n checksum file\n checksum file\n + */ + + /* Get uname */ + uname = getuname(); + if (!uname) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return; + } + + /* Get shared files */ + shared_files = getsharedfiles(); + if (!shared_files) { + shared_files = strdup("\0"); + if (!shared_files) { + free(uname); + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return; + } + } + + rand_keepalive_str2(keep_alive_random, 700); + + /* Create message */ + if ((File_DateofChange(AGENTCONFIGINT) > 0 ) && + (OS_MD5_File(AGENTCONFIGINT, md5sum, OS_TEXT) == 0)) { + snprintf(tmp_msg, OS_SIZE_1024, "#!-%s / %s\n%s\n%s", + uname, md5sum, shared_files, keep_alive_random); + } else { + snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s\n%s", + uname, shared_files, keep_alive_random); + } + + /* Send status message */ + send_msg(0, tmp_msg); + + free(uname); + free(shared_files); + + return; +} +#endif /* !WIN32 */ + diff --git a/src/client-agent/receiver-win.c b/src/client-agent/receiver-win.c new file mode 100644 index 000000000..4ab62ee77 --- /dev/null +++ b/src/client-agent/receiver-win.c @@ -0,0 +1,232 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifdef WIN32 + +#include "shared.h" +#include "os_execd/execd.h" +#include "os_crypto/md5/md5_op.h" +#include "os_net/os_net.h" +#include "agentd.h" + + +/* Receive events from the server */ +void *receiver_thread(__attribute__((unused)) void *none) +{ + extern agent *agt; + int recv_b; + + char file[OS_SIZE_1024 + 1]; + char buffer[OS_MAXSTR + 1]; + + char cleartext[OS_MAXSTR + 1]; + char *tmp_msg; + + char file_sum[34]; + + fd_set fdset; + struct timeval selecttime; + + FILE *fp; + + /* Set FP to null before starting */ + fp = NULL; + + memset(cleartext, '\0', OS_MAXSTR + 1); + memset(buffer, '\0', OS_MAXSTR + 1); + memset(file, '\0', OS_SIZE_1024 + 1); + memset(file_sum, '\0', 34); + + while (1) { + /* sock must be set */ + if (agt->sock == -1) { + sleep(5); + continue; + } + + FD_ZERO(&fdset); + FD_SET(agt->sock, &fdset); + + /* Wait for 30 seconds */ + selecttime.tv_sec = 30; + selecttime.tv_usec = 0; + + /* Wait with a timeout for any descriptor */ + recv_b = select(0, &fdset, NULL, NULL, &selecttime); + if (recv_b == -1) { + merror(SELECT_ERROR, ARGV0, errno, strerror(errno)); + sleep(30); + continue; + } else if (recv_b == 0) { + continue; + } + + /* Read until no more messages are available */ + while ((recv_b = recv(agt->sock, buffer, OS_SIZE_1024, 0)) > 0) { + /* Id of zero -- only one key allowed */ + tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b - 1); + if (tmp_msg == NULL) { + merror(MSG_ERROR, ARGV0, agt->rip[agt->rip_id]); + continue; + } + + /* Check for commands */ + if (IsValidHeader(tmp_msg)) { + /* This is the only thread that modifies it */ + available_server = (int)time(NULL); + + /* Run timeout commands */ + if (agt->execdq >= 0) { + WinTimeoutRun(available_server); + } + + /* If it is an active response message */ + if (strncmp(tmp_msg, EXECD_HEADER, strlen(EXECD_HEADER)) == 0) { + tmp_msg += strlen(EXECD_HEADER); + + /* Run on Windows */ + if (agt->execdq >= 0) { + WinExecdRun(tmp_msg); + } + + continue; + } + + /* Restart syscheck */ + else if (strcmp(tmp_msg, HC_SK_RESTART) == 0) { + os_set_restart_syscheck(); + continue; + } + + /* Ack from server */ + else if (strcmp(tmp_msg, HC_ACK) == 0) { + continue; + } + + /* Close any open file pointer if it was being written to */ + if (fp) { + fclose(fp); + fp = NULL; + } + + /* File update message */ + if (strncmp(tmp_msg, FILE_UPDATE_HEADER, + strlen(FILE_UPDATE_HEADER)) == 0) { + char *validate_file; + tmp_msg += strlen(FILE_UPDATE_HEADER); + + /* Going to after the file sum */ + validate_file = strchr(tmp_msg, ' '); + if (!validate_file) { + continue; + } + + *validate_file = '\0'; + + /* Copy the file sum */ + strncpy(file_sum, tmp_msg, 33); + + /* Set tmp_msg to the beginning of the file name */ + validate_file++; + tmp_msg = validate_file; + + if ((validate_file = strchr(tmp_msg, '\n')) != NULL) { + *validate_file = '\0'; + } + + while ((validate_file = strchr(tmp_msg, '/')) != NULL) { + *validate_file = '-'; + } + + if (tmp_msg[0] == '.') { + tmp_msg[0] = '-'; + } + + snprintf(file, OS_SIZE_1024, "%s/%s", + SHAREDCFG_DIR, + tmp_msg); + + fp = fopen(file, "wb"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, file, errno, strerror(errno)); + } + } + + else if (strncmp(tmp_msg, FILE_CLOSE_HEADER, + strlen(FILE_CLOSE_HEADER)) == 0) { + /* No error */ + os_md5 currently_md5; + + /* Close for the rename to work */ + if (fp) { + fclose(fp); + fp = NULL; + } + + if (file[0] == '\0') { + /* Nothing to be done */ + } + + else if (OS_MD5_File(file, currently_md5, OS_TEXT) < 0) { + /* Remove file */ + unlink(file); + file[0] = '\0'; + } else { + if (strcmp(currently_md5, file_sum) != 0) { + debug1("%s: Failed md5 for: %s -- deleting.", + ARGV0, file); + unlink(file); + } else { + char *final_file; + + /* Rename the file to its original name */ + final_file = strrchr(file, '/'); + if (final_file) { + if (strcmp(final_file + 1, SHAREDCFG_FILENAME) == 0) { + UnmergeFiles(file, SHAREDCFG_DIR); + } + } else { + unlink(file); + } + } + + file[0] = '\0'; + } + } + + else { + merror("%s: WARN: Unknown message received from server.", ARGV0); + } + } + + else if (fp) { + available_server = (int)time(NULL); + fprintf(fp, "%s", tmp_msg); + } + + else { + merror("%s: WARN: Unknown message received. No action defined.", + ARGV0); + } + } + } + + /* Clean up */ + if (fp) { + fclose(fp); + if (file[0] != '\0') { + unlink(file); + } + } + + return (NULL); +} + +#endif /* WIN32 */ + diff --git a/src/client-agent/receiver.c b/src/client-agent/receiver.c new file mode 100644 index 000000000..91f1e179b --- /dev/null +++ b/src/client-agent/receiver.c @@ -0,0 +1,200 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#ifdef WIN32 +#include "os_execd/execd.h" +#endif +#include "os_crypto/md5/md5_op.h" +#include "os_net/os_net.h" +#include "agentd.h" + +/* Global variables */ +static FILE *fp = NULL; +static char file_sum[34] = ""; +static char file[OS_SIZE_1024 + 1] = ""; + + +/* Receive events from the server */ +void *receive_msg() +{ + ssize_t recv_b; + char buffer[OS_MAXSTR + 1]; + char cleartext[OS_MAXSTR + 1]; + char *tmp_msg; + + extern agent *agt; + + memset(cleartext, '\0', OS_MAXSTR + 1); + memset(buffer, '\0', OS_MAXSTR + 1); + + /* Read until no more messages are available */ + while ((recv_b = recv(agt->sock, buffer, OS_SIZE_1024, MSG_DONTWAIT)) > 0) { + buffer[recv_b] = '\0'; + + tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b - 1); + if (tmp_msg == NULL) { + merror(MSG_ERROR, ARGV0, agt->rip[agt->rip_id]); + continue; + } + + /* Check for commands */ + if (IsValidHeader(tmp_msg)) { + available_server = (int)time(NULL); + +#ifdef WIN32 + /* Run timeout commands */ + if (agt->execdq >= 0) { + WinTimeoutRun(available_server); + } +#endif + + /* If it is an active response message */ + if (strncmp(tmp_msg, EXECD_HEADER, strlen(EXECD_HEADER)) == 0) { + tmp_msg += strlen(EXECD_HEADER); +#ifndef WIN32 + if (agt->execdq >= 0) { + if (OS_SendUnix(agt->execdq, tmp_msg, 0) < 0) { + merror("%s: Error communicating with execd", + ARGV0); + } + } +#else + /* Run on Windows */ + if (agt->execdq >= 0) { + WinExecdRun(tmp_msg); + } +#endif + + continue; + } + + /* Restart syscheck */ + else if (strcmp(tmp_msg, HC_SK_RESTART) == 0) { + os_set_restart_syscheck(); + continue; + } + + /* Ack from server */ + else if (strcmp(tmp_msg, HC_ACK) == 0) { + continue; + } + + /* Close any open file pointer if it was being written to */ + if (fp) { + fclose(fp); + fp = NULL; + } + + /* File update message */ + if (strncmp(tmp_msg, FILE_UPDATE_HEADER, + strlen(FILE_UPDATE_HEADER)) == 0) { + char *validate_file; + + tmp_msg += strlen(FILE_UPDATE_HEADER); + + /* Going to after the file sum */ + validate_file = strchr(tmp_msg, ' '); + if (!validate_file) { + continue; + } + + *validate_file = '\0'; + + /* Copy the file sum */ + strncpy(file_sum, tmp_msg, 33); + + /* Set tmp_msg to the beginning of the file name */ + validate_file++; + tmp_msg = validate_file; + + if ((validate_file = strchr(tmp_msg, '\n')) != NULL) { + *validate_file = '\0'; + } + + while ((validate_file = strchr(tmp_msg, '/')) != NULL) { + *validate_file = '-'; + } + + if (tmp_msg[0] == '.') { + tmp_msg[0] = '-'; + } + + snprintf(file, OS_SIZE_1024, "%s/%s", + SHAREDCFG_DIR, + tmp_msg); + + fp = fopen(file, "w"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, file, errno, strerror(errno)); + } + } + + else if (strncmp(tmp_msg, FILE_CLOSE_HEADER, + strlen(FILE_CLOSE_HEADER)) == 0) { + /* No error */ + os_md5 currently_md5; + + /* Close for the rename to work */ + if (fp) { + fclose(fp); + fp = NULL; + } + + if (file[0] == '\0') { + /* Nothing to be done */ + } + + else if (OS_MD5_File(file, currently_md5, OS_TEXT) < 0) { + /* Remove file */ + unlink(file); + file[0] = '\0'; + } else { + if (strcmp(currently_md5, file_sum) != 0) { + debug1("%s: ERROR: Failed md5 for: %s -- deleting.", + ARGV0, file); + unlink(file); + } else { + char *final_file; + + /* Rename the file to its original name */ + final_file = strrchr(file, '/'); + if (final_file) { + if (strcmp(final_file + 1, SHAREDCFG_FILENAME) == 0) { + UnmergeFiles(file, SHAREDCFG_DIR); + } + } else { + /* Remove file */ + unlink(file); + } + } + + file[0] = '\0'; + } + } + + else { + merror("%s: WARN: Unknown message received from server.", ARGV0); + } + } + + else if (fp) { + available_server = (int)time(NULL); + fprintf(fp, "%s", tmp_msg); + } + + else { + merror("%s: WARN: Unknown message received. No action defined.", + ARGV0); + } + } + + return (NULL); +} + diff --git a/src/client-agent/sendmsg.c b/src/client-agent/sendmsg.c new file mode 100644 index 000000000..3076dfcf9 --- /dev/null +++ b/src/client-agent/sendmsg.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentd.h" +#include "os_net/os_net.h" + + +/* Send a message to the server */ +int send_msg(int agentid, const char *msg) +{ + + extern agent *agt; + + size_t msg_size; + char crypt_msg[OS_MAXSTR + 1]; + + msg_size = CreateSecMSG(&keys, msg, crypt_msg, agentid); + if (msg_size == 0) { + merror(SEC_ERROR, ARGV0); + return (-1); + } + + /* Send msg_size of crypt_msg */ + if (OS_SendUDPbySize(agt->sock, msg_size, crypt_msg) < 0) { + merror(SEND_ERROR, ARGV0, "server"); + sleep(1); + return (-1); + } + + return (0); +} + diff --git a/src/client-agent/start_agent.c b/src/client-agent/start_agent.c new file mode 100644 index 000000000..0e0452b67 --- /dev/null +++ b/src/client-agent/start_agent.c @@ -0,0 +1,196 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentd.h" +#include "os_net/os_net.h" + + +/* Attempt to connect to all configured servers */ +int connect_server(int initial_id) +{ + unsigned int attempts = 2; + + extern agent *agt; + + int rc = initial_id; + + /* Checking if the initial is zero, meaning we have to + * rotate to the beginning + */ + if (agt->rip[initial_id] == NULL) { + rc = 0; + } + + /* Close socket if available */ + if (agt->sock >= 0) { + sleep(1); + CloseSocket(agt->sock); + agt->sock = -1; + + if (agt->rip[1]) { + verbose("%s: INFO: Closing connection to server %s, port %s.", + ARGV0, + agt->rip[rc], + agt->port); + } + + } + + while (agt->rip[rc]) { + + /* Connect to any useable address of the server */ + verbose("%s: INFO: Trying to connect to server %s, port %s.", ARGV0, + agt->rip[rc], + agt->port); + + agt->sock = OS_ConnectUDP(agt->port, agt->rip[rc]); + + if (agt->sock < 0) { + agt->sock = -1; + merror(CONNS_ERROR, ARGV0, agt->rip[rc]); + rc++; + + if (agt->rip[rc] == NULL) { + attempts += 10; + + /* Only log that if we have more than 1 server configured */ + if (agt->rip[1]) { + merror("%s: ERROR: Unable to connect to any server.", ARGV0); + } + + sleep(attempts); + rc = 0; + } + } else { +#ifdef HPUX + /* Set socket non-blocking on HPUX */ + // fcntl(agt->sock, O_NONBLOCK); +#endif + +#ifdef WIN32 + int bmode = 1; + + /* Set socket to non-blocking */ + ioctlsocket(agt->sock, FIONBIO, (u_long FAR *) &bmode); +#endif + + agt->rip_id = rc; + return (1); + } + } + + return (0); +} + +/* Send synchronization message to the server and wait for the ack */ +void start_agent(int is_startup) +{ + ssize_t recv_b = 0; + unsigned int attempts = 0, g_attempts = 1; + + char *tmp_msg; + char msg[OS_MAXSTR + 2]; + char buffer[OS_MAXSTR + 1]; + char cleartext[OS_MAXSTR + 1]; + char fmsg[OS_MAXSTR + 1]; + + extern agent *agt; + + memset(msg, '\0', OS_MAXSTR + 2); + memset(buffer, '\0', OS_MAXSTR + 1); + memset(cleartext, '\0', OS_MAXSTR + 1); + memset(fmsg, '\0', OS_MAXSTR + 1); + snprintf(msg, OS_MAXSTR, "%s%s", CONTROL_HEADER, HC_STARTUP); + +#ifdef ONEWAY_ENABLED + return; +#endif + + while (1) { + /* Send start up message */ + send_msg(0, msg); + attempts = 0; + + /* Read until our reply comes back */ + while (((recv_b = recv(agt->sock, buffer, OS_MAXSTR, + MSG_DONTWAIT)) >= 0) || (attempts <= 5)) { + if (recv_b <= 0) { + /* Sleep five seconds before trying to get the reply from + * the server again + */ + attempts++; + sleep(attempts); + + /* Send message again (after three attempts) */ + if (attempts >= 3) { + send_msg(0, msg); + } + + continue; + } + + /* Id of zero -- only one key allowed */ + tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b - 1); + if (tmp_msg == NULL) { + merror(MSG_ERROR, ARGV0, agt->rip[agt->rip_id]); + continue; + } + + /* Check for commands */ + if (IsValidHeader(tmp_msg)) { + /* If it is an ack reply */ + if (strcmp(tmp_msg, HC_ACK) == 0) { + available_server = time(0); + + verbose(AG_CONNECTED, ARGV0, agt->rip[agt->rip_id], + agt->port); + + if (is_startup) { + /* Send log message about start up */ + snprintf(msg, OS_MAXSTR, OS_AG_STARTED, + keys.keyentries[0]->name, + keys.keyentries[0]->ip->ip); + snprintf(fmsg, OS_MAXSTR, "%c:%s:%s", LOCALFILE_MQ, + "openarmor", msg); + send_msg(0, fmsg); + } + return; + } + } + } + + /* Wait for server reply */ + merror(AG_WAIT_SERVER, ARGV0, agt->rip[agt->rip_id]); + + /* If we have more than one server, try all */ + if (agt->rip[1]) { + int curr_rip = agt->rip_id; + merror("%s: INFO: Trying next server in the line: '%s'.", ARGV0, + agt->rip[agt->rip_id + 1] != NULL ? agt->rip[agt->rip_id + 1] : agt->rip[0]); + connect_server(agt->rip_id + 1); + + if (agt->rip_id == curr_rip) { + sleep(g_attempts); + g_attempts += (attempts * 3); + } else { + g_attempts += 5; + sleep(g_attempts); + } + } else { + sleep(g_attempts); + g_attempts += (attempts * 3); + + connect_server(0); + } + } + + return; +} + diff --git a/src/config/active-response.c b/src/config/active-response.c new file mode 100644 index 000000000..d25533f04 --- /dev/null +++ b/src/config/active-response.c @@ -0,0 +1,422 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 +#include +#include +#endif + +#include "shared.h" +#include "os_xml/os_xml.h" +#include "os_regex/os_regex.h" +#include "active-response.h" +#include "config.h" + +/* Global variables */ +int ar_flag = 0; + + +/* Generate a list with all active responses */ +int ReadActiveResponses(XML_NODE node, void *d1, void *d2) +{ + OSList *l1 = (OSList *) d1; + OSList *l2 = (OSList *) d2; + FILE *fp; + int i = 0; + int r_ar = 0; + int l_ar = 0; + int rpt = 0; + + /* Xml options */ + const char *xml_ar_command = "command"; + const char *xml_ar_location = "location"; + const char *xml_ar_agent_id = "agent_id"; + const char *xml_ar_rules_id = "rules_id"; + const char *xml_ar_rules_group = "rules_group"; + const char *xml_ar_level = "level"; + const char *xml_ar_timeout = "timeout"; + const char *xml_ar_disabled = "disabled"; + const char *xml_ar_repeated = "repeated_offenders"; + + char *tmp_location; + + /* Currently active response */ + active_response *tmp_ar; + + /* Open shared ar file */ + fp = fopen(DEFAULTARPATH, "a"); + if (!fp) { + merror(FOPEN_ERROR, __local_name, DEFAULTARPATH, errno, strerror(errno)); + return (-1); + } + +#ifndef WIN32 + struct group *os_group; + if ((os_group = getgrnam(USER)) == NULL) { + merror("Could not get openarmor gid."); + fclose(fp); + return (-1); + } + + if ((chown(DEFAULTARPATH, (uid_t) - 1, os_group->gr_gid)) == -1) { + merror("Could not change the group to openarmor: %d", errno); + fclose(fp); + return (-1); + } +#endif + + if ((chmod(DEFAULTARPATH, 0440)) == -1) { + merror("Could not chmod to 0440: %d", errno); + fclose(fp); + return (-1); + } + + /* Allocate for the active-response */ + tmp_ar = (active_response *) calloc(1, sizeof(active_response)); + if (!tmp_ar) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + fclose(fp); + return (-1); + } + + /* Initialize variables */ + tmp_ar->name = NULL; + tmp_ar->command = NULL; + tmp_ar->location = 0; + tmp_ar->timeout = 0; + tmp_ar->level = 0; + tmp_ar->agent_id = NULL; + tmp_ar->rules_id = NULL; + tmp_ar->rules_group = NULL; + tmp_ar->ar_cmd = NULL; + tmp_location = NULL; + + /* Search for the commands */ + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + goto error_invalid; + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + goto error_invalid; + } + + /* Command */ + if (strcmp(node[i]->element, xml_ar_command) == 0) { + tmp_ar->command = strdup(node[i]->content); + } + /* Target */ + else if (strcmp(node[i]->element, xml_ar_location) == 0) { + free(tmp_location); + tmp_location = strdup(node[i]->content); + } else if (strcmp(node[i]->element, xml_ar_agent_id) == 0) { + tmp_ar->agent_id = strdup(node[i]->content); + } else if (strcmp(node[i]->element, xml_ar_rules_id) == 0) { + tmp_ar->rules_id = strdup(node[i]->content); + } else if (strcmp(node[i]->element, xml_ar_rules_group) == 0) { + tmp_ar->rules_group = strdup(node[i]->content); + } else if (strcmp(node[i]->element, xml_ar_level) == 0) { + /* Level must be numeric */ + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto error_invalid; + } + + tmp_ar->level = atoi(node[i]->content); + + /* Make sure the level is valid */ + if ((tmp_ar->level < 0) || (tmp_ar->level > 20)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto error_invalid; + } + } else if (strcmp(node[i]->element, xml_ar_timeout) == 0) { + tmp_ar->timeout = atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_ar_disabled) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + ar_flag = -1; + } else if (strcmp(node[i]->content, "no") == 0) { + /* Don't do anything if disabled is set to "no" */ + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto error_invalid; + } + } else if (strcmp(node[i]->element, xml_ar_repeated) == 0) { + /* Nothing - we deal with it on execd */ + rpt = 1; + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + goto error_invalid; + } + i++; + } + + /* Check if ar is disabled */ + if (ar_flag == -1) { + /* reset ar_flag, the next ar command may not be disabled */ + ar_flag = 0; + if (tmp_ar->command) { + debug1("active response command '%s' is disabled", tmp_ar->command); + } + fclose(fp); + free(tmp_ar); + free(tmp_location); + return (0); + } + + /* Command and location must be there */ + if (!tmp_ar->command || !tmp_location) { + debug1("command or location missing"); + fclose(fp); + free(tmp_ar); + free(tmp_location); + + if (rpt == 1) { + return (0); + } + merror(AR_MISS, __local_name); + return (-1); + } + + /* analysisd */ + if (OS_Regex("AS|analysisd|analysis-server|server", tmp_location)) { + tmp_ar->location |= AS_ONLY; + } + + if (OS_Regex("local", tmp_location)) { + tmp_ar->location |= REMOTE_AGENT; + } + + if (OS_Regex("defined-agent", tmp_location)) { + if (!tmp_ar->agent_id) { + debug1("'defined-agent' agent_id not defined"); + merror(AR_DEF_AGENT, __local_name); + fclose(fp); + free(tmp_ar); + free(tmp_location); + return (-1); + } + + tmp_ar->location |= SPECIFIC_AGENT; + + } + if (OS_Regex("all|any", tmp_location)) { + tmp_ar->location |= ALL_AGENTS; + } + + /* If we didn't set any value for the location */ + if (tmp_ar->location == 0) { + debug1("no location defined"); + merror(AR_INV_LOC, __local_name, tmp_location); + fclose(fp); + free(tmp_ar); + free(tmp_location); + return (-1); + } + + /* Clean tmp_location */ + free(tmp_location); + tmp_location = NULL; + + /* Check if command name is valid */ + { + OSListNode *my_commands_node; + + my_commands_node = OSList_GetFirstNode(l1); + while (my_commands_node) { + ar_command *my_command; + my_command = (ar_command *)my_commands_node->data; + + if (strcmp(my_command->name, tmp_ar->command) == 0) { + tmp_ar->ar_cmd = my_command; + break; + } + + my_commands_node = OSList_GetNextNode(l1); + } + + /* Didn't find a valid command */ + if (tmp_ar->ar_cmd == NULL) { + debug1("invalid command"); + merror(AR_INV_CMD, __local_name, tmp_ar->command); + fclose(fp); + free(tmp_ar); + return (-1); + } + } + + /* Check if timeout is allowed */ + if (tmp_ar->timeout && !tmp_ar->ar_cmd->timeout_allowed) { + debug1("timeout is not allowed"); + merror(AR_NO_TIMEOUT, __local_name, tmp_ar->ar_cmd->name); + fclose(fp); + free(tmp_ar); + return (-1); + } + + /* d1 is the active response list */ + if (!OSList_AddData(l2, (void *)tmp_ar)) { + merror(LIST_ADD_ERROR, __local_name); + fclose(fp); + free(tmp_ar); + return (-1); + } + + /* Set a unique active response name */ + tmp_ar->name = (char *) calloc(OS_FLSIZE + 1, sizeof(char)); + if (!tmp_ar->name) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + snprintf(tmp_ar->name, OS_FLSIZE, "%s%d", + tmp_ar->ar_cmd->name, + tmp_ar->timeout); + + /* Add to shared file */ + debug1("writing command '%s' to '%s'", tmp_ar->command, DEFAULTARPATH); + fprintf(fp, "%s - %s - %d\n", + tmp_ar->name, + tmp_ar->ar_cmd->executable, + tmp_ar->timeout); + + /* Set the configs to start the right queues */ + if (tmp_ar->location & AS_ONLY) { + l_ar = 1; + } + if (tmp_ar->location & ALL_AGENTS) { + r_ar = 1; + } + if (tmp_ar->location & REMOTE_AGENT) { + r_ar = 1; + l_ar = 1; + } + if (tmp_ar->location & SPECIFIC_AGENT) { + r_ar = 1; + } + + /* Set the configuration for the active response */ + if (r_ar && (!(ar_flag & REMOTE_AR))) { + ar_flag |= REMOTE_AR; + } + if (l_ar && (!(ar_flag & LOCAL_AR))) { + ar_flag |= LOCAL_AR; + } + + /* Close shared file for active response */ + fclose(fp); + + /* Done over here */ + return (0); + +error_invalid: + /* In case of an error clean up first*/ + fclose(fp); + free(tmp_ar); + free(tmp_location); + + return (OS_INVALID); +} + +int ReadActiveCommands(XML_NODE node, void *d1, __attribute__((unused)) void *d2) +{ + OSList *l1 = (OSList *) d1; + int i = 0; + char *tmp_str = NULL; + + /* Xml values */ + const char *command_name = "name"; + const char *command_expect = "expect"; + const char *command_executable = "executable"; + const char *timeout_allowed = "timeout_allowed"; + + ar_command *tmp_command; + + /* Allocate the active-response command */ + tmp_command = (ar_command *) calloc(1, sizeof(ar_command)); + if (!tmp_command) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (-1); + } + + tmp_command->name = NULL; + tmp_command->expect = 0; + tmp_command->executable = NULL; + tmp_command->timeout_allowed = 0; + + /* Search for the commands */ + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + free(tmp_str); + free(tmp_command); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + free(tmp_str); + free(tmp_command); + return (OS_INVALID); + } + if (strcmp(node[i]->element, command_name) == 0) { + tmp_command->name = strdup(node[i]->content); + } else if (strcmp(node[i]->element, command_expect) == 0) { + free(tmp_str); + tmp_str = strdup(node[i]->content); + } else if (strcmp(node[i]->element, command_executable) == 0) { + tmp_command->executable = strdup(node[i]->content); + } else if (strcmp(node[i]->element, timeout_allowed) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + tmp_command->timeout_allowed = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + tmp_command->timeout_allowed = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + free(tmp_str); + free(tmp_command); + return (OS_INVALID); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + free(tmp_str); + free(tmp_command); + return (OS_INVALID); + } + i++; + } + + if (!tmp_command->name || !tmp_str || !tmp_command->executable) { + merror(AR_CMD_MISS, __local_name); + free(tmp_str); + free(tmp_command); + return (-1); + } + + /* Get the expect */ + if (strlen(tmp_str) >= 4) { + if (OS_Regex("user", tmp_str)) { + tmp_command->expect |= USERNAME; + } + if (OS_Regex("srcip", tmp_str)) { + tmp_command->expect |= SRCIP; + } + if (OS_Regex("filename", tmp_str)) { + tmp_command->expect |= FILENAME; + } + } + + free(tmp_str); + tmp_str = NULL; + + /* Add command to the list */ + if (!OSList_AddData(l1, (void *)tmp_command)) { + merror(LIST_ADD_ERROR, __local_name); + free(tmp_command); + return (-1); + } + + return (0); +} + diff --git a/src/config/active-response.h b/src/config/active-response.h new file mode 100644 index 000000000..3ed487221 --- /dev/null +++ b/src/config/active-response.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _CAR__H +#define _CAR__H + +/* Active response commands */ +typedef struct _ar_command { + int expect; + int timeout_allowed; + + char *name; + char *executable; +} ar_command; + +/* Active response data */ +typedef struct _ar { + int timeout; + int location; + int level; + char *name; + char *command; + char *agent_id; + char *rules_id; + char *rules_group; + + ar_command *ar_cmd; +} active_response; + +/* Active response flag */ +extern int ar_flag; + +#endif /* _CAR__H */ + diff --git a/src/config/agentlessd-config.c b/src/config/agentlessd-config.c new file mode 100644 index 000000000..41b8902b5 --- /dev/null +++ b/src/config/agentlessd-config.c @@ -0,0 +1,155 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "agentlessd-config.h" +#include "config.h" + + +int Read_CAgentless(XML_NODE node, void *config, __attribute__((unused)) void *config2) +{ + unsigned int i = 0, j = 0, s = 0; + + /* XML definitions */ + const char *xml_lessd_server = "host"; + const char *xml_lessd_port = "port"; + const char *xml_lessd_type = "type"; + const char *xml_lessd_frequency = "frequency"; + const char *xml_lessd_state = "state"; + const char *xml_lessd_command = "run_command"; + const char *xml_lessd_options = "arguments"; + + agentlessd_config *lessd_config = (agentlessd_config *)config; + + /* Get any configured entry */ + if (lessd_config->entries) { + while (lessd_config->entries[s]) { + s++; + } + } + + /* Allocate the memory for the config */ + os_realloc(lessd_config->entries, (s + 2) * sizeof(agentlessd_entries *), + lessd_config->entries); + os_calloc(1, sizeof(agentlessd_entries), lessd_config->entries[s]); + lessd_config->entries[s + 1] = NULL; + + /* Zero the elements */ + lessd_config->entries[s]->server = NULL; + lessd_config->entries[s]->command = NULL; + lessd_config->entries[s]->options = ""; + lessd_config->entries[s]->type = NULL; + lessd_config->entries[s]->frequency = 86400; + lessd_config->entries[s]->state = 0; + lessd_config->entries[s]->current_state = 0; + lessd_config->entries[s]->port = 0; + lessd_config->entries[s]->error_flag = 0; + + /* Read the XML */ + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } else if (strcmp(node[i]->element, xml_lessd_frequency) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + lessd_config->entries[s]->frequency = atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_lessd_port) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + lessd_config->entries[s]->port = atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_lessd_server) == 0) { + char s_content[1024 + 1]; + s_content[1024] = '\0'; + + /* Get any configured entry */ + j = 0; + if (lessd_config->entries[s]->server) { + while (lessd_config->entries[s]->server[j]) { + j++; + } + } + + os_realloc(lessd_config->entries[s]->server, (j + 2) * + sizeof(char *), + lessd_config->entries[s]->server); + if (strncmp(node[i]->content, "use_su ", 7) == 0) { + snprintf(s_content, 1024, "s%s", node[i]->content + 7); + } else if (strncmp(node[i]->content, "use_sudo ", 9) == 0) { + snprintf(s_content, 1024, "o%s", node[i]->content + 9); + } else { + snprintf(s_content, 1024, " %s", node[i]->content); + } + + os_strdup(s_content, + lessd_config->entries[s]->server[j]); + lessd_config->entries[s]->server[j + 1] = NULL; + } else if (strcmp(node[i]->element, xml_lessd_type) == 0) { + char script_path[1024 + 1]; + + script_path[1024] = '\0'; + snprintf(script_path, 1024, "%s/%s", AGENTLESSDIRPATH, + node[i]->content); + + if (File_DateofChange(script_path) <= 0) { + merror("%s: ERROR: Unable to find '%s' at '%s'.", + __local_name, node[i]->content, AGENTLESSDIRPATH); + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + os_strdup(node[i]->content, lessd_config->entries[s]->type); + } else if (strcmp(node[i]->element, xml_lessd_command) == 0) { + os_strdup(node[i]->content, lessd_config->entries[s]->command); + } else if (strcmp(node[i]->element, xml_lessd_options) == 0) { + os_strdup(node[i]->content, lessd_config->entries[s]->options); + } else if (strcmp(node[i]->element, xml_lessd_state) == 0) { + if (strcmp(node[i]->content, "periodic") == 0) { + lessd_config->entries[s]->state |= LESSD_STATE_PERIODIC; + } else if (strcmp(node[i]->content, "stay_connected") == 0) { + lessd_config->entries[s]->state |= LESSD_STATE_CONNECTED; + } else if (strcmp(node[i]->content, "periodic_diff") == 0) { + lessd_config->entries[s]->state |= LESSD_STATE_PERIODIC; + lessd_config->entries[s]->state |= LESSD_STATE_DIFF; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + /* We must have at least one entry set */ + if (!lessd_config->entries[s]->server || + !lessd_config->entries[s]->state || + !lessd_config->entries[s]->type) { + merror(XML_INV_MISSOPTS, __local_name); + return (OS_INVALID); + } + + if ((lessd_config->entries[s]->state == LESSD_STATE_PERIODIC) && + !lessd_config->entries[s]->frequency) { + merror(XML_INV_MISSFREQ, __local_name); + return (OS_INVALID); + } + + return (0); +} + diff --git a/src/config/agentlessd-config.h b/src/config/agentlessd-config.h new file mode 100644 index 000000000..8583f551b --- /dev/null +++ b/src/config/agentlessd-config.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _AGENTLESSDCONFIG_H +#define _AGENTLESSDCONFIG_H + +/* Entry states */ +#define LESSD_STATE_CONNECTED 0x001 +#define LESSD_STATE_PERIODIC 0x002 +#define LESSD_STATE_DIFF 0x004 +#define LESSD_USE_SU 0x010 +#define LESSD_USE_SUDO 0x020 + +/* Structure for each entry */ +typedef struct _agentlessd_entries { + short int state; + + int frequency; + time_t current_state; + int port; + int error_flag; + + char *type; + char **server; + const char *options; + char *command; + +} agentlessd_entries; + +/* Configuration structure */ +typedef struct _agentlessd_config { + int queue; + agentlessd_entries **entries; + +} agentlessd_config; + +#endif /* _AGENTLESSDCONFIG_H */ + diff --git a/src/config/alerts-config.c b/src/config/alerts-config.c new file mode 100644 index 000000000..7b86126fb --- /dev/null +++ b/src/config/alerts-config.c @@ -0,0 +1,83 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "global-config.h" +#include "config.h" + + +int Read_Alerts(XML_NODE node, void *configp, __attribute__((unused)) void *mailp) +{ + int i = 0; + + /* XML definitions */ + const char *xml_email_level = "email_alert_level"; + const char *xml_log_level = "log_alert_level"; + +#ifdef LIBGEOIP_ENABLED + /* GeoIP */ + const char *xml_log_geoip = "use_geoip"; +#endif + + _Config *Config; + Config = (_Config *)configp; + + if (!Config) { + merror("%s: ERROR: Configuration handle is NULL.", __local_name); + return (OS_INVALID); + } + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + /* Mail notification */ + else if (strcmp(node[i]->element, xml_email_level) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + Config->mailbylevel = (u_int8_t) atoi(node[i]->content); + } + /* Log alerts */ + else if (strcmp(node[i]->element, xml_log_level) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + Config->logbylevel = (u_int8_t) atoi(node[i]->content); + } +#ifdef LIBGEOIP_ENABLED + /* Enable GeoIP */ + else if (strcmp(node[i]->element, xml_log_geoip) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + Config->loggeoip = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + Config->loggeoip = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + } +#endif + else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + return (0); +} + diff --git a/src/config/client-config.c b/src/config/client-config.c new file mode 100644 index 000000000..e670fe6cb --- /dev/null +++ b/src/config/client-config.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "client-config.h" +#include "os_net/os_net.h" +#include "config.h" + + +int Read_Client(XML_NODE node, void *d1, __attribute__((unused)) void *d2) +{ + int i = 0, portnum; + + /* XML definitions */ + const char *xml_server_ip = "server-ip"; + const char *xml_server_hostname = "server-hostname"; + const char *xml_local_ip = "local_ip"; + const char *xml_client_port = "port"; + const char *xml_ar_disabled = "disable-active-response"; + const char *xml_notify_time = "notify_time"; + const char *xml_max_time_reconnect_try = "time-reconnect"; + const char *xml_profile_name = "config-profile"; + + agent *logr; + + logr = (agent *)d1; + + logr->notify_time = 0; + logr->max_time_reconnect_try = 0; + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + /* Get local IP */ + else if (strcmp(node[i]->element, xml_local_ip) == 0) { + os_strdup(node[i]->content, logr->lip); + if (OS_IsValidIP(logr->lip, NULL) != 1) { + merror(INVALID_IP, __local_name, logr->lip); + return (OS_INVALID); + } + } + /* Get server IP */ + else if (strcmp(node[i]->element, xml_server_ip) == 0) { + unsigned int ip_id = 0; + + /* Get last IP */ + if (logr->rip) { + while (logr->rip[ip_id]) { + ip_id++; + } + } + os_realloc(logr->rip, (ip_id + 2) * sizeof(char *), logr->rip); + logr->rip[ip_id] = NULL; + logr->rip[ip_id + 1] = NULL; + + os_strdup(node[i]->content, logr->rip[ip_id]); + if (OS_IsValidIP(logr->rip[ip_id], NULL) != 1) { + merror(INVALID_IP, __local_name, logr->rip[ip_id]); + return (OS_INVALID); + } + logr->rip_id++; + } else if (strcmp(node[i]->element, xml_server_hostname) == 0) { + unsigned int ip_id = 0; + char *s_ip; + + /* Get last IP */ + if (logr->rip) { + while (logr->rip[ip_id]) { + ip_id++; + } + } + os_realloc(logr->rip, (ip_id + 2) * sizeof(char *), logr->rip); + s_ip = OS_GetHost(node[i]->content, 5); + if (!s_ip) { + merror("%s: WARN: '%s' does not resolve to an address.", + __local_name, node[i]->content); + merror(AG_INV_HOST, __local_name, node[i]->content); + } + free(s_ip); + + os_strdup(node[i]->content, logr->rip[ip_id]); + logr->rip[ip_id + 1] = NULL; + logr->rip_id++; + } else if (strcmp(node[i]->element, xml_client_port) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + os_strdup(node[i]->content, logr->port); + portnum = atoi(node[i]->content); + + if(portnum <= 0 || portnum > 65535) + { + merror(PORT_ERROR, __local_name, portnum); + return(OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_notify_time) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + logr->notify_time = atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_max_time_reconnect_try) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + logr->max_time_reconnect_try = atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_ar_disabled) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + logr->execdq = -1; + } else if (strcmp(node[i]->content, "no") == 0) { + logr->execdq = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_profile_name) == 0) { + /* Profile name can be anything hence no validation */ + os_strdup(node[i]->content, logr->profile); + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + if (!logr->rip) { + return (OS_INVALID); + } + + return (0); +} + diff --git a/src/config/client-config.h b/src/config/client-config.h new file mode 100644 index 000000000..7c071a7b0 --- /dev/null +++ b/src/config/client-config.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CAGENTD_H +#define __CAGENTD_H + +#ifndef WIN32 +#include +#include +#include +#include +#include +#endif //WIN32 + +/* Configuration structure */ +typedef struct _agent { + char *port; + int m_queue; + int sock; + int execdq; + int rip_id; + char *lip; + char **rip; /* remote (server) IP */ + int notify_time; + int max_time_reconnect_try; + char *profile; + +#ifndef WIN32 + struct imsgbuf ibuf; +#endif //WIN32 + +} agent; + +#endif /* __CAGENTD_H */ + diff --git a/src/config/config.c b/src/config/config.c new file mode 100644 index 000000000..fd0a2541b --- /dev/null +++ b/src/config/config.c @@ -0,0 +1,313 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Unified function to read the configuration */ + +#include +#include "shared.h" +#include "os_xml/os_xml.h" +#include "config.h" + +/* Prototypes */ +static int read_main_elements(const OS_XML *xml, int modules, + XML_NODE node, + void *d1, + void *d2); + + +/* Read the main elements of the configuration */ +static int read_main_elements(const OS_XML *xml, int modules, + XML_NODE node, + void *d1, + void *d2) +{ + int i = 0; + const char *osglobal = "global"; /* Server Config */ + const char *osrules = "rules"; /* Server Config */ + const char *ossyscheck = "syscheck"; /* Agent Config */ + const char *osrootcheck = "rootcheck"; /* Agent Config */ + const char *osalerts = "alerts"; /* Server Config */ + const char *osemailalerts = "email_alerts"; /* Server Config */ + const char *osdbd = "database_output"; /* Server Config */ + const char *oscsyslogd = "syslog_output"; /* Server Config */ + const char *oscagentless = "agentless"; /* Server Config */ + const char *oslocalfile = "localfile"; /* Agent Config */ + const char *osremote = "remote"; /* Agent Config */ + const char *osclient = "client"; /* Agent Config */ + const char *oscommand = "command"; /* ? Config */ + const char *osreports = "reports"; /* Server Config */ + const char *osactive_response = "active-response"; /* Agent Config */ + + while (node[i]) { + XML_NODE chld_node = NULL; + + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + goto fail; + } else if (!(chld_node = OS_GetElementsbyNode(xml, node[i]))) { + merror(XML_INVELEM, __local_name, node[i]->element); + goto fail; + } else if (strcmp(node[i]->element, osglobal) == 0) { + if (((modules & CGLOBAL) || (modules & CMAIL)) + && (Read_Global(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osemailalerts) == 0) { + if ((modules & CMAIL) && (Read_EmailAlerts(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osdbd) == 0) { + if ((modules & CDBD) && (Read_DB(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, oscsyslogd) == 0) { + if ((modules & CSYSLOGD) && (Read_CSyslog(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, oscagentless) == 0) { + if ((modules & CAGENTLESS) && (Read_CAgentless(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osrules) == 0) { + if ((modules & CRULES) && (Read_Rules(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, ossyscheck) == 0) { + if ((modules & CSYSCHECK) && (Read_Syscheck(chld_node, d1, d2) < 0)) { + goto fail; + } + if ((modules & CGLOBAL) && (Read_GlobalSK(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osrootcheck) == 0) { + if ((modules & CROOTCHECK) && (Read_Rootcheck(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osalerts) == 0) { + if ((modules & CALERTS) && (Read_Alerts(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, oslocalfile) == 0) { + if ((modules & CLOCALFILE) && (Read_Localfile(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osremote) == 0) { + if ((modules & CREMOTE) && (Read_Remote(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osclient) == 0) { + if ((modules & CCLIENT) && (Read_Client(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, oscommand) == 0) { + if ((modules & CAR) && (ReadActiveCommands(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osactive_response) == 0) { + if ((modules & CAR) && (ReadActiveResponses(chld_node, d1, d2) < 0)) { + goto fail; + } + } else if (strcmp(node[i]->element, osreports) == 0) { + if ((modules & CREPORTS) && (Read_CReports(chld_node, d1, d2) < 0)) { + goto fail; + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + goto fail; + } + + OS_ClearNode(chld_node); + i++; + + continue; + + fail: + OS_ClearNode(chld_node); + return (OS_INVALID); + } + + return (0); +} + +/* Read the config files */ +int ReadConfig(int modules, const char *cfgfile, void *d1, void *d2) +{ + int i; + OS_XML xml; + XML_NODE node; + + /** XML definitions **/ + /* Global */ + const char *xml_start_openarmor = "openarmor_config"; + const char *xml_start_agent = "agent_config"; + + /* Attributes of the tag */ + const char *xml_agent_name = "name"; + const char *xml_agent_os = "os"; + const char *xml_agent_overwrite = "overwrite"; + const char *xml_agent_profile = "profile"; + + int xml_ret = OS_ReadXML(cfgfile, &xml); + if (xml_ret < 0) { + char *tmpcfg; + tmpcfg = strdup(cfgfile); + const char *cfg_base = basename(tmpcfg); + if (!cfg_base) { + /* XXX */ + merror("ERROR: basename() failed: %s", strerror(errno)); + free(tmpcfg); + return (OS_INVALID); + } + if((strncmp(cfg_base, "agent.conf", 10)) == 0 && xml_ret == -2) { + debug2("WARN: Cannot open %s: %s", cfgfile, xml.err); + } else { + merror(XML_ERROR, __local_name, cfgfile, xml.err, xml.err_line); + } + free(tmpcfg); + return (OS_INVALID); + } + + node = OS_GetElementsbyNode(&xml, NULL); + if (!node) { + return (0); + } + + /* Read the main configuration */ + i = 0; + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + OS_ClearNode(node); + return (OS_INVALID); + } else if (!(modules & CAGENT_CONFIG) && + (strcmp(node[i]->element, xml_start_openarmor) == 0)) { + XML_NODE chld_node = NULL; + chld_node = OS_GetElementsbyNode(&xml, node[i]); + + /* Main element does not need to have any child */ + if (chld_node) { + if (read_main_elements(&xml, modules, chld_node, d1, d2) < 0) { + merror(CONFIG_ERROR, __local_name, cfgfile); + OS_ClearNode(chld_node); + OS_ClearNode(node); + return (OS_INVALID); + } + + OS_ClearNode(chld_node); + } + } else if ((modules & CAGENT_CONFIG) && + (strcmp(node[i]->element, xml_start_agent) == 0)) { + int passed_agent_test = 1; + int attrs = 0; + XML_NODE chld_node = NULL; + chld_node = OS_GetElementsbyNode(&xml, node[i]); + + /* Check if this is specific to any agent */ + if (node[i]->attributes && node[i]->values) { + while (node[i]->attributes[attrs] && node[i]->values[attrs]) { + /* Check if there is an "name=" attribute */ + if (strcmp(xml_agent_name, node[i]->attributes[attrs]) == 0) { +#ifdef CLIENT + char *agentname = os_read_agent_name(); + + if (!agentname) { + passed_agent_test = 0; + } else { + if (!OS_Match2(node[i]->values[attrs], agentname)) { + passed_agent_test = 0; + } + free(agentname); + } +#endif + } else if (strcmp(xml_agent_os, node[i]->attributes[attrs]) == 0) { +#ifdef CLIENT + char *agentos = getuname(); + + if (agentos) { + if (!OS_Match2(node[i]->values[attrs], agentos)) { + passed_agent_test = 0; + } + free(agentos); + } else { + passed_agent_test = 0; + merror("%s: ERROR: Unable to retrieve uname.", __local_name); + } +#endif + } else if (strcmp(xml_agent_profile, node[i]->attributes[attrs]) == 0) { +#ifdef CLIENT + char *agentprofile = os_read_agent_profile(); + debug2("Read agent config profile name [%s]", agentprofile); + + if (!agentprofile) { + passed_agent_test = 0; + } else { + /* match the profile name of this section + * with a comma separated list of values in agent's + * tag. + */ + if (!OS_Match2(node[i]->values[attrs], agentprofile)) { + passed_agent_test = 0; + debug2("[%s] did not match agent config profile name [%s]", + node[i]->values[attrs], agentprofile); + } else { + debug2("Matched agent config profile name [%s]", agentprofile); + } + free(agentprofile); + } +#endif + } else if (strcmp(xml_agent_overwrite, node[i]->attributes[attrs]) == 0) { + } else { + merror(XML_INVATTR, __local_name, node[i]->attributes[attrs], + cfgfile); + } + attrs++; + } + } +#ifdef CLIENT + else { + debug2("agent_config element does not have any attributes."); + + /* if node does not have any attributes, it is a generic config block. + * check if agent has a profile name + * if agent does not have profile name, then only read this generic + * agent_config block + */ + + if (!os_read_agent_profile()) { + debug2("but agent has a profile name."); + passed_agent_test = 0; + } + } +#endif + + /* Main element does not need to have any child */ + if (chld_node) { + if (passed_agent_test && read_main_elements(&xml, modules, chld_node, d1, d2) < 0) { + merror(CONFIG_ERROR, __local_name, cfgfile); + OS_ClearNode(chld_node); + OS_ClearNode(node); + return (OS_INVALID); + } + + OS_ClearNode(chld_node); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + OS_ClearNode(node); + return (OS_INVALID); + } + i++; + } + + /* Clear node and xml */ + OS_ClearNode(node); + OS_ClearXML(&xml); + return (0); +} + diff --git a/src/config/config.h b/src/config/config.h new file mode 100644 index 000000000..7acc2acf4 --- /dev/null +++ b/src/config/config.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _HCONFIG__H +#define _HCONFIG__H + +#define CGLOBAL 0000001 +#define CRULES 0000002 +#define CSYSCHECK 0000004 +#define CROOTCHECK 0000010 +#define CALERTS 0000020 +#define CLOCALFILE 0000040 +#define CREMOTE 0000100 +#define CCLIENT 0000200 +#define CMAIL 0000400 +#define CAR 0001000 +#define CDBD 0002000 +#define CSYSLOGD 0004000 +#define CAGENTLESS 0020000 +#define CREPORTS 0040000 + +#define CAGENT_CONFIG 0010000 + +#include "os_xml/os_xml.h" + +/* Main function to read the config */ +int ReadConfig(int modules, const char *cfgfile, void *d1, void *d2); + +int Read_Global(XML_NODE node, void *d1, void *d2); +int Read_GlobalSK(XML_NODE node, void *configp, void *mailp); +int Read_Rules(XML_NODE node, void *d1, void *d2); +int Read_Syscheck(XML_NODE node, void *d1, void *d2); +int Read_Rootcheck(XML_NODE node, void *d1, void *d2); +int Read_Alerts(XML_NODE node, void *d1, void *d2); +int Read_EmailAlerts(XML_NODE node, void *d1, void *d2); +int Read_DB(XML_NODE node, void *config1, void *config2); +int Read_CSyslog(XML_NODE node, void *config1, void *config2); +int Read_CAgentless(XML_NODE node, void *config1, void *config2); +int Read_Localfile(XML_NODE node, void *d1, void *d2); +int Read_Remote(XML_NODE node, void *d1, void *d2); +int Read_Client(XML_NODE node, void *d1, void *d2); +int ReadActiveResponses(XML_NODE node, void *d1, void *d2); +int ReadActiveCommands(XML_NODE node, void *d1, void *d2); +int Read_CReports(XML_NODE node, void *config1, void *config2); + +#endif /* _HCONFIG__H */ diff --git a/src/config/csyslogd-config.c b/src/config/csyslogd-config.c new file mode 100644 index 000000000..6ca65d8a7 --- /dev/null +++ b/src/config/csyslogd-config.c @@ -0,0 +1,208 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "csyslogd-config.h" +#include "config.h" + + +int Read_CSyslog(XML_NODE node, void *config, __attribute__((unused)) void *config2) +{ + unsigned int i = 0, s = 0; + + /* XML definitions */ + const char *xml_syslog_server = "server"; + const char *xml_syslog_port = "port"; + const char *xml_syslog_format = "format"; + const char *xml_syslog_level = "level"; + const char *xml_syslog_id = "rule_id"; + const char *xml_syslog_group = "group"; + const char *xml_syslog_location = "location"; + const char *xml_syslog_use_fqdn = "use_fqdn"; + + struct SyslogConfig_holder *config_holder = (struct SyslogConfig_holder *)config; + SyslogConfig **syslog_config = config_holder->data; + + if (syslog_config) { + while (syslog_config[s]) { + s++; + } + } + + /* Allocate the memory for the config */ + os_realloc(syslog_config, (s + 2) * sizeof(SyslogConfig *), syslog_config); + os_calloc(1, sizeof(SyslogConfig), syslog_config[s]); + syslog_config[s + 1] = NULL; + + /* Zero the elements */ + syslog_config[s]->server = NULL; + syslog_config[s]->rule_id = NULL; + syslog_config[s]->group = NULL; + syslog_config[s]->location = NULL; + syslog_config[s]->level = 0; + syslog_config[s]->port = "514"; + syslog_config[s]->format = DEFAULT_CSYSLOG; + syslog_config[s]->use_fqdn = 0; + /* local 0 facility (16) + severity 4 - warning. --default */ + syslog_config[s]->priority = (16 * 8) + 4; + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + goto fail; + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + goto fail; + } else if (strcmp(node[i]->element, xml_syslog_level) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto fail; + } + + syslog_config[s]->level = (unsigned int) atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_syslog_port) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto fail; + } + + os_strdup(node[i]->content, syslog_config[s]->port); + } else if (strcmp(node[i]->element, xml_syslog_server) == 0) { + os_strdup(node[i]->content, syslog_config[s]->server); + } else if (strcmp(node[i]->element, xml_syslog_id) == 0) { + unsigned int r_id = 0; + char *str_pt = node[i]->content; + + while (*str_pt != '\0') { + /* We allow spaces in between */ + if (*str_pt == ' ') { + str_pt++; + continue; + } + + /* If is digit, we get the value + * and search for the next digit + * available + */ + else if (isdigit((int)*str_pt)) { + unsigned int id_i = 0; + + r_id = (unsigned int) atoi(str_pt); + debug1("%s: DEBUG: Adding '%d' to syslog alerting", + __local_name, r_id); + + if (syslog_config[s]->rule_id) { + while (syslog_config[s]->rule_id[id_i]) { + id_i++; + } + } + + os_realloc(syslog_config[s]->rule_id, + (id_i + 2) * sizeof(unsigned int), + syslog_config[s]->rule_id); + + syslog_config[s]->rule_id[id_i + 1] = 0; + syslog_config[s]->rule_id[id_i] = r_id; + + str_pt = strchr(str_pt, ','); + if (str_pt) { + str_pt++; + } else { + break; + } + } + + /* Check for duplicate commas */ + else if (*str_pt == ',') { + str_pt++; + continue; + } + + else { + break; + } + } + + } else if (strcmp(node[i]->element, xml_syslog_format) == 0) { + if (strcmp(node[i]->content, "default") == 0) { + /* Default is full format */ + } else if (strcmp(node[i]->content, "cef") == 0) { + /* Enable the CEF format */ + syslog_config[s]->format = CEF_CSYSLOG; + } else if (strcmp(node[i]->content, "json") == 0) { + /* Enable the JSON format */ + syslog_config[s]->format = JSON_CSYSLOG; + } else if (strcmp(node[i]->content, "splunk") == 0) { + /* Enable the Splunk Key/Value format */ + syslog_config[s]->format = SPLUNK_CSYSLOG; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto fail; + } + } else if (strcmp(node[i]->element, xml_syslog_location) == 0) { + os_calloc(1, sizeof(OSMatch), syslog_config[s]->location); + if (!OSMatch_Compile(node[i]->content, + syslog_config[s]->location, 0)) { + merror(REGEX_COMPILE, __local_name, node[i]->content, + syslog_config[s]->location->error); + goto fail; + } + } else if (strcmp(node[i]->element, xml_syslog_use_fqdn) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + syslog_config[s]->use_fqdn = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + syslog_config[s]->use_fqdn = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + goto fail; + } + } else if (strcmp(node[i]->element, xml_syslog_group) == 0) { + os_calloc(1, sizeof(OSMatch), syslog_config[s]->group); + if (!OSMatch_Compile(node[i]->content, + syslog_config[s]->group, 0)) { + merror(REGEX_COMPILE, __local_name, node[i]->content, + syslog_config[s]->group->error); + goto fail; + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + goto fail; + } + i++; + } + + /* We must have at least one entry set */ + if (!syslog_config[s]->server) { + merror(XML_INV_CSYSLOG, __local_name); + goto fail; + } + + config_holder->data = syslog_config; + return (0); + +fail: + i = 0; + while (syslog_config[i]) { + free(syslog_config[i]->server); + + if (syslog_config[i]->group) { + OSMatch_FreePattern(syslog_config[i]->group); + } + + if (syslog_config[i]->location) { + OSMatch_FreePattern(syslog_config[i]->location); + } + + free(syslog_config[i]->rule_id); + + ++i; + } + free(syslog_config); + return (OS_INVALID); +} + diff --git a/src/config/csyslogd-config.h b/src/config/csyslogd-config.h new file mode 100644 index 000000000..087429b1b --- /dev/null +++ b/src/config/csyslogd-config.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" + +#ifndef _CSYSLOGCONFIG__H +#define _CSYSLOGCONFIG__H + +/* Database config structure */ +typedef struct _SyslogConfig { + char *port; + unsigned int format; + unsigned int level; + unsigned int *rule_id; + unsigned int priority; + unsigned int use_fqdn; + int socket; + + char *server; + OSMatch *group; + OSMatch *location; +} SyslogConfig; + +struct SyslogConfig_holder { + SyslogConfig **data; +}; + +/* Syslog formats */ +#define DEFAULT_CSYSLOG 0 +#define CEF_CSYSLOG 1 +#define JSON_CSYSLOG 2 +#define SPLUNK_CSYSLOG 3 + +/* Syslog severities */ +#define SLOG_EMERG 0 /* system is unusable */ +#define SLOG_ALERT 1 /* action must be taken immediately */ +#define SLOG_CRIT 2 /* critical conditions */ +#define SLOG_ERR 3 /* error conditions */ +#define SLOG_WARNING 4 /* warning conditions */ +#define SLOG_NOTICE 5 /* normal but significant condition */ +#define SLOG_INFO 6 /* informational */ +#define SLOG_DEBUG 7 /* debug-level messages */ + +#endif /* _CSYSLOGCONFIG__H */ diff --git a/src/config/dbd-config.c b/src/config/dbd-config.c new file mode 100644 index 000000000..1dfa4ccb5 --- /dev/null +++ b/src/config/dbd-config.c @@ -0,0 +1,74 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "dbd-config.h" +#include "config.h" + + +int Read_DB(XML_NODE node, __attribute__((unused)) void *config1, void *config2) +{ + int i = 0; + DBConfig *db_config; + + /* XML definitions */ + const char *xml_dbhost = "hostname"; + const char *xml_dbuser = "username"; + const char *xml_dbpass = "password"; + const char *xml_dbdb = "database"; + const char *xml_dbport = "port"; + const char *xml_dbsock = "socket"; + const char *xml_dbtype = "type"; + + db_config = (DBConfig *)config2; + if (!db_config) { + return (0); + } + + /* Read the xml */ + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + /* Mail notification */ + else if (strcmp(node[i]->element, xml_dbhost) == 0) { + os_strdup(node[i]->content, db_config->host); + } else if (strcmp(node[i]->element, xml_dbuser) == 0) { + os_strdup(node[i]->content, db_config->user); + } else if (strcmp(node[i]->element, xml_dbpass) == 0) { + os_strdup(node[i]->content, db_config->pass); + } else if (strcmp(node[i]->element, xml_dbdb) == 0) { + os_strdup(node[i]->content, db_config->db); + } else if (strcmp(node[i]->element, xml_dbport) == 0) { + db_config->port = (unsigned int) atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_dbsock) == 0) { + os_strdup(node[i]->content, db_config->sock); + } else if (strcmp(node[i]->element, xml_dbtype) == 0) { + if (strcmp(node[i]->content, "mysql") == 0) { + db_config->db_type = MYSQLDB; + } else if (strcmp(node[i]->content, "postgresql") == 0) { + db_config->db_type = POSTGDB; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + return (0); +} + diff --git a/src/config/dbd-config.h b/src/config/dbd-config.h new file mode 100644 index 000000000..f24653f36 --- /dev/null +++ b/src/config/dbd-config.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _DBDCONFIG__H +#define _DBDCONFIG__H + +/* Database config structure */ +typedef struct _DBConfig { + unsigned int db_type; + unsigned int alert_id; + unsigned int server_id; + unsigned int error_count; + unsigned int maxreconnect; + unsigned int port; + + char *host; + char *user; + char *pass; + char *db; + char *sock; + + void *conn; + OSHash *location_hash; + + char **includes; +} DBConfig; + +#define MYSQLDB 0x002 +#define POSTGDB 0x004 + +#endif /* _DBDCONFIG__H */ + diff --git a/src/config/email-alerts-config.c b/src/config/email-alerts-config.c new file mode 100644 index 000000000..d9ea22aeb --- /dev/null +++ b/src/config/email-alerts-config.c @@ -0,0 +1,210 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ +#include "shared.h" +#include "mail-config.h" +#include "config.h" + + +int Read_EmailAlerts(XML_NODE node, __attribute__((unused)) void *configp, void *mailp) +{ + int i = 0; + unsigned int granto_size = 0; + + /* XML definitions */ + const char *xml_email_to = "email_to"; + const char *xml_email_format = "format"; + const char *xml_email_level = "level"; + const char *xml_email_id = "rule_id"; + const char *xml_email_group = "group"; + const char *xml_email_location = "event_location"; + const char *xml_email_donotdelay = "do_not_delay"; + const char *xml_email_donotgroup = "do_not_group"; + + MailConfig *Mail; + + Mail = (MailConfig *)mailp; + if (!Mail) { + return (0); + } + + /* Get Granular mail_to size */ + if (Mail && Mail->gran_to) { + char **ww; + ww = Mail->gran_to; + while (*ww != NULL) { + ww++; + granto_size++; + } + } + + if (Mail) { + os_realloc(Mail->gran_to, + sizeof(char *) * (granto_size + 2), Mail->gran_to); + os_realloc(Mail->gran_id, + sizeof(unsigned int *) * (granto_size + 2), Mail->gran_id); + os_realloc(Mail->gran_level, + sizeof(unsigned int) * (granto_size + 2), Mail->gran_level); + os_realloc(Mail->gran_set, + sizeof(int) * (granto_size + 2), Mail->gran_set); + os_realloc(Mail->gran_format, + sizeof(int) * (granto_size + 2), Mail->gran_format); + os_realloc(Mail->gran_location, + sizeof(OSMatch *) * (granto_size + 2), Mail->gran_location); + os_realloc(Mail->gran_group, + sizeof(OSMatch *) * (granto_size + 2), Mail->gran_group); + + Mail->gran_to[granto_size] = NULL; + Mail->gran_to[granto_size + 1] = NULL; + + Mail->gran_id[granto_size] = NULL; + Mail->gran_id[granto_size + 1] = NULL; + + Mail->gran_location[granto_size] = NULL; + Mail->gran_location[granto_size + 1] = NULL; + + Mail->gran_group[granto_size] = NULL; + Mail->gran_group[granto_size + 1] = NULL; + + Mail->gran_level[granto_size] = 0; + Mail->gran_level[granto_size + 1] = 0; + + Mail->gran_format[granto_size] = FULL_FORMAT; + Mail->gran_format[granto_size + 1] = FULL_FORMAT; + + Mail->gran_set[granto_size] = 0; + Mail->gran_set[granto_size + 1] = 0; + } + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + /* Mail notification */ + else if (strcmp(node[i]->element, xml_email_level) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + Mail->gran_level[granto_size] = atoi(node[i]->content); + } else if (strcmp(node[i]->element, xml_email_to) == 0) { + os_strdup(node[i]->content, Mail->gran_to[granto_size]); + } else if (strcmp(node[i]->element, xml_email_id) == 0) { + int r_id = 0; + char *str_pt = node[i]->content; + + while (*str_pt != '\0') { + /* We allow spaces in between */ + if (*str_pt == ' ') { + str_pt++; + continue; + } + + /* If is digit, we get the value and + * search for the next digit available + */ + else if (isdigit((int)*str_pt)) { + unsigned int id_i = 0; + + r_id = atoi(str_pt); + debug1("%s: DEBUG: Adding '%d' to granular e-mail", + __local_name, r_id); + + if (!Mail->gran_id[granto_size]) { + os_calloc(2, sizeof(unsigned int), Mail->gran_id[granto_size]); + Mail->gran_id[granto_size][0] = 0; + Mail->gran_id[granto_size][1] = 0; + } else { + while (Mail->gran_id[granto_size][id_i] != 0) { + id_i++; + } + + os_realloc(Mail->gran_id[granto_size], + (id_i + 2) * sizeof(unsigned int), + Mail->gran_id[granto_size]); + Mail->gran_id[granto_size][id_i + 1] = 0; + } + Mail->gran_id[granto_size][id_i] = r_id; + + str_pt = strchr(str_pt, ','); + if (str_pt) { + str_pt++; + } else { + break; + } + } + + /* Check for duplicate commas */ + else if (*str_pt == ',') { + str_pt++; + continue; + } + + else { + break; + } + } + + } else if (strcmp(node[i]->element, xml_email_format) == 0) { + if (strcmp(node[i]->content, "default") == 0) { + /* Default is full format */ + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_email_donotdelay) == 0) { + if ((Mail->gran_format[granto_size] != SMS_FORMAT) && + (Mail->gran_format[granto_size] != DONOTGROUP)) { + Mail->gran_format[granto_size] = FORWARD_NOW; + } + } else if (strcmp(node[i]->element, xml_email_donotgroup) == 0) { + if (Mail->gran_format[granto_size] != SMS_FORMAT) { + Mail->gran_format[granto_size] = DONOTGROUP; + } + } else if (strcmp(node[i]->element, xml_email_location) == 0) { + os_calloc(1, sizeof(OSMatch), Mail->gran_location[granto_size]); + if (!OSMatch_Compile(node[i]->content, + Mail->gran_location[granto_size], 0)) { + merror(REGEX_COMPILE, __local_name, node[i]->content, + Mail->gran_location[granto_size]->error); + return (-1); + } + } else if (strcmp(node[i]->element, xml_email_group) == 0) { + os_calloc(1, sizeof(OSMatch), Mail->gran_group[granto_size]); + if (!OSMatch_Compile(node[i]->content, + Mail->gran_group[granto_size], 0)) { + merror(REGEX_COMPILE, __local_name, node[i]->content, + Mail->gran_group[granto_size]->error); + return (-1); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + /* We must have at least one entry set */ + if ((Mail->gran_location[granto_size] == NULL && + Mail->gran_level[granto_size] == 0 && + Mail->gran_group[granto_size] == NULL && + Mail->gran_id[granto_size] == NULL && + Mail->gran_format[granto_size] == FULL_FORMAT) || + Mail->gran_to[granto_size] == NULL) { + merror(XML_INV_GRAN_MAIL, __local_name); + return (OS_INVALID); + } + + return (0); +} + diff --git a/src/config/global-config.c b/src/config/global-config.c new file mode 100644 index 000000000..0449a8c94 --- /dev/null +++ b/src/config/global-config.c @@ -0,0 +1,523 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_net/os_net.h" +#include "global-config.h" +#include "mail-config.h" +#include "config.h" + + +int Read_GlobalSK(XML_NODE node, void *configp, __attribute__((unused)) void *mailp) +{ + int i = 0; + unsigned int ign_size = 1; + const char *xml_ignore = "ignore"; + const char *xml_auto_ignore = "auto_ignore"; + const char *xml_alert_new_files = "alert_new_files"; + + _Config *Config; + Config = (_Config *)configp; + + if (!Config) { + return (0); + } + + /* Get right allow_size */ + if (Config && Config->syscheck_ignore) { + char **ww; + ww = Config->syscheck_ignore; + + while (*ww != NULL) { + ign_size++; + ww++; + } + } + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } else if (strcmp(node[i]->element, xml_auto_ignore) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + Config->syscheck_auto_ignore = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + Config->syscheck_auto_ignore = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_alert_new_files) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + Config->syscheck_alert_new = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + Config->syscheck_alert_new = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_ignore) == 0) { + ign_size++; + Config->syscheck_ignore = (char **) + realloc(Config->syscheck_ignore, sizeof(char *)*ign_size); + if (!Config->syscheck_ignore) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_strdup(node[i]->content, Config->syscheck_ignore[ign_size - 2]); + Config->syscheck_ignore[ign_size - 1] = NULL; + } + i++; + } + + return (0); +} + +int Read_Global(XML_NODE node, void *configp, void *mailp) +{ + int i = 0; + + /* allowlist size */ + unsigned int allow_size = 1; + unsigned int hostname_allow_size = 1; + unsigned int mailto_size = 1; + + /* XML definitions */ + const char *xml_mailnotify = "email_notification"; + const char *xml_logall = "logall"; + const char *xml_logall_json = "logall_json"; + const char *xml_integrity = "integrity_checking"; + const char *xml_rootcheckd = "rootkit_detection"; + const char *xml_hostinfo = "host_information"; + const char *xml_prelude = "prelude_output"; + const char *xml_prelude_profile = "prelude_profile"; + const char *xml_prelude_log_level = "prelude_log_level"; + const char *xml_geoipdb_file = "geoipdb"; + const char *xml_zeromq_output = "zeromq_output"; + const char *xml_zeromq_output_uri = "zeromq_uri"; + const char *xml_zeromq_output_server_cert = "zeromq_server_cert"; + const char *xml_zeromq_output_client_cert = "zeromq_client_cert"; + const char *xml_jsonout_output = "jsonout_output"; + const char *xml_stats = "stats"; + const char *xml_memorysize = "memory_size"; + const char *xml_white_list = "white_list"; + const char *xml_allow_list = "allow_list"; + const char *xml_compress_alerts = "compress_alerts"; + const char *xml_custom_alert_output = "custom_alert_output"; + + const char *xml_emailto = "email_to"; + const char *xml_emailfrom = "email_from"; + const char *xml_emailreplyto = "email_reply_to"; + const char *xml_emailidsname = "email_idsname"; + const char *xml_smtpserver = "smtp_server"; + const char *xml_heloserver = "helo_server"; + const char *xml_mailmaxperhour = "email_maxperhour"; + +#ifdef LIBGEOIP_ENABLED + const char *xml_geoip_db_path = "geoip_db_path"; + const char *xml_geoip6_db_path = "geoip6_db_path"; +#endif + +#ifdef SQLITE_ENABLED + /* MD5 DB */ + char *xml_md5_whitelist = "md5_whitelist"; + char *xml_md5_allowlist = "md5_allowlist"; +#endif + + _Config *Config; + MailConfig *Mail; + + Config = (_Config *)configp; + Mail = (MailConfig *)mailp; + + /* Get right allow_size */ + if (Config && Config->allow_list) { + os_ip **ww; + ww = Config->allow_list; + + while (*ww != NULL) { + allow_size++; + ww++; + } + } + + /* Get right allow_size */ + if (Config && Config->hostname_allow_list) { + char **ww; + ww = Config->hostname_allow_list; + + while (*ww != NULL) { + hostname_allow_size++; + ww++; + } + } + + /* Get mail_to size */ + if (Mail && Mail->to) { + char **ww; + ww = Mail->to; + while (*ww != NULL) { + mailto_size++; + ww++; + } + } + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } else if (strcmp(node[i]->element, xml_custom_alert_output) == 0) { + if (Config) { + Config->custom_alert_output = 1; + os_strdup(node[i]->content, Config->custom_alert_output_format); + } + } + /* Mail notification */ + else if (strcmp(node[i]->element, xml_mailnotify) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + if (Config) { + Config->mailnotify = 1; + } + if (Mail) { + Mail->mn = 1; + } + } else if (strcmp(node[i]->content, "no") == 0) { + if (Config) { + Config->mailnotify = 0; + } + if (Mail) { + Mail->mn = 0; + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + /* Prelude support */ + else if (strcmp(node[i]->element, xml_prelude) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + if (Config) { + Config->prelude = 1; + } + } else if (strcmp(node[i]->content, "no") == 0) { + if (Config) { + Config->prelude = 0; + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + /* GeoIP */ + } else if(strcmp(node[i]->element, xml_geoipdb_file) == 0) { + if(Config) + { + Config->geoipdb_file = strdup(node[i]->content); + } + } else if (strcmp(node[i]->element, xml_prelude_profile) == 0) { + if (Config) { + Config->prelude_profile = strdup(node[i]->content); + } + } else if (strcmp(node[i]->element, xml_prelude_log_level) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + if (Config) { + Config->prelude_log_level = (u_int8_t) atoi(node[i]->content); + } + } + /* ZeroMQ output */ + else if (strcmp(node[i]->element, xml_zeromq_output) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + if (Config) { + Config->zeromq_output = 1; + } + } else if (strcmp(node[i]->content, "no") == 0) { + if (Config) { + Config->zeromq_output = 0; + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_zeromq_output_uri) == 0) { + if (Config) { + Config->zeromq_output_uri = strdup(node[i]->content); + } + } else if (strcmp(node[i]->element, xml_zeromq_output_server_cert) == 0) { + if (Config) { + Config->zeromq_output_server_cert = strdup(node[i]->content); + } + } else if (strcmp(node[i]->element, xml_zeromq_output_client_cert) == 0) { + if (Config) { + Config->zeromq_output_client_cert = strdup(node[i]->content); + } + } + /* jsonout output */ + else if (strcmp(node[i]->element, xml_jsonout_output) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + if (Config) { + Config->jsonout_output = 1; + } + } else if (strcmp(node[i]->content, "no") == 0) { + if (Config) { + Config->jsonout_output = 0; + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + /* Log all */ + else if (strcmp(node[i]->element, xml_logall) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + if (Config) { + Config->logall = 1; + } + } else if (strcmp(node[i]->content, "no") == 0) { + if (Config) { + Config->logall = 0; + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + /* Log all JSON*/ + else if (strcmp(node[i]->element, xml_logall_json) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + if (Config) { + Config->logall_json = 1; + } + } else if (strcmp(node[i]->content, "no") == 0) { + if (Config) { + Config->logall_json = 0; + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + /* Compress alerts */ + else if (strcmp(node[i]->element, xml_compress_alerts) == 0) { + /* removed from here -- compatibility issues only */ + } + /* Integrity */ + else if (strcmp(node[i]->element, xml_integrity) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + if (Config) { + Config->integrity = (u_int8_t) atoi(node[i]->content); + } + } + /* rootcheck */ + else if (strcmp(node[i]->element, xml_rootcheckd) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + if (Config) { + Config->rootcheck = (u_int8_t) atoi(node[i]->content); + } + } + /* hostinfo */ + else if (strcmp(node[i]->element, xml_hostinfo) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + if (Config) { + Config->hostinfo = (u_int8_t) atoi(node[i]->content); + } + } + /* stats */ + else if (strcmp(node[i]->element, xml_stats) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + if (Config) { + Config->stats = (u_int8_t) atoi(node[i]->content); + } + } else if (strcmp(node[i]->element, xml_memorysize) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + if (Config) { + Config->memorysize = atoi(node[i]->content); + } + } + /* allowlist */ + else if ((strcmp(node[i]->element, xml_white_list) == 0) || (strcmp(node[i]->element, xml_allow_list) == 0)) { + /* Windows do not need it */ +#ifndef WIN32 + + const char *ip_address_regex = + "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/?" + "([0-9]{0,2}|[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})$"; + + if (Config && OS_PRegex(node[i]->content, ip_address_regex)) { + allow_size++; + Config->allow_list = (os_ip **) + realloc(Config->allow_list, sizeof(os_ip *)*allow_size); + if (!Config->allow_list) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_calloc(1, sizeof(os_ip), Config->allow_list[allow_size - 2]); + Config->allow_list[allow_size - 1] = NULL; + + if (!OS_IsValidIP(node[i]->content, + Config->allow_list[allow_size - 2])) { + merror(INVALID_IP, __local_name, + node[i]->content); + return (OS_INVALID); + } + } + /* Add hostname */ + else if (Config) { + hostname_allow_size++; + Config->hostname_allow_list = (char **) + realloc(Config->hostname_allow_list, + sizeof(char *)*hostname_allow_size); + + if (!Config->hostname_allow_list) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + os_strdup(node[i]->content, Config->hostname_allow_list[hostname_allow_size - 2]); + Config->hostname_allow_list[hostname_allow_size - 1] = NULL; + } +#endif + + } + + /* For the email now + * email_to, email_from, email_replyto, idsname, smtp_Server and maxperhour. + * We will use a separate structure for that. + */ + else if (strcmp(node[i]->element, xml_emailto) == 0) { +#ifndef WIN32 + if (!OS_PRegex(node[i]->content, "[a-zA-Z0-9\\._-]+@[a-zA-Z0-9\\._-]")) { + merror("%s: ERROR: Invalid Email address: %s.", __local_name, node[i]->content); + return (OS_INVALID); + } +#endif + if (Mail) { + mailto_size++; + Mail->to = (char **) realloc(Mail->to, sizeof(char *)*mailto_size); + if (!Mail->to) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_strdup(node[i]->content, Mail->to[mailto_size - 2]); + Mail->to[mailto_size - 1] = NULL; + } + } else if (strcmp(node[i]->element, xml_emailfrom) == 0) { + if (Mail) { + if (Mail->from) { + free(Mail->from); + } + os_strdup(node[i]->content, Mail->from); + } + } else if (strcmp(node[i]->element, xml_emailreplyto) == 0) { + if (Mail) { + if (Mail->reply_to) { + free(Mail->reply_to); + } + os_strdup(node[i]->content, Mail->reply_to); + } + } else if (strcmp(node[i]->element, xml_emailidsname) == 0) { + if (Mail) { + if (Mail->idsname) { + free(Mail->idsname); + } + os_strdup(node[i]->content, Mail->idsname); + } + } else if (strcmp(node[i]->element, xml_smtpserver) == 0) { +#ifndef WIN32 + if (Mail && (Mail->mn)) { + if (node[i]->content[0] == '/') { + os_strdup(node[i]->content, Mail->smtpserver); + } else { + Mail->smtpserver = OS_GetHost(node[i]->content, 5); + if (!Mail->smtpserver) { + merror(INVALID_SMTP, __local_name, node[i]->content); + return (OS_INVALID); + } + } + free(Mail->smtpserver); + os_strdup(node[i]->content, Mail->smtpserver); + } +#endif + } else if (strcmp(node[i]->element, xml_heloserver) == 0) { + if (Mail && (Mail->mn)) { + os_strdup(node[i]->content, Mail->heloserver); + } + } else if (strcmp(node[i]->element, xml_mailmaxperhour) == 0) { + if (Mail) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + Mail->maxperhour = atoi(node[i]->content); + + if ((Mail->maxperhour <= 0) || (Mail->maxperhour > 9999)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + } +#ifdef LIBGEOIP_ENABLED + /* GeoIP v4 DB location */ + else if (strcmp(node[i]->element, xml_geoip_db_path) == 0) { + if (Config) { + os_strdup(node[i]->content, Config->geoip_db_path); + } + } + /* GeoIP v6 DB location */ + else if (strcmp(node[i]->element, xml_geoip6_db_path) == 0) { + if (Config) { + os_strdup(node[i]->content, Config->geoip6_db_path); + } + } +#endif + +#ifdef SQLITE_ENABLED + /* MD5 DB */ + else if((strcmp(node[i]->element, xml_md5_allowlist) == 0) || (strcmp(node[i]->element, xml_md5_whitelist) == 0)) { + if(Config) { + os_strdup(node[i]->content, Config->md5_allowlist); + } + } +#endif + + else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + return (0); +} + diff --git a/src/config/global-config.h b/src/config/global-config.h new file mode 100644 index 000000000..774466335 --- /dev/null +++ b/src/config/global-config.h @@ -0,0 +1,101 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _CCONFIG__H +#define _CCONFIG__H + +#include "shared.h" + +/* Configuration structure */ +typedef struct __Config { + u_int8_t logall; + u_int8_t logall_json; + u_int8_t stats; + u_int8_t integrity; + u_int8_t syscheck_auto_ignore; + u_int8_t syscheck_alert_new; + u_int8_t rootcheck; + u_int8_t hostinfo; + u_int8_t mailbylevel; + u_int8_t logbylevel; + u_int8_t logfw; + int decoder_order_size; + + + /* Prelude support */ + u_int8_t prelude; + /* which min. level the alert must be sent to prelude */ + u_int8_t prelude_log_level; + /* prelude profile name */ + char *prelude_profile; + + /* GeoIP DB */ + char *geoipdb_file; + + /* ZEROMQ Export */ + u_int8_t zeromq_output; + char *zeromq_output_uri; + char *zeromq_output_server_cert; + char *zeromq_output_client_cert; + + /* JSONOUT Export */ + u_int8_t jsonout_output; + + /* Not currently used */ + u_int8_t keeplogdate; + + /* Mail alerting */ + short int mailnotify; + + /* Custom Alert output*/ + short int custom_alert_output; + char *custom_alert_output_format; + + /* For the active response */ + int ar; + + /* For the correlation */ + int memorysize; + + /* List of files to ignore (syscheck) */ + char **syscheck_ignore; + + /* List of ips to never block */ + os_ip **allow_list; + + /* List of hostnames to never block */ + char **hostname_allow_list; + + /* List of rules */ + char **includes; + + /* List of Lists */ + char **lists; + + /* List of decoders */ + char **decoders; + + /* Global rule hash */ + OSHash *g_rules_hash; + +#ifdef LIBGEOIP_ENABLED + /* GeoIP support */ + u_int8_t loggeoip; + char *geoip_db_path; + char *geoip6_db_path; + int geoip_jsonout; +#endif + + /* MD5 DB support */ + char *md5_allowlist; + +} _Config; + +#endif /* _CCONFIG__H */ + diff --git a/src/config/localfile-config.c b/src/config/localfile-config.c new file mode 100644 index 000000000..cb22e7d4a --- /dev/null +++ b/src/config/localfile-config.c @@ -0,0 +1,395 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "localfile-config.h" +#include "config.h" + + +int Read_Localfile(XML_NODE node, void *d1, __attribute__((unused)) void *d2) +{ + unsigned int pl = 0; + unsigned int i = 0; + unsigned int glob_set = 0; +#ifndef WIN32 + int glob_offset = 0; +#endif + + /* XML Definitions */ + const char *xml_localfile_location = "location"; + const char *xml_localfile_command = "command"; + const char *xml_localfile_logformat = "log_format"; + const char *xml_localfile_frequency = "frequency"; + const char *xml_localfile_alias = "alias"; + const char *xml_localfile_future = "only-future-events"; + const char *xml_localfile_query = "query"; + + logreader *logf; + logreader_config *log_config; + + log_config = (logreader_config *)d1; + + /* If config is not set, create it */ + if (!log_config->config) { + os_calloc(2, sizeof(logreader), log_config->config); + logf = log_config->config; + logf[0].file = NULL; + logf[0].command = NULL; + logf[0].alias = NULL; + logf[0].logformat = NULL; + logf[0].future = 0; + logf[0].query = NULL; + logf[1].file = NULL; + logf[1].command = NULL; + logf[1].alias = NULL; + logf[1].logformat = NULL; + logf[1].future = 0; + logf[1].query = NULL; + } else { + logf = log_config->config; + while (logf[pl].file != NULL) { + pl++; + } + + /* Allocate more memory */ + os_realloc(logf, (pl + 2)*sizeof(logreader), log_config->config); + logf = log_config->config; + logf[pl + 1].file = NULL; + logf[pl + 1].command = NULL; + logf[pl + 1].alias = NULL; + logf[pl + 1].logformat = NULL; + logf[pl + 1].future = 0; + logf[pl + 1].query = NULL; + } + + logf[pl].file = NULL; + logf[pl].command = NULL; + logf[pl].alias = NULL; + logf[pl].logformat = NULL; + logf[pl].future = 0; + logf[pl].query = NULL; + logf[pl].fp = NULL; + logf[pl].ffile = NULL; + logf[pl].djb_program_name = NULL; + logf[pl].ign = 360; + + + /* Search for entries related to files */ + i = 0; + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } else if (strcmp(node[i]->element, xml_localfile_future) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + logf[pl].future = 1; + } + } else if (strcmp(node[i]->element, xml_localfile_query) == 0) { + os_strdup(node[i]->content, logf[pl].query); + } else if (strcmp(node[i]->element, xml_localfile_command) == 0) { + /* We don't accept remote commands from the manager - just in case */ + if (log_config->agent_cfg == 1 && log_config->accept_remote == 0) { + merror("%s: Remote commands are not accepted from the manager. " + "Ignoring it on the agent.conf", __local_name); + + logf[pl].file = NULL; + logf[pl].ffile = NULL; + logf[pl].command = NULL; + logf[pl].alias = NULL; + logf[pl].logformat = NULL; + logf[pl].fp = NULL; + return (OS_INVALID); + } + + os_strdup(node[i]->content, logf[pl].file); + logf[pl].command = logf[pl].file; + } else if (strcmp(node[i]->element, xml_localfile_frequency) == 0) { + + if(strcmp(node[i]->content, "hourly") == 0) + { + logf[pl].ign = 3600; + } + else if(strcmp(node[i]->content, "daily") == 0) + { + logf[pl].ign = 86400; + } + else + { + + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + logf[pl].ign = atoi(node[i]->content); + } + } else if (strcmp(node[i]->element, xml_localfile_location) == 0) { + #ifdef WIN32 + /* Expand variables on Windows */ + if (strchr(node[i]->content, '%')) { + int expandreturn = 0; + char newfile[OS_MAXSTR + 1]; + + newfile[OS_MAXSTR] = '\0'; + expandreturn = ExpandEnvironmentStrings(node[i]->content, + newfile, OS_MAXSTR); + + if ((expandreturn > 0) && (expandreturn < OS_MAXSTR)) { + free(node[i]->content); + + os_strdup(newfile, node[i]->content); + } + } + #endif + + /* This is a glob* + * We will call this file multiple times until + * there is no one else available. + */ +#ifndef WIN32 /* No windows support for glob */ + if (strchr(node[i]->content, '*') || + strchr(node[i]->content, '?') || + strchr(node[i]->content, '[')) { + glob_t g; + + /* Setting to the first entry of the glob */ + if (glob_set == 0) { + glob_set = pl + 1; + } + + if (glob(node[i]->content, 0, NULL, &g) != 0) { + merror(GLOB_ERROR, __local_name, node[i]->content); + os_strdup(node[i]->content, logf[pl].file); + i++; + continue; + } + + /* Check for the last entry */ + if ((g.gl_pathv[glob_offset]) == NULL) { + /* Check when nothing is found */ + if (glob_offset == 0) { + merror(GLOB_NFOUND, __local_name, node[i]->content); + return (OS_INVALID); + } + i++; + continue; + } + + + while(g.gl_pathv[glob_offset] != NULL) + { + /* Check for strftime on globs too */ + if (strchr(g.gl_pathv[glob_offset], '%')) { + struct tm *p; + time_t l_time = time(0); + char lfile[OS_FLSIZE + 1]; + size_t ret; + + p = localtime(&l_time); + + lfile[OS_FLSIZE] = '\0'; + ret = strftime(lfile, OS_FLSIZE, g.gl_pathv[glob_offset], p); + if (ret == 0) { + merror(PARSE_ERROR, __local_name, g.gl_pathv[glob_offset]); + return (OS_INVALID); + } + + os_strdup(g.gl_pathv[glob_offset], logf[pl].ffile); + os_strdup(g.gl_pathv[glob_offset], logf[pl].file); + } else { + os_strdup(g.gl_pathv[glob_offset], logf[pl].file); + } + + glob_offset++; + + /* Now we need to create another file entry */ + pl++; + os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config); + logf = log_config->config; + + logf[pl].file = NULL; + logf[pl].alias = NULL; + logf[pl].logformat = NULL; + logf[pl].fp = NULL; + logf[pl].ffile = NULL; + + logf[pl +1].file = NULL; + logf[pl +1].alias = NULL; + logf[pl +1].logformat = NULL; + } + + + globfree(&g); + } else if (strchr(node[i]->content, '%')) + #else + if (strchr(node[i]->content, '%')) + #endif /* WIN32 */ + + /* We need the format file (based on date) */ + { + struct tm *p; + time_t l_time = time(0); + char lfile[OS_FLSIZE + 1]; + size_t ret; + + p = localtime(&l_time); + + lfile[OS_FLSIZE] = '\0'; + ret = strftime(lfile, OS_FLSIZE, node[i]->content, p); + if (ret != 0) { + os_strdup(node[i]->content, logf[pl].ffile); + } + + os_strdup(node[i]->content, logf[pl].file); + } + + /* Normal file */ + else { + os_strdup(node[i]->content, logf[pl].file); + } + } + + /* Get log format */ + else if (strcasecmp(node[i]->element, xml_localfile_logformat) == 0) { + os_strdup(node[i]->content, logf[pl].logformat); + + if (strcmp(logf[pl].logformat, "syslog") == 0) { + } else if (strcmp(logf[pl].logformat, "generic") == 0) { + } else if (strcmp(logf[pl].logformat, "snort-full") == 0) { + } else if (strcmp(logf[pl].logformat, "snort-fast") == 0) { + } else if (strcmp(logf[pl].logformat, "apache") == 0) { + } else if (strcmp(logf[pl].logformat, "iis") == 0) { + } else if (strcmp(logf[pl].logformat, "squid") == 0) { + } else if (strcmp(logf[pl].logformat, "nmapg") == 0) { + } else if (strcmp(logf[pl].logformat, "mysql_log") == 0) { + } else if (strcmp(logf[pl].logformat, "openarmoralert") == 0) { + } else if (strcmp(logf[pl].logformat, "mssql_log") == 0) { + } else if (strcmp(logf[pl].logformat, "postgresql_log") == 0) { + } else if (strcmp(logf[pl].logformat, "djb-multilog") == 0) { + } else if (strcmp(logf[pl].logformat, "syslog-pipe") == 0) { + } else if (strcmp(logf[pl].logformat, "command") == 0) { + } else if (strcmp(logf[pl].logformat, "full_command") == 0) { + } else if (strcmp(logf[pl].logformat, "audit") == 0) { + } else if (strcmp(logf[pl].logformat, "journald") == 0) { + } else if (strcmp(logf[pl].logformat, "multi-line_indented") == 0) { + } else if (strncmp(logf[pl].logformat, "multi-line", 10) == 0) { + int x = 0; + logf[pl].logformat += 10; + + while (logf[pl].logformat[0] == ' ') { + logf[pl].logformat++; + } + + if (logf[pl].logformat[0] != ':') { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + logf[pl].logformat++; + + while (*logf[pl].logformat == ' ') { + logf[pl].logformat++; + } + + while (logf[pl].logformat[x] >= '0' && logf[pl].logformat[x] <= '9') { + x++; + } + + while (logf[pl].logformat[x] == ' ') { + x++; + } + + if (logf[pl].logformat[x] != '\0') { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(logf[pl].logformat, EVENTLOG) == 0) { + } else if (strcmp(logf[pl].logformat, EVENTCHANNEL) == 0) { + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcasecmp(node[i]->element, xml_localfile_alias) == 0) { + os_strdup(node[i]->content, logf[pl].alias); + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + + i++; + } + + /* Validate glob entries */ + if (glob_set) { + char *format; + + /* Get log format */ + if (logf[pl].logformat) { + format = logf[pl].logformat; + } else if (logf[glob_set - 1].logformat) { + format = logf[glob_set - 1].logformat; + } else { + merror(MISS_LOG_FORMAT, __local_name); + return (OS_INVALID); + } + + /* The last entry is always null on glob */ + pl--; + + /* Set format for all entries */ + for (i = (glob_set - 1); i <= pl; i++) { + /* Every entry must be valid */ + if (!logf[i].file) { + merror(MISS_FILE, __local_name); + return (OS_INVALID); + } + + if (logf[i].logformat == NULL) { + logf[i].logformat = format; + } + + } + } + + /* Missing log format */ + if (!logf[pl].logformat) { + merror(MISS_LOG_FORMAT, __local_name); + return (OS_INVALID); + } + + /* Missing file */ + if (!logf[pl].file) { + merror(MISS_FILE, __local_name); + return (OS_INVALID); + } + + /* Verify a valid event log config */ + if (strcmp(logf[pl].logformat, EVENTLOG) == 0) { + if ((strcmp(logf[pl].file, "Application") != 0) && + (strcmp(logf[pl].file, "System") != 0) && + (strcmp(logf[pl].file, "Security") != 0)) { + /* Invalid event log */ + merror(NSTD_EVTLOG, __local_name, logf[pl].file); + return (0); + } + } + + if ((strcmp(logf[pl].logformat, "command") == 0) || + (strcmp(logf[pl].logformat, "full_command") == 0)) { + if (!logf[pl].command) { + merror("%s: ERROR: Missing 'command' argument. " + "This option will be ignored.", __local_name); + } + } + + return (0); +} + diff --git a/src/config/localfile-config.h b/src/config/localfile-config.h new file mode 100644 index 000000000..ddb03043b --- /dev/null +++ b/src/config/localfile-config.h @@ -0,0 +1,59 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CLOGREADER_H +#define __CLOGREADER_H + +#define EVENTLOG "eventlog" +#define EVENTCHANNEL "eventchannel" +#define VCHECK_FILES 64 +#define DATE_MODIFIED 1 + +/* For ino_t */ +#include + +/* Logreader config */ +typedef struct _logreader { + off_t size; + int ign; + +#ifdef WIN32 + HANDLE h; + DWORD fd; +#else + ino_t fd; +#endif + + /* ffile - format file is only used when + * the file has format string to retrieve + * the date, + */ + char *ffile; + char *file; + char *logformat; + char *djb_program_name; + char *command; + char *alias; + char future; + char *query; + + void *(*read)(int i, int *rc, int drop_it); + + void *ptr; + FILE *fp; +} logreader; + +typedef struct _logreader_config { + int agent_cfg; + int accept_remote; + logreader *config; +} logreader_config; + +#endif /* __CLOGREADER_H */ + diff --git a/src/config/mail-config.h b/src/config/mail-config.h new file mode 100644 index 000000000..f5fe6f332 --- /dev/null +++ b/src/config/mail-config.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _MCCONFIG__H +#define _MCCONFIG__H + +#ifndef WIN32 +#include +#include +#include +#include +#include +#endif //WIN32 + +#include "shared.h" + +/* Mail config structure */ +typedef struct _MailConfig { + int mn; + int maxperhour; + int strict_checking; + int groupping; + int subject_full; + int priority; + char **to; + char *reply_to; + char *from; + char *idsname; + char *smtpserver; + char *heloserver; + + /* Granular e-mail options */ + unsigned int *gran_level; + unsigned int **gran_id; + int *gran_set; + int *gran_format; + char **gran_to; + +#ifdef LIBGEOIP_ENABLED + /* Use GeoIP */ + int geoip; +#endif + +#ifndef WIN32 + /* ibuf for imsg */ + struct imsgbuf ibuf; +#endif //WIN32 + + OSMatch **gran_location; + OSMatch **gran_group; +} MailConfig; + +/* Email message formats */ +#define FULL_FORMAT 2 +#define SMS_FORMAT 3 +#define FORWARD_NOW 4 +#define DONOTGROUP 5 + +#endif /* _MCCONFIG__H */ + diff --git a/src/config/remote-config.c b/src/config/remote-config.c new file mode 100644 index 000000000..7958797d0 --- /dev/null +++ b/src/config/remote-config.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "remote-config.h" +#include "config.h" + + +/* Reads remote config */ +int Read_Remote(XML_NODE node, void *d1, __attribute__((unused)) void *d2) +{ + int i = 0; + unsigned int pl = 0; + unsigned int allow_size = 1; + unsigned int deny_size = 1; + int portnum; + remoted *logr; + + /*** XML Definitions ***/ + + /* Allowed and denied IPS */ + const char *xml_allowips = "allowed-ips"; + const char *xml_denyips = "denied-ips"; + + /* Remote options */ + const char *xml_remote_port = "port"; + const char *xml_remote_proto = "protocol"; + const char *xml_remote_ipv6 = "ipv6"; + const char *xml_remote_connection = "connection"; + const char *xml_remote_lip = "local_ip"; + + logr = (remoted *)d1; + + /* Getting allowed-ips */ + if (logr->allowips) { + while (logr->allowips[allow_size - 1]) { + allow_size++; + } + } + + /* Getting denied-ips */ + if (logr->denyips) { + while (logr->denyips[deny_size - 1]) { + deny_size++; + } + } + + /* conn and port must not be null */ + if (!logr->conn) { + os_calloc(1, sizeof(int), logr->conn); + logr->conn[0] = 0; + } + if(!logr->port) { + os_calloc(1, sizeof(char *), logr->port); + logr->port[0] = NULL; + } + if (!logr->proto) { + os_calloc(1, sizeof(int), logr->proto); + logr->proto[0] = 0; + } + if (!logr->ipv6) { + os_calloc(1, sizeof(int), logr->ipv6); + logr->ipv6[0] = 0; + } + if (!logr->lip) { + os_calloc(1, sizeof(char *), logr->lip); + logr->lip[0] = NULL; + } + + /* Clean */ + while (logr->conn[pl] != 0) { + pl++; + } + + /* Add space for the last null connection/port */ + logr->port = (char **) realloc(logr->port, sizeof(char *) * (pl + 2)); + logr->conn = (int *) realloc(logr->conn, sizeof(int) * (pl + 2)); + logr->proto = (int *) realloc(logr->proto, sizeof(int) * (pl + 2)); + logr->ipv6 = (int *) realloc(logr->ipv6, sizeof(int) * (pl + 2)); + logr->lip = (char **) realloc(logr->lip, sizeof(char *) * (pl + 2)); + if (!logr->port || !logr->conn || !logr->proto || !logr->ipv6 || !logr->lip) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + + logr->port[pl] = NULL; + logr->conn[pl] = 0; + logr->proto[pl] = 0; + logr->ipv6[pl] = 0; + logr->lip[pl] = NULL; + + logr->port[pl + 1] = NULL; + logr->conn[pl + 1] = 0; + logr->proto[pl + 1] = 0; + logr->ipv6[pl + 1] = 0; + logr->lip[pl + 1] = NULL; + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } else if (strcasecmp(node[i]->element, xml_remote_connection) == 0) { + if (strcmp(node[i]->content, "syslog") == 0) { + logr->conn[pl] = SYSLOG_CONN; + } else if (strcmp(node[i]->content, "secure") == 0) { + logr->conn[pl] = SECURE_CONN; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcasecmp(node[i]->element, xml_remote_port) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + os_strdup(node[i]->content,logr->port[pl]); + portnum = atoi(node[i]->content); + + if (portnum <= 0 || portnum > 65535) { + merror(PORT_ERROR, __local_name, portnum); + return (OS_INVALID); + } + } else if (strcasecmp(node[i]->element, xml_remote_proto) == 0) { + if (strcasecmp(node[i]->content, "tcp") == 0) { + logr->proto[pl] = IPPROTO_TCP; + } else if (strcasecmp(node[i]->content, "udp") == 0) { + logr->proto[pl] = IPPROTO_UDP; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, + node[i]->content); + return (OS_INVALID); + } + } else if (strcasecmp(node[i]->element, xml_remote_ipv6) == 0) { + if (strcasecmp(node[i]->content, "yes") == 0) { + logr->ipv6[pl] = 1; + } + } else if (strcasecmp(node[i]->element, xml_remote_lip) == 0) { + os_strdup(node[i]->content, logr->lip[pl]); + if (OS_IsValidIP(logr->lip[pl], NULL) != 1) { + merror(INVALID_IP, __local_name, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_allowips) == 0) { + allow_size++; + logr->allowips = (os_ip **) realloc(logr->allowips, sizeof(os_ip *)*allow_size); + if (!logr->allowips) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_calloc(1, sizeof(os_ip), logr->allowips[allow_size - 2]); + logr->allowips[allow_size - 1] = NULL; + + if (!OS_IsValidIP(node[i]->content, logr->allowips[allow_size - 2])) { + merror(INVALID_IP, __local_name, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_denyips) == 0) { + deny_size++; + logr->denyips = (os_ip **) realloc(logr->denyips, sizeof(os_ip *)*deny_size); + if (!logr->denyips) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_calloc(1, sizeof(os_ip), logr->denyips[deny_size - 2]); + logr->denyips[deny_size - 1] = NULL; + if (!OS_IsValidIP(node[i]->content, logr->denyips[deny_size - 2])) { + merror(INVALID_IP, __local_name, node[i]->content); + return (OS_INVALID); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + /* conn must be set */ + if (logr->conn[pl] == 0) { + merror(CONN_ERROR, __local_name); + return (OS_INVALID); + } + + /* Set port in here */ + if (logr->port[pl] == NULL) { + if (logr->conn[pl] == SECURE_CONN) { + logr->port[pl] = DEFAULT_SECURE; + } else { + logr->port[pl] = DEFAULT_SYSLOG; + } + } + + /* Set default protocol */ + if (logr->proto[pl] == 0) { + logr->proto[pl] = IPPROTO_UDP; + } + + /* Secure connections only run on UDP */ + if ((logr->conn[pl] == SECURE_CONN) && (logr->proto[pl] == IPPROTO_TCP)) { + logr->proto[pl] = IPPROTO_UDP; + } + + return (0); +} + diff --git a/src/config/remote-config.h b/src/config/remote-config.h new file mode 100644 index 000000000..48048171d --- /dev/null +++ b/src/config/remote-config.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CLOGREMOTE_H +#define __CLOGREMOTE_H + +#define SYSLOG_CONN 1 +#define SECURE_CONN 2 + +#include "shared.h" +#include "os_net/os_net.h" + +/* socklen_t header */ +typedef struct _remoted { + int *proto; + char **port; + int *conn; + int *ipv6; + + char **lip; + os_ip **allowips; + os_ip **denyips; + + int m_queue; + int sock; + OSNetInfo *netinfo; + socklen_t peer_size; +} remoted; + +#endif /* __CLOGREMOTE_H */ + diff --git a/src/config/reports-config.c b/src/config/reports-config.c new file mode 100644 index 000000000..968883b1a --- /dev/null +++ b/src/config/reports-config.c @@ -0,0 +1,188 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "reports-config.h" +#include "config.h" + + +/* Filter argument */ +static int _filter_arg(char *mystr) +{ + if (!mystr) { + return (0); + } + + while (*mystr) { + if ((*mystr >= 'a' && *mystr <= 'z') || + (*mystr >= 'A' && *mystr <= 'Z') || + (*mystr >= '0' && *mystr <= '9') || + *mystr == '-' || *mystr == '_' || *mystr == '.') { + mystr++; + } else { + *mystr = '-'; + mystr++; + } + } + + return (1); +} + +int Read_CReports(XML_NODE node, void *config, __attribute__((unused)) void *config2) +{ + unsigned int i = 0, s = 0; + + /* XML definitions */ + const char *xml_title = "title"; + const char *xml_type = "type"; + const char *xml_categories = "category"; + const char *xml_group = "group"; + const char *xml_rule = "rule"; + const char *xml_level = "level"; + const char *xml_location = "location"; + const char *xml_showlogs = "showlogs"; + const char *xml_srcip = "srcip"; + const char *xml_user = "user"; + const char *xml_frequency = "frequency"; + const char *xml_email = "email_to"; + + monitor_config *mon_config = (monitor_config *)config; + + /* Get any configured entry */ + if (mon_config->reports) { + while (mon_config->reports[s]) { + s++; + } + } + + /* Allocate the memory for the config */ + os_realloc(mon_config->reports, (s + 2) * sizeof(report_config *), + mon_config->reports); + os_calloc(1, sizeof(report_config), mon_config->reports[s]); + mon_config->reports[s + 1] = NULL; + + /* Zero the elements */ + mon_config->reports[s]->title = NULL; + mon_config->reports[s]->args = NULL; + mon_config->reports[s]->relations = NULL; + mon_config->reports[s]->type = NULL; + mon_config->reports[s]->emailto = NULL; + + mon_config->reports[s]->r_filter.group = NULL; + mon_config->reports[s]->r_filter.rule = NULL; + mon_config->reports[s]->r_filter.level = NULL; + mon_config->reports[s]->r_filter.location = NULL; + mon_config->reports[s]->r_filter.srcip = NULL; + mon_config->reports[s]->r_filter.user = NULL; + mon_config->reports[s]->r_filter.related_group = 0; + mon_config->reports[s]->r_filter.related_rule = 0; + mon_config->reports[s]->r_filter.related_level = 0; + mon_config->reports[s]->r_filter.related_location = 0; + mon_config->reports[s]->r_filter.related_srcip = 0; + mon_config->reports[s]->r_filter.related_user = 0; + mon_config->reports[s]->r_filter.report_name = NULL; + mon_config->reports[s]->r_filter.show_alerts = 0; + + /* Reading the XML */ + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } else if (strcmp(node[i]->element, xml_title) == 0) { + if (!mon_config->reports[s]->title) { + os_strdup(node[i]->content, mon_config->reports[s]->title); + } + } else if (strcmp(node[i]->element, xml_type) == 0) { + if (strcmp(node[i]->content, "email") == 0) { + if (!mon_config->reports[s]->type) { + os_strdup(node[i]->content, mon_config->reports[s]->type); + } + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + } + } else if (strcmp(node[i]->element, xml_frequency) == 0) { + } else if (strcmp(node[i]->element, xml_showlogs) == 0) { + if (strcasecmp(node[i]->content, "yes") == 0) { + mon_config->reports[s]->r_filter.show_alerts = 1; + } + } else if (strcmp(node[i]->element, xml_categories) == 0) { + char *ncat = NULL; + _filter_arg(node[i]->content); + + os_strdup(node[i]->content, ncat); + + if (os_report_configfilter("group", ncat, + &mon_config->reports[s]->r_filter, REPORT_FILTER) < 0) { + merror(CONFIG_ERROR, __local_name, "user argument"); + } + } else if ((strcmp(node[i]->element, xml_group) == 0) || + (strcmp(node[i]->element, xml_rule) == 0) || + (strcmp(node[i]->element, xml_level) == 0) || + (strcmp(node[i]->element, xml_location) == 0) || + (strcmp(node[i]->element, xml_srcip) == 0) || + (strcmp(node[i]->element, xml_user) == 0)) { + int reportf = REPORT_FILTER; + char *ncat = NULL; + _filter_arg(node[i]->content); + + if (node[i]->attributes && node[i]->values) { + if (node[i]->attributes[0] && node[i]->values[0]) { + if (strcmp(node[i]->attributes[0], "type") == 0) { + if (strcmp(node[i]->values[0], "relation") == 0) { + reportf = REPORT_RELATED; + } else { + merror("%s: WARN: Invalid value for 'relation' attribute: '%s'. (ignored).", __local_name, node[i]->values[0]); + i++; + continue; + } + } else { + merror("%s: WARN: Invalid attribute: %s (ignored). ", __local_name, node[i]->attributes[0]); + i++; + continue; + } + } + } + + os_strdup(node[i]->content, ncat); + + if (os_report_configfilter(node[i]->element, ncat, + &mon_config->reports[s]->r_filter, reportf) < 0) { + merror("%s: Invalid filter: %s:%s (ignored).", __local_name, node[i]->element, node[i]->content); + } + } else if (strcmp(node[i]->element, xml_email) == 0) { + mon_config->reports[s]->emailto = os_AddStrArray(node[i]->content, mon_config->reports[s]->emailto); + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + /* Set proper report type */ + mon_config->reports[s]->r_filter.report_type = REPORT_TYPE_DAILY; + + if (mon_config->reports[s]->emailto == NULL) { + if (mon_config->reports[s]->title) { + merror("%s: No \"email to\" configured for the report '%s'. Ignoring it.", __local_name, mon_config->reports[s]->title); + } else { + merror("%s: No \"email to\" and title configured for report. Ignoring it.", __local_name); + } + } + + if (!mon_config->reports[s]->title) { + os_strdup("openarmor Report (unnamed)", mon_config->reports[s]->title); + } + mon_config->reports[s]->r_filter.report_name = mon_config->reports[s]->title; + + return (0); +} + diff --git a/src/config/reports-config.h b/src/config/reports-config.h new file mode 100644 index 000000000..5ec1bd210 --- /dev/null +++ b/src/config/reports-config.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _REPORTSCONFIG_H +#define _REPORTSCONFIG_H + +#include "report_op.h" + +/* Structure for the report */ +typedef struct _report_config { + char *title; + char *args; + char *relations; + char *type; + char **emailto; + report_filter r_filter; +} report_config; + +typedef struct _monitor_config { + unsigned short int day_wait; + short int compress; + short int sign; + short int monitor_agents; + int a_queue; + int notify_time; + + char *smtpserver; + char *emailfrom; + char *emailidsname; + + char **agents; + report_config **reports; +} monitor_config; + +#endif /* _REPORTSCONFIG_H */ diff --git a/src/config/rootcheck-config.c b/src/config/rootcheck-config.c new file mode 100644 index 000000000..68816e85b --- /dev/null +++ b/src/config/rootcheck-config.c @@ -0,0 +1,229 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck-config.h" +#include "config.h" + + +static short eval_bool(const char *str) +{ + if (str == NULL) { + return (OS_INVALID); + } else if (strcmp(str, "yes") == 0) { + return (1); + } else if (strcmp(str, "no") == 0) { + return (0); + } else { + return (OS_INVALID); + } +} + +/* Read the rootcheck config */ +int Read_Rootcheck(XML_NODE node, void *configp, __attribute__((unused)) void *mailp) +{ + int i = 0; + rkconfig *rootcheck; + + /* XML Definitions */ + const char *xml_rootkit_files = "rootkit_files"; + const char *xml_rootkit_trojans = "rootkit_trojans"; + const char *xml_winaudit = "windows_audit"; + const char *xml_unixaudit = "system_audit"; + const char *xml_winapps = "windows_apps"; + const char *xml_winmalware = "windows_malware"; + const char *xml_scanall = "scanall"; + const char *xml_readall = "readall"; + const char *xml_time = "frequency"; + const char *xml_disabled = "disabled"; + const char *xml_skip_nfs = "skip_nfs"; + const char *xml_base_dir = "base_directory"; + const char *xml_ignore = "ignore"; + + const char *xml_check_dev = "check_dev"; + const char *xml_check_files = "check_files"; + const char *xml_check_if = "check_if"; + const char *xml_check_pids = "check_pids"; + const char *xml_check_ports = "check_ports"; + const char *xml_check_sys = "check_sys"; + const char *xml_check_trojans = "check_trojans"; + const char *xml_check_unixaudit = "check_unixaudit"; + const char *xml_check_winapps = "check_winapps"; + const char *xml_check_winaudit = "check_winaudit"; + const char *xml_check_winmalware = "check_winmalware"; + + rootcheck = (rkconfig *)configp; + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + + /* Get frequency */ + else if (strcmp(node[i]->element, xml_time) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + rootcheck->time = atoi(node[i]->content); + } + /* Get scan all */ + else if (strcmp(node[i]->element, xml_scanall) == 0) { + rootcheck->scanall = eval_bool(node[i]->content); + if (rootcheck->scanall == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_disabled) == 0) { + rootcheck->disabled = eval_bool(node[i]->content); + if (rootcheck->disabled == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + else if(strcmp(node[i]->element, xml_skip_nfs) == 0) + { + rootcheck->skip_nfs = eval_bool(node[i]->content); + if (rootcheck->skip_nfs == OS_INVALID) + { + merror(XML_VALUEERR,__local_name,node[i]->element,node[i]->content); + return(OS_INVALID); + } + } + else if(strcmp(node[i]->element,xml_readall) == 0) + { + rootcheck->readall = eval_bool(node[i]->content); + if (rootcheck->readall == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_rootkit_files) == 0) { + os_strdup(node[i]->content, rootcheck->rootkit_files); + } else if (strcmp(node[i]->element, xml_rootkit_trojans) == 0) { + os_strdup(node[i]->content, rootcheck->rootkit_trojans); + } else if (strcmp(node[i]->element, xml_winaudit) == 0) { + os_strdup(node[i]->content, rootcheck->winaudit); + } else if (strcmp(node[i]->element, xml_unixaudit) == 0) { + unsigned int j = 0; + while (rootcheck->unixaudit && rootcheck->unixaudit[j]) { + j++; + } + + os_realloc(rootcheck->unixaudit, sizeof(char *) * (j + 2), + rootcheck->unixaudit); + rootcheck->unixaudit[j] = NULL; + rootcheck->unixaudit[j + 1] = NULL; + + os_strdup(node[i]->content, rootcheck->unixaudit[j]); + } else if (strcmp(node[i]->element, xml_ignore) == 0) { + unsigned int j = 0; + while (rootcheck->ignore && rootcheck->ignore[j]) { + j++; + } + + os_realloc(rootcheck->ignore, sizeof(char *) * (j + 2), + rootcheck->ignore); + rootcheck->ignore[j] = NULL; + rootcheck->ignore[j + 1] = NULL; + + os_strdup(node[i]->content, rootcheck->ignore[j]); + } else if (strcmp(node[i]->element, xml_winmalware) == 0) { + os_strdup(node[i]->content, rootcheck->winmalware); + } else if (strcmp(node[i]->element, xml_winapps) == 0) { + os_strdup(node[i]->content, rootcheck->winapps); + } else if (strcmp(node[i]->element, xml_base_dir) == 0) { + os_strdup(node[i]->content, rootcheck->basedir); + } else if (strcmp(node[i]->element, xml_check_dev) == 0) { + rootcheck->checks.rc_dev = eval_bool(node[i]->content); + if (rootcheck->checks.rc_dev == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_files) == 0) { + rootcheck->checks.rc_files = eval_bool(node[i]->content); + if (rootcheck->checks.rc_files == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_if) == 0) { + rootcheck->checks.rc_if = eval_bool(node[i]->content); + if (rootcheck->checks.rc_if == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_pids) == 0) { + rootcheck->checks.rc_pids = eval_bool(node[i]->content); + if (rootcheck->checks.rc_pids == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_ports) == 0) { + rootcheck->checks.rc_ports = eval_bool(node[i]->content); + if (rootcheck->checks.rc_ports == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_sys) == 0) { + rootcheck->checks.rc_sys = eval_bool(node[i]->content); + if (rootcheck->checks.rc_sys == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_trojans) == 0) { + rootcheck->checks.rc_trojans = eval_bool(node[i]->content); + if (rootcheck->checks.rc_trojans == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } else if (strcmp(node[i]->element, xml_check_unixaudit) == 0) { +#ifndef WIN32 + rootcheck->checks.rc_unixaudit = eval_bool(node[i]->content); + if (rootcheck->checks.rc_unixaudit == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } +#endif + } else if (strcmp(node[i]->element, xml_check_winapps) == 0) { +#ifdef WIN32 + rootcheck->checks.rc_winapps = eval_bool(node[i]->content); + if (rootcheck->checks.rc_winapps == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } +#endif + } else if (strcmp(node[i]->element, xml_check_winaudit) == 0) { +#ifdef WIN32 + rootcheck->checks.rc_winaudit = eval_bool(node[i]->content); + if (rootcheck->checks.rc_winaudit == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } +#endif + } else if (strcmp(node[i]->element, xml_check_winmalware) == 0) { +#ifdef WIN32 + rootcheck->checks.rc_winmalware = eval_bool(node[i]->content); + if (rootcheck->checks.rc_winmalware == OS_INVALID) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } +#endif + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + return (0); +} + diff --git a/src/config/rootcheck-config.h b/src/config/rootcheck-config.h new file mode 100644 index 000000000..24c3aba89 --- /dev/null +++ b/src/config/rootcheck-config.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CROOTCHECK_H +#define __CROOTCHECK_H + +#include + +typedef struct _rkconfig { + const char *workdir; + char *basedir; + char *rootkit_files; + char *rootkit_trojans; + char **unixaudit; + char **ignore; + char *winaudit; + char *winmalware; + char *winapps; + char **alert_msg; + + FILE *fp; + int daemon; + int notify; /* QUEUE or SYSLOG */ + int scanall; + int readall; + int disabled; + short skip_nfs; + +#ifdef openarmorHIDS + unsigned int tsleep; +#endif /* openarmorHIDS */ + + int time; + int queue; + + struct _checks { + short rc_dev; + short rc_files; + short rc_if; + short rc_pids; + short rc_ports; + short rc_sys; + short rc_trojans; + +#ifdef WIN32 + short rc_winaudit; + short rc_winmalware; + short rc_winapps; +#else + short rc_unixaudit; +#endif + + } checks; + +} rkconfig; + +#endif /* __CROOTCHECK_H */ + diff --git a/src/config/rules-config.c b/src/config/rules-config.c new file mode 100644 index 000000000..ca05420e7 --- /dev/null +++ b/src/config/rules-config.c @@ -0,0 +1,260 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include + +#include "config.h" +#include "shared.h" +#include "global-config.h" +#include "config.h" + +/* Prototypes */ +static int cmpr(const void *a, const void *b) __attribute__((nonnull)); +static int file_in_list(unsigned int list_size, char *f_name, char *d_name, char **alist) __attribute__((nonnull)); + + +static int cmpr(const void *a, const void *b) +{ + return strcmp(*(const char *const *)a, *(const char *const *)b); +} + +static int file_in_list(unsigned int list_size, char *f_name, char *d_name, char **alist) +{ + unsigned int i = 0; + for (i = 0; (i + 1) < list_size; i++) { + if ((strcmp(alist[i], f_name) == 0 || strcmp(alist[i], d_name) == 0)) { + return (1); + } + } + return (0); +} + +int Read_Rules(XML_NODE node, void *configp, __attribute__((unused)) void *mailp) +{ + int i = 0; + unsigned int ii = 0; + + unsigned int rules_size = 1; + unsigned int lists_size = 1; + unsigned int decoders_size = 1; + + char path[PATH_MAX + 2]; + char f_name[PATH_MAX + 2]; + unsigned int start_point = 0; + int att_count = 0; + struct dirent *entry; + DIR *dfd; + OSRegex regex; + + /* XML definitions */ + const char *xml_rules_include = "include"; + const char *xml_rules_rule = "rule"; + const char *xml_rules_rules_dir = "rule_dir"; + const char *xml_rules_lists = "list"; + const char *xml_rules_decoders = "decoder"; + const char *xml_rules_decoders_dir = "decoder_dir"; + + _Config *Config; + + Config = (_Config *)configp; + + /* Initialize OSRegex */ + memset(®ex, 0, sizeof(regex)); + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + /* Mail notification */ + else if ((strcmp(node[i]->element, xml_rules_include) == 0) || + (strcmp(node[i]->element, xml_rules_rule) == 0)) { + rules_size++; + Config->includes = (char **) realloc(Config->includes, + sizeof(char *)*rules_size); + if (!Config->includes) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_strdup(node[i]->content, Config->includes[rules_size - 2]); + Config->includes[rules_size - 1] = NULL; + debug1("adding rule: %s", node[i]->content); + } else if (strcmp(node[i]->element, xml_rules_decoders) == 0) { + decoders_size++; + Config->decoders = (char **) realloc(Config->decoders, + sizeof(char *)*decoders_size); + if (!Config->decoders) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + + os_strdup(node[i]->content, Config->decoders[decoders_size - 2]); + Config->decoders[decoders_size - 1] = NULL; + debug1("adding decoder: %s", node[i]->content); + } else if (strcmp(node[i]->element, xml_rules_lists) == 0) { + lists_size++; + Config->lists = (char **) realloc(Config->lists, + sizeof(char *)*lists_size); + if (!Config->lists) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (OS_INVALID); + } + os_strdup(node[i]->content, Config->lists[lists_size - 2]); + Config->lists[lists_size - 1] = NULL; + + } else if (strcmp(node[i]->element, xml_rules_decoders_dir) == 0) { + + if (node[i]->attributes && node[i]->values) { + while (node[i]->attributes[att_count]) { + if ((strcasecmp(node[i]->attributes[att_count], "pattern") == 0)) { + if (node[i]->values[att_count]) { + if (!OSRegex_Compile(node[i]->values[att_count], ®ex, 0)) { + merror(CONFIG_ERROR, __local_name, "pattern in decoders_dir does not compile"); + merror("%s: ERROR: Regex would not compile", __local_name); + return (-1); + } + } + } + att_count++; + } + } else { + OSRegex_Compile(".xml$", ®ex, 0); + } + +#ifdef TESTRULE + snprintf(path, PATH_MAX + 1, "%s", node[i]->content); +#else + snprintf(path, PATH_MAX + 1, "%s/%s", DEFAULTDIR, node[i]->content); +#endif + + f_name[PATH_MAX + 1] = '\0'; + dfd = opendir(path); + + att_count = 0; // Reset this variable after it was used in decoder + + if (dfd != NULL) { + start_point = decoders_size - 1; + while ((entry = readdir(dfd)) != NULL) { + snprintf(f_name, PATH_MAX + 1, "%s/%s", node[i]->content, entry->d_name); + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + /* No duplicates allowed */ + if (file_in_list(decoders_size, f_name, entry->d_name, Config->decoders)) { + continue; + } + + if (OSRegex_Execute(f_name, ®ex)) { + decoders_size++; + Config->decoders = (char **) realloc(Config->decoders, sizeof(char *)*decoders_size); + if (!Config->decoders) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + OSRegex_FreePattern(®ex); + closedir(dfd); + return (-1); + } + + os_strdup(f_name, Config->decoders[decoders_size - 2]); + Config->decoders[decoders_size - 1] = NULL; + debug1("adding decoder: %s", f_name); + } else { + debug1("Regex does not match \"%s\"", f_name); + } + } + + OSRegex_FreePattern(®ex); + closedir(dfd); + /* Sort just then newly added items */ + qsort(Config->decoders + start_point , decoders_size - start_point - 1, sizeof(char *), cmpr); + } + debug1("decoders_size %d", decoders_size); + for (ii = 0; ii < decoders_size - 1; ii++) { + debug1("- %s", Config->decoders[ii]); + } + } else if (strcmp(node[i]->element, xml_rules_rules_dir) == 0) { + if (node[i]->attributes && node[i]->values) { + while (node[i]->attributes[att_count]) { + if ((strcasecmp(node[i]->attributes[att_count], "pattern") == 0)) { + if (node[i]->values[att_count]) { + if (!OSRegex_Compile(node[i]->values[att_count], ®ex, 0)) { + merror(CONFIG_ERROR, __local_name, "pattern in rules_dir does not compile"); + merror("%s: ERROR: Regex would not compile", __local_name); + return (-1); + } + } + } + att_count++; + } + } else { + OSRegex_Compile(".xml$", ®ex, 0); + } + +#ifdef TESTRULE + snprintf(path, PATH_MAX + 1, "%s", node[i]->content); +#else + snprintf(path, PATH_MAX + 1, "%s/%s", DEFAULTDIR, node[i]->content); +#endif + + f_name[PATH_MAX + 1] = '\0'; + dfd = opendir(path); + + if (dfd != NULL) { + start_point = rules_size - 1; + while ((entry = readdir(dfd)) != NULL) { + snprintf(f_name, PATH_MAX + 1, "%s/%s", node[i]->content, entry->d_name); + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + /* No duplicates allowed */ + if (file_in_list(rules_size, f_name, entry->d_name, Config->includes)) { + continue; + } + + if (OSRegex_Execute(f_name, ®ex)) { + rules_size++; + Config->includes = (char **) realloc(Config->includes, sizeof(char *)*rules_size); + if (!Config->includes) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + OSRegex_FreePattern(®ex); + closedir(dfd); + return (-1); + } + + os_strdup(f_name, Config->includes[rules_size - 2]); + Config->includes[rules_size - 1] = NULL; + debug1("adding rule: %s", f_name); + } else { + debug1("Regex does not match \"%s\"", f_name); + } + } + + OSRegex_FreePattern(®ex); + closedir(dfd); + /* Sort just then newly added items */ + qsort(Config->includes + start_point , rules_size - start_point - 1, sizeof(char *), cmpr); + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + OSRegex_FreePattern(®ex); + return (OS_INVALID); + } + i++; + } + return (0); +} diff --git a/src/config/syscheck-config.c b/src/config/syscheck-config.c new file mode 100644 index 000000000..d91567f8e --- /dev/null +++ b/src/config/syscheck-config.c @@ -0,0 +1,876 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "syscheck-config.h" +#include "config.h" + + +int dump_syscheck_entry(syscheck_config *syscheck, const char *entry, int vals, int reg, const char *restrictfile) +{ + unsigned int pl = 0; + + if (reg == 1) { +#ifdef WIN32 + if (syscheck->registry == NULL) { + os_calloc(2, sizeof(char *), syscheck->registry); + syscheck->registry[pl + 1] = NULL; + os_strdup(entry, syscheck->registry[pl]); + } else { + while (syscheck->registry[pl] != NULL) { + pl++; + } + os_realloc(syscheck->registry, (pl + 2) * sizeof(char *), + syscheck->registry); + syscheck->registry[pl + 1] = NULL; + os_strdup(entry, syscheck->registry[pl]); + } +#endif + } + + else { + if (syscheck->dir == NULL) { + os_calloc(2, sizeof(char *), syscheck->dir); + syscheck->dir[pl + 1] = NULL; + os_strdup(entry, syscheck->dir[pl]); + + os_calloc(2, sizeof(int), syscheck->opts); + syscheck->opts[pl + 1] = 0; + syscheck->opts[pl] = vals; + + os_calloc(2, sizeof(OSMatch *), syscheck->filerestrict); + syscheck->filerestrict[pl] = NULL; + syscheck->filerestrict[pl + 1] = NULL; + } else { + while (syscheck->dir[pl] != NULL) { + pl++; + } + os_realloc(syscheck->dir, (pl + 2) * sizeof(char *), + syscheck->dir); + syscheck->dir[pl + 1] = NULL; + os_strdup(entry, syscheck->dir[pl]); + + os_realloc(syscheck->opts, (pl + 2) * sizeof(int), + syscheck->opts); + syscheck->opts[pl + 1] = 0; + syscheck->opts[pl] = vals; + + os_realloc(syscheck->filerestrict, (pl + 2) * sizeof(OSMatch *), + syscheck->filerestrict); + syscheck->filerestrict[pl] = NULL; + syscheck->filerestrict[pl + 1] = NULL; + } + if (restrictfile) { + os_calloc(1, sizeof(OSMatch), syscheck->filerestrict[pl]); + if (!OSMatch_Compile(restrictfile, syscheck->filerestrict[pl], 0)) { + OSMatch *ptm; + + ptm = syscheck->filerestrict[pl]; + + merror(REGEX_COMPILE, __local_name, restrictfile, + ptm->error); + free(syscheck->filerestrict[pl]); + syscheck->filerestrict[pl] = NULL; + } + } + } + + return (1); +} + +#ifdef WIN32 +/* Read Windows registry configuration */ +int read_reg(syscheck_config *syscheck, char *entries) +{ + int i; + char **entry; + char *tmp_str; + + /* Get each entry separately */ + entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */ + + if (entry == NULL) { + return (0); + } + + while (*entry) { + char *tmp_entry; + + tmp_entry = *entry; + + /* Remove spaces at the beginning */ + while (*tmp_entry == ' ') { + tmp_entry++; + } + + /* Remove spaces at the end */ + tmp_str = strchr(tmp_entry, ' '); + if (tmp_str) { + tmp_str++; + + /* Check if it is really at the end */ + if ((*tmp_str == '\0') || (*tmp_str == ' ')) { + tmp_str--; + *tmp_str = '\0'; + } + } + + /* Add entries - look for the last available */ + i = 0; + while (syscheck->registry && syscheck->registry[i]) { + int str_len_i; + int str_len_dir; + + str_len_dir = strlen(tmp_entry); + str_len_i = strlen(syscheck->registry[i]); + + if (str_len_dir > str_len_i) { + str_len_dir = str_len_i; + } + + /* Duplicated entry */ + if (strcmp(syscheck->registry[i], tmp_entry) == 0) { + merror(SK_DUP, __local_name, tmp_entry); + return (1); + } + i++; + } + + /* Add new entry */ + dump_syscheck_entry(syscheck, tmp_entry, 0, 1, NULL); + + /* Next entry */ + entry++; + } + + return (1); +} +#endif /* WIN32 */ + +/* Read directories attributes */ +static int read_attr(syscheck_config *syscheck, const char *dirs, char **g_attrs, char **g_values) +{ + const char *xml_check_all = "check_all"; + const char *xml_check_sum = "check_sum"; + const char *xml_check_sha1sum = "check_sha1sum"; + const char *xml_check_md5sum = "check_md5sum"; + const char *xml_check_size = "check_size"; + const char *xml_check_owner = "check_owner"; + const char *xml_check_group = "check_group"; + const char *xml_check_perm = "check_perm"; + const char *xml_real_time = "realtime"; + const char *xml_report_changes = "report_changes"; + const char *xml_restrict = "restrict"; + const char *xml_no_recurse = "no_recurse"; + + char *restrictfile = NULL; + char **dir; + char *tmp_str; + dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */ + char **dir_org = dir; + + int ret = 0, i; + + /* Dir can not be null */ + if (dir == NULL) { + return (0); + } + + while (*dir) { + int j = 0; + int opts = 0; + char *tmp_dir; + + char **attrs = NULL; + char **values = NULL; + + tmp_dir = *dir; + restrictfile = NULL; + + /* Remove spaces at the beginning */ + while (*tmp_dir == ' ') { + tmp_dir++; + } + + /* Remove spaces at the end */ + tmp_str = strchr(tmp_dir, ' '); + if (tmp_str) { + tmp_str++; + + /* Check if it is really at the end */ + if ((*tmp_str == '\0') || (*tmp_str == ' ')) { + tmp_str--; + *tmp_str = '\0'; + } + } + + /* Get the options */ + if (!g_attrs || !g_values) { + merror(SYSCHECK_NO_OPT, __local_name, dirs); + ret = 0; + goto out_free; + } + + attrs = g_attrs; + values = g_values; + + while (*attrs && *values) { + /* Check all */ + if (strcmp(*attrs, xml_check_all) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_MD5SUM; + opts |= CHECK_SHA1SUM; + opts |= CHECK_PERM; + opts |= CHECK_SIZE; + opts |= CHECK_OWNER; + opts |= CHECK_GROUP; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ ( CHECK_MD5SUM | CHECK_SHA1SUM | CHECK_PERM + | CHECK_SIZE | CHECK_OWNER | CHECK_GROUP ); + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check sum */ + else if (strcmp(*attrs, xml_check_sum) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_MD5SUM; + opts |= CHECK_SHA1SUM; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ ( CHECK_MD5SUM | CHECK_SHA1SUM ); + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check md5sum */ + else if (strcmp(*attrs, xml_check_md5sum) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_MD5SUM; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_MD5SUM; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check sha1sum */ + else if (strcmp(*attrs, xml_check_sha1sum) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_SHA1SUM; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_SHA1SUM; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check permission */ + else if (strcmp(*attrs, xml_check_perm) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_PERM; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_PERM; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check size */ + else if (strcmp(*attrs, xml_check_size) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_SIZE; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_SIZE; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check owner */ + else if (strcmp(*attrs, xml_check_owner) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_OWNER; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_OWNER; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } + /* Check group */ + else if (strcmp(*attrs, xml_check_group) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_GROUP; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_GROUP; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } else if (strcmp(*attrs, xml_real_time) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_REALTIME; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_REALTIME; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } else if (strcmp(*attrs, xml_report_changes) == 0) { + if (strcmp(*values, "yes") == 0) { + opts |= CHECK_SEECHANGES; + } else if (strcmp(*values, "no") == 0) { + opts &= ~ CHECK_SEECHANGES; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } else if (strcmp(*attrs, xml_restrict) == 0) { + if (restrictfile) { + free(restrictfile); + restrictfile = NULL; + } + os_strdup(*values, restrictfile); + } else if (strcmp(*attrs, xml_no_recurse) == 0) { + if(strcmp(*values, "yes") == 0) { + opts |= CHECK_NORECURSE; + } else { + merror(SK_INV_OPT, __local_name, *values, *attrs); + ret = 0; + goto out_free; + } + } else { + merror(SK_INV_ATTR, __local_name, *attrs); + ret = 0; + goto out_free; + } + attrs++; + values++; + } + + /* You must have something set */ + if (opts == 0) { + merror(SYSCHECK_NO_OPT, __local_name, dirs); + ret = 0; + goto out_free; + } + + /* Add directory - look for the last available */ + j = 0; + while (syscheck->dir && syscheck->dir[j]) { + /* Duplicate entry */ + if (strcmp(syscheck->dir[j], tmp_dir) == 0) { + merror(SK_DUP, __local_name, tmp_dir); + ret = 1; + goto out_free; + } + + j++; + } + + /* Check for glob */ + /* The mingw32 builder used by travis.ci can't find glob.h + * Yet glob must work on actual win32. + */ +#ifndef __MINGW32__ + if (strchr(tmp_dir, '*') || + strchr(tmp_dir, '?') || + strchr(tmp_dir, '[')) { + int gindex = 0; + glob_t g; + + if (glob(tmp_dir, 0, NULL, &g) != 0) { + merror(GLOB_ERROR, __local_name, tmp_dir); + ret = 1; + goto out_free; + } + + if (g.gl_pathv[0] == NULL) { + merror(GLOB_NFOUND, __local_name, tmp_dir); + ret = 1; + goto out_free; + } + + while (g.gl_pathv[gindex]) { + dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile); + gindex++; + } + + globfree(&g); + } + + else { + dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile); + } +#else + dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile); +#endif + + if (restrictfile) { + free(restrictfile); + restrictfile = NULL; + } + + /* Next entry */ + dir++; + } + + ret = 1; + +out_free: + + i = 0; + while (dir_org[i]) { + free(dir_org[i++]); + } + + free(dir_org); + free(restrictfile); + + return ret; +} + +int Read_Syscheck(XML_NODE node, void *configp, __attribute__((unused)) void *mailp) +{ + int i = 0; + + /* XML Definitions */ + const char *xml_directories = "directories"; + const char *xml_registry = "windows_registry"; + const char *xml_time = "frequency"; + const char *xml_scanday = "scan_day"; + const char *xml_scantime = "scan_time"; + const char *xml_ignore = "ignore"; + const char *xml_registry_ignore = "registry_ignore"; + const char *xml_auto_ignore = "auto_ignore"; + const char *xml_alert_new_files = "alert_new_files"; + const char *xml_disabled = "disabled"; + const char *xml_scan_on_start = "scan_on_start"; + const char *xml_prefilter_cmd = "prefilter_cmd"; + const char *xml_skip_nfs = "skip_nfs"; + const char *xml_nodiff = "nodiff"; + + /* Configuration example + /etc,/usr/bin + /var/log + */ + + syscheck_config *syscheck; + syscheck = (syscheck_config *)configp; + unsigned int nodiff_size = 0; + + while (node[i]) { + if (!node[i]->element) { + merror(XML_ELEMNULL, __local_name); + return (OS_INVALID); + } else if (!node[i]->content) { + merror(XML_VALUENULL, __local_name, node[i]->element); + return (OS_INVALID); + } + + /* Get directories */ + else if (strcmp(node[i]->element, xml_directories) == 0) { + char dirs[OS_MAXSTR]; + +#ifdef WIN32 + ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) - 1); +#else + strncpy(dirs, node[i]->content, sizeof(dirs) - 1); +#endif + + if (!read_attr(syscheck, + dirs, + node[i]->attributes, + node[i]->values)) { + return (OS_INVALID); + } + } + /* Get Windows registry */ + else if (strcmp(node[i]->element, xml_registry) == 0) { +#ifdef WIN32 + if (!read_reg(syscheck, node[i]->content)) { + return (OS_INVALID); + } +#endif + } + /* Get frequency */ + else if (strcmp(node[i]->element, xml_time) == 0) { + if (!OS_StrIsNum(node[i]->content)) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + + syscheck->time = atoi(node[i]->content); + } + /* Get scan time */ + else if (strcmp(node[i]->element, xml_scantime) == 0) { + syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content); + if (!syscheck->scan_time) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + + /* Get scan day */ + else if (strcmp(node[i]->element, xml_scanday) == 0) { + syscheck->scan_day = OS_IsValidDay(node[i]->content); + if (!syscheck->scan_day) { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + + /* Get if xml_scan_on_start */ + else if (strcmp(node[i]->element, xml_scan_on_start) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + syscheck->scan_on_start = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + syscheck->scan_on_start = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + + /* Get if disabled */ + else if (strcmp(node[i]->element, xml_disabled) == 0) { + if (strcmp(node[i]->content, "yes") == 0) { + syscheck->disabled = 1; + } else if (strcmp(node[i]->content, "no") == 0) { + syscheck->disabled = 0; + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + + /* Getting if skip_nfs. */ + else if (strcmp(node[i]->element,xml_skip_nfs) == 0) + { + if(strcmp(node[i]->content, "yes") == 0) + syscheck->skip_nfs = 1; + else if(strcmp(node[i]->content, "no") == 0) + syscheck->skip_nfs = 0; + else + { + merror(XML_VALUEERR,__local_name,node[i]->element,node[i]->content); + return(OS_INVALID); + } + } + + /* Getting file/dir ignore */ + else if (strcmp(node[i]->element,xml_ignore) == 0) + { + unsigned int ign_size = 0; + +#ifdef WIN32 + /* For Windows, we attempt to expand environment variables */ + char *new_ig = NULL; + os_calloc(2048, sizeof(char), new_ig); + + ExpandEnvironmentStrings(node[i]->content, new_ig, 2047); + + free(node[i]->content); + node[i]->content = new_ig; +#endif + /* Add if regex */ + if (node[i]->attributes && node[i]->values) { + if (node[i]->attributes[0] && node[i]->values[0] && + (strcmp(node[i]->attributes[0], "type") == 0) && + (strcmp(node[i]->values[0], "sregex") == 0)) { + OSMatch *mt_pt; + + if (!syscheck->ignore_regex) { + os_calloc(2, sizeof(OSMatch *), syscheck->ignore_regex); + syscheck->ignore_regex[0] = NULL; + syscheck->ignore_regex[1] = NULL; + } else { + while (syscheck->ignore_regex[ign_size] != NULL) { + ign_size++; + } + + os_realloc(syscheck->ignore_regex, + sizeof(OSMatch *) * (ign_size + 2), + syscheck->ignore_regex); + syscheck->ignore_regex[ign_size + 1] = NULL; + } + os_calloc(1, sizeof(OSMatch), + syscheck->ignore_regex[ign_size]); + + if (!OSMatch_Compile(node[i]->content, + syscheck->ignore_regex[ign_size], 0)) { + mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size]; + merror(REGEX_COMPILE, __local_name, node[i]->content, + mt_pt->error); + return (0); + } + } else { + if (node[i]->attributes[0] != NULL) { + merror(SK_INV_ATTR, __local_name, node[i]->attributes[0]); + } + return (OS_INVALID); + } + } + + /* Add if simple entry -- check for duplicates */ + else if (!os_IsStrOnArray(node[i]->content, syscheck->ignore)) { + if (!syscheck->ignore) { + os_calloc(2, sizeof(char *), syscheck->ignore); + syscheck->ignore[0] = NULL; + syscheck->ignore[1] = NULL; + } else { + while (syscheck->ignore[ign_size] != NULL) { + ign_size++; + } + + os_realloc(syscheck->ignore, + sizeof(char *) * (ign_size + 2), + syscheck->ignore); + syscheck->ignore[ign_size + 1] = NULL; + } + os_strdup(node[i]->content, syscheck->ignore[ign_size]); + } + } + + /* Get registry ignore list */ + else if (strcmp(node[i]->element, xml_registry_ignore) == 0) { +#ifdef WIN32 + int ign_size = 0; + + /* Add if regex */ + if (node[i]->attributes && node[i]->values) { + if (node[i]->attributes[0] && node[i]->values[0] && + (strcmp(node[i]->attributes[0], "type") == 0) && + (strcmp(node[i]->values[0], "sregex") == 0)) { + OSMatch *mt_pt; + + if (!syscheck->registry_ignore_regex) { + os_calloc(2, sizeof(OSMatch *), + syscheck->registry_ignore_regex); + syscheck->registry_ignore_regex[0] = NULL; + syscheck->registry_ignore_regex[1] = NULL; + } else { + while (syscheck->registry_ignore_regex[ign_size] != NULL) { + ign_size++; + } + + os_realloc(syscheck->registry_ignore_regex, + sizeof(OSMatch *) * (ign_size + 2), + syscheck->registry_ignore_regex); + syscheck->registry_ignore_regex[ign_size + 1] = NULL; + } + + os_calloc(1, sizeof(OSMatch), + syscheck->registry_ignore_regex[ign_size]); + + if (!OSMatch_Compile(node[i]->content, + syscheck->registry_ignore_regex[ign_size], 0)) { + mt_pt = (OSMatch *) + syscheck->registry_ignore_regex[ign_size]; + merror(REGEX_COMPILE, __local_name, node[i]->content, + mt_pt->error); + return (0); + } + } else { + merror(SK_INV_ATTR, __local_name, node[i]->attributes[0]); + return (OS_INVALID); + } + } + /* We do not add duplicated entries */ + else if (!os_IsStrOnArray(node[i]->content, + syscheck->registry_ignore)) { + if (!syscheck->registry_ignore) { + os_calloc(2, sizeof(char *), syscheck->registry_ignore); + syscheck->registry_ignore[0] = NULL; + syscheck->registry_ignore[1] = NULL; + } else { + while (syscheck->registry_ignore[ign_size] != NULL) { + ign_size++; + } + + os_realloc(syscheck->registry_ignore, + sizeof(char *) * (ign_size + 2), + syscheck->registry_ignore); + syscheck->registry_ignore[ign_size + 1] = NULL; + } + os_strdup(node[i]->content, syscheck->registry_ignore[ign_size]); + } +#endif + /* Getting file/dir nodiff */ + } else if (strcmp(node[i]->element,xml_nodiff) == 0) { +#ifdef WIN32 + /* For Windows, we attempt to expand environment variables */ + char *new_nodiff = NULL; + os_calloc(2048, sizeof(char), new_nodiff); + + ExpandEnvironmentStrings(node[i]->content, new_nodiff, 2047); + + free(node[i]->content); + node[i]->content = new_nodiff; +#endif + /* Add if regex */ + if (node[i]->attributes && node[i]->values) { + if (node[i]->attributes[0] && node[i]->values[0] && + (strcmp(node[i]->attributes[0], "type") == 0) && + (strcmp(node[i]->values[0], "sregex") == 0)) { + OSMatch *mt_pt; + if (!syscheck->nodiff_regex) { + os_calloc(2, sizeof(OSMatch *), syscheck->nodiff_regex); + syscheck->nodiff_regex[0] = NULL; + syscheck->nodiff_regex[1] = NULL; + } else { + while (syscheck->nodiff_regex[nodiff_size] != NULL) { + nodiff_size++; + } + + os_realloc(syscheck->nodiff_regex, + sizeof(OSMatch *) * (nodiff_size + 2), + syscheck->nodiff_regex); + syscheck->nodiff_regex[nodiff_size + 1] = NULL; + } + os_calloc(1, sizeof(OSMatch), + syscheck->nodiff_regex[nodiff_size]); + debug1("Found nodiff regex node %s", node[i]->content); + if (!OSMatch_Compile(node[i]->content, + syscheck->nodiff_regex[nodiff_size], 0)) { + mt_pt = (OSMatch *)syscheck->nodiff_regex[nodiff_size]; + merror(REGEX_COMPILE, __local_name, node[i]->content, + mt_pt->error); + return (0); + } + if (node[i]->content != NULL) { + debug1("Found nodiff regex node %s OK?", node[i]->content); + } + debug1("Found nodiff regex size %d", nodiff_size); + } else { + if (node[i]->attributes[0] != NULL) { + merror(SK_INV_ATTR, __local_name, node[i]->attributes[0]); + } + return (OS_INVALID); + } + } + + /* Add if simple entry -- check for duplicates */ + else if (!os_IsStrOnArray(node[i]->content, syscheck->nodiff)) { + if (!syscheck->nodiff) { + os_calloc(2, sizeof(char *), syscheck->nodiff); + syscheck->nodiff[0] = NULL; + syscheck->nodiff[1] = NULL; + } else { + while (syscheck->nodiff[nodiff_size] != NULL) { + nodiff_size++; + } + + os_realloc(syscheck->nodiff, + sizeof(char *) * (nodiff_size + 2), + syscheck->nodiff); + syscheck->nodiff[nodiff_size + 1] = NULL; + } + os_strdup(node[i]->content, syscheck->nodiff[nodiff_size]); + } + } else if (strcmp(node[i]->element, xml_auto_ignore) == 0) { + /* auto_ignore is not read here */ + } else if (strcmp(node[i]->element, xml_alert_new_files) == 0) { + /* alert_new_files option is not read here */ + } else if (strcmp(node[i]->element, xml_prefilter_cmd) == 0) { + char cmd[OS_MAXSTR]; + struct stat statbuf; + +#ifdef WIN32 + ExpandEnvironmentStrings(node[i]->content, cmd, sizeof(cmd) - 1); +#else + strncpy(cmd, node[i]->content, sizeof(cmd) - 1); +#endif + + if (strlen(cmd) > 0) { + char statcmd[OS_MAXSTR]; + char *ix; + strncpy(statcmd, cmd, sizeof(statcmd) - 1); + if (NULL != (ix = strchr(statcmd, ' '))) { + *ix = '\0'; + } + if (stat(statcmd, &statbuf) == 0) { + /* More checks needed (perms, owner, etc.) */ + os_calloc(1, strlen(cmd) + 1, syscheck->prefilter_cmd); + strncpy(syscheck->prefilter_cmd, cmd, strlen(cmd)); + } else { + merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content); + return (OS_INVALID); + } + } + } else { + merror(XML_INVELEM, __local_name, node[i]->element); + return (OS_INVALID); + } + i++; + } + + return (0); +} + + +/* return a text version of the directory check option bits, + * in a provided string buffer + */ +char *syscheck_opts2str(char *buf, int buflen, int opts) { + int left = buflen; + int i; + int check_bits[] = { + CHECK_PERM, + CHECK_SIZE, + CHECK_OWNER, + CHECK_GROUP, + CHECK_MD5SUM, + CHECK_SHA1SUM, + CHECK_REALTIME, + CHECK_SEECHANGES, + CHECK_NORECURSE, + 0 + }; + char *check_strings[] = { + "perm", + "size", + "owner", + "group", + "md5sum", + "sha1sum", + "realtime", + "report_changes", + "no_recurse", + NULL + }; + + buf[0] = '\0'; + for ( i = 0; check_bits[ i ]; i++ ) { + if ( opts & check_bits[ i ] ) { + if ( left < buflen ) { + strncat( buf, " | ", left ); + left -= 3; + } + strncat( buf, check_strings[ i ], left ); + left = buflen - strlen( buf ); + } + } + + return buf; + } + diff --git a/src/config/syscheck-config.h b/src/config/syscheck-config.h new file mode 100644 index 000000000..51ca01a05 --- /dev/null +++ b/src/config/syscheck-config.h @@ -0,0 +1,93 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __SYSCHECKC_H +#define __SYSCHECKC_H + +#define MAX_DIR_SIZE 64 +#define MAX_DIR_ENTRY 128 +#define SYSCHECK_WAIT 300 + +/* Checking options */ +#define CHECK_MD5SUM 0000001 +#define CHECK_PERM 0000002 +#define CHECK_SIZE 0000004 +#define CHECK_OWNER 0000010 +#define CHECK_GROUP 0000020 +#define CHECK_SHA1SUM 0000040 +#define CHECK_REALTIME 0000100 +#define CHECK_SEECHANGES 0000200 +#define CHECK_SHA256SUM 0000400 +#define CHECK_GENERIC 0001000 +#define CHECK_NORECURSE 0002000 + + +#include + +#include "os_regex/os_regex.h" + +typedef struct _rtfim { + int fd; + OSHash *dirtb; +#ifdef WIN32 + HANDLE evt; +#endif +} rtfim; + +typedef struct _config { + unsigned int tsleep; /* sleep for sometime for daemon to settle */ + int sleep_after; + int rootcheck; /* set to 0 when rootcheck is disabled */ + int disabled; /* is syscheck disabled? */ + int scan_on_start; + int realtime_count; + short skip_nfs; + + int time; /* frequency (secs) for syscheck to run */ + int queue; /* file descriptor of socket to write to queue */ + + int *opts; /* attributes set in the tag element */ + + char *remote_db; + char *db; + + char *scan_day; /* run syscheck on this day */ + char *scan_time; /* run syscheck at this time */ + + char **ignore; /* list of files/dirs to ignore */ + OSMatch **ignore_regex; /* regex of files/dirs to ignore */ + + char **nodiff; /* list of files/dirs to never output diff */ + OSMatch **nodiff_regex; /* regex of files/dirs to never output diff */ + + char **dir; /* array of directories to be scanned */ + OSMatch **filerestrict; + + /* Windows only registry checking */ +#ifdef WIN32 + char **registry_ignore; /* list of registry entries to ignore */ + void **registry_ignore_regex; /* regex of registry entries to ignore */ + char **registry; /* array of registry entries to be scanned */ + FILE *reg_fp; +#endif + + OSHash *fp; + + rtfim *realtime; + + char *prefilter_cmd; + +} syscheck_config; + +int dump_syscheck_entry(syscheck_config *syscheck, const char *entry, int vals, int reg, const char *restrictfile) __attribute__((nonnull(1, 2))); + +char *syscheck_opts2str(char *buf, int buflen, int opts); + +#endif /* __SYSCHECKC_H */ + diff --git a/src/error_messages/error_messages.h b/src/error_messages/error_messages.h new file mode 100644 index 000000000..ac315ebaf --- /dev/null +++ b/src/error_messages/error_messages.h @@ -0,0 +1,296 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _ERROR_MESSAGES__H +#define _ERROR_MESSAGES__H + +/*** Error messages - English ***/ + +/* SYSTEM ERRORS */ +#define FORK_ERROR "%s(1101): ERROR: Could not fork due to [(%d)-(%s)]." +#define MEM_ERROR "%s(1102): ERROR: Could not acquire memory due to [(%d)-(%s)]." +#define FOPEN_ERROR "%s(1103): ERROR: Could not open file '%s' due to [(%d)-(%s)]." +#define SIZE_ERROR "%s(1104): ERROR: Maximum string size reached for: %s." +#define NULL_ERROR "%s(1105): ERROR: Attempted to use null string. " +#define FORMAT_ERROR "%s(1106): ERROR: String not correctly formatted." +#define MKDIR_ERROR "%s(1107): ERROR: Could not create directory '%s' due to [(%d)-(%s)]." +//#define PERM_ERROR "%s(1108): ERROR: Permission error. Operation not completed." +#define THREAD_ERROR "%s(1109): ERROR: Unable to create new pthread." +//#define READ_ERROR "%s(1110): ERROR: Unable to read from socket." +#define WAITPID_ERROR "%s(1111): ERROR: Error during waitpid()-call due to [(%d)-(%s)]." +#define SETSID_ERROR "%s(1112): ERROR: Error during setsid()-call due to [(%d)-(%s)]." +#define MUTEX_ERROR "%s(1113): ERROR: Unable to set pthread mutex." +#define SELECT_ERROR "%s(1114): ERROR: Error during select()-call due to [(%d)-(%s)]." +#define FREAD_ERROR "%s(1115): ERROR: Could not read from file '%s' due to [(%d)-(%s)]." +#define FSEEK_ERROR "%s(1116): ERROR: Could not set position in file '%s' due to [(%d)-(%s)]." +#define FILE_ERROR "%s(1117): ERROR: Error handling file '%s' (date)." +#define FSTAT_ERROR "%s(1117): ERROR: Could not retrieve informations of file '%s' due to [(%d)-(%s)]." +#define FGETS_ERROR "%s(1119): ERROR: Invalid line on file '%s': %s." +//#define PIPE_ERROR "%s(1120): ERROR: Pipe error." +#define GLOB_ERROR "%s(1121): ERROR: Glob error. Invalid pattern: '%s'." +#define GLOB_NFOUND "%s(1122): ERROR: No file found by pattern: '%s'." +#define UNLINK_ERROR "%s(1123): ERROR: Unable to delete file: '%s'." +#define RENAME_ERROR "%s(1124): ERROR: Could not rename file '%s' to '%s' due to [(%d)-(%s)]." +#define INT_ERROR "%s(1125): ERROR: Internal error (undefined)." +#define OPEN_ERROR "%s(1126): ERROR: Unable to open file '%s' due to [(%d)-(%s)]." +#define CHMOD_ERROR "%s(1127): ERROR: Could not chmod object '%s' due to [(%d)-(%s)]." +#define MKSTEMP_ERROR "%s(1128): ERROR: Could not create temporary file '%s' due to [(%d)-(%s)]." +#define DELETE_ERROR "%s(1129): ERROR: Could not unlink file '%s' due to [(%d)-(%s)]." +#define SETGID_ERROR "%s(1130): ERROR: Unable to switch to group '%s' due to [(%d)-(%s)]." +#define SETUID_ERROR "%s(1131): ERROR: Unable to switch to user '%s' due to [(%d)-(%s)]." +#define CHROOT_ERROR "%s(1132): ERROR: Unable to chroot to directory '%s' due to [(%d)-(%s)]." +#define CHDIR_ERROR "%s(1133): ERROR: Unable to chdir to directory '%s' due to [(%d)-(%s)]." +#define LINK_ERROR "%s(1134): ERROR: Unable to link from '%s' to '%s' due to [(%d)-(%s)]." +#define CHOWN_ERROR "%s(1135): ERROR: Could not chown object '%s' due to [(%d)-(%s)]." +/* auditd support */ +#define FTELL_ERROR "%s(1139): ERROR: Could not get position from file '%s' due to [(%d)-(%s)]." + + +/* COMMON ERRORS */ +#define CONN_ERROR "%s(1201): ERROR: No remote connection configured." +#define CONFIG_ERROR "%s(1202): ERROR: Configuration error at '%s'. Exiting." +#define USER_ERROR "%s(1203): ERROR: Invalid user '%s' or group '%s' given." +#define CONNTYPE_ERROR "%s(1204): ERROR: Invalid connection type: '%s'." +#define PORT_ERROR "%s(1205): INFO: No port specified. Using default: '%d'." +#define BIND_ERROR "%s(1206): ERROR: Unable to Bind port '%s'" +#define QUEUE_ERROR "%s(1210): ERROR: Queue '%s' not accessible: '%s'." +#define QUEUE_FATAL "%s(1211): ERROR: Unable to access queue: '%s'. Giving up.." +#define PID_ERROR "%s(1212): ERROR: Unable to create PID file." +#define DENYIP_WARN "%s(1213): WARN: Message from '%s' not allowed." +#define MSG_ERROR "%s(1214): WARN: Problem receiving message from '%s'." +#define CLIENT_ERROR "%s(1215): ERROR: No client configured. Exiting." +#define CONNS_ERROR "%s(1216): ERROR: Unable to connect to '%s'." +#define UNABLE_CONN "%s(1242): ERROR: Unable to connect to server. Exhausted all options." +#define SEC_ERROR "%s(1217): ERROR: Error creating encrypted message." +#define SEND_ERROR "%s(1218): ERROR: Unable to send message to '%s'." +#define RULESLOAD_ERROR "%s(1219): ERROR: Unable to access the rules directory." +#define RULES_ERROR "%s(1220): ERROR: Error loading the rules: '%s'." +#define LISTS_ERROR "%s(1221): ERROR: Error loading the list: '%s'." +#define QUEUE_SEND "%s(1224): ERROR: Error sending message to queue." +#define SIGNAL_RECV "%s(1225): INFO: SIGNAL [(%d)-(%s)] Received. Exit Cleaning..." +#define XML_ERROR "%s(1226): ERROR: Error reading XML file '%s': %s (line %d)." +#define XML_ERROR_VAR "%s(1227): ERROR: Error applying XML variables '%s': %s." +#define XML_NO_ELEM "%s(1228): ERROR: Element '%s' without any option." +#define XML_INVALID "%s(1229): ERROR: Invalid element '%s' on the '%s' config." +#define XML_INVELEM "%s(1230): ERROR: Invalid element in the configuration: '%s'." +#define XML_INVATTR "%s(1243): ERROR: Invalid attribute '%s' in the configuration: '%s'." +#define XML_ELEMNULL "%s(1231): ERROR: Invalid NULL element in the configuration." +#define XML_READ_ERROR "%s(1232): ERROR: Error reading XML. Unknown cause." +#define XML_VALUENULL "%s(1234): ERROR: Invalid NULL content for element: %s." +#define XML_VALUEERR "%s(1235): ERROR: Invalid value for element '%s': %s." +#define XML_MAXREACHED "%s(1236): ERROR: Maximum number of elements reached for: %s." +#define INVALID_IP "%s(1237): ERROR: Invalid ip address: '%s'." +#define INVALID_ELEMENT "%s(1238): ERROR: Invalid value for element '%s': %s" +#define NO_CONFIG "%s(1239): ERROR: Configuration file not found: '%s'." +#define INVALID_TIME "%s(1240): ERROR: Invalid time format: '%s'." +#define INVALID_DAY "%s(1241): ERROR: Invalid day format: '%s'." + +#define MAILQ_ERROR "%s(1221): ERROR: No Mail queue at %s" +#define IMSG_ERROR "%s(1222): ERROR: Invalid msg: %s" +#define SNDMAIL_ERROR "%s(1223): ERROR: Error Sending email to %s (smtp server)" +#define XML_INV_GRAN_MAIL "%s(1224): ERROR: Invalid 'email_alerts' config (missing parameters)." +#define CHLDWAIT_ERROR "%s(1261): ERROR: Waiting for child process. (status: %d)." +#define TOOMANY_WAIT_ERROR "%s(1262): ERROR: Too many errors waiting for child process(es)." + +/* rootcheck */ +#define MAX_RK_MSG "%s(1250): ERROR: Maximum number of global files reached: %d" +#define INVALID_RKCL_NAME "%s(1251): ERROR: Invalid rk configuration name: '%s'." +#define INVALID_RKCL_VALUE "%s(1252): ERROR: Invalid rk configuration value: '%s'." +#define INVALID_ROOTDIR "%s(1253): ERROR: Invalid rootdir (unable to retrieve)." +#define INVALID_RKCL_VAR "%s(1254): ERROR: Invalid rk variable: '%s'." + +/* syscheck */ +#define SYSCHECK_NO_OPT "%s(1701): WARN: No option provided for directories: '%s', ignoring it." +#define SK_NO_DIR "%s(1702): INFO: No directory provided for syscheck to monitor." +#define SK_INV_ATTR "%s(1703): ERROR: Invalid attribute '%s' for directory option." +#define SK_INV_OPT "%s(1704): ERROR: Invalid option '%s' for attribute '%s'" +#define SK_NO_DB "%s(1705): ERROR: No integrity database found at '%s'." +#define SK_INV_MSG "%s(1755): ERROR: Invalid syscheck message received." +#define SK_DUP "%s(1756): ERROR: Duplicated directory given: '%s'." +#define SK_INV_REG "%s(1757): ERROR: Invalid syscheck registry entry: '%s'." +#define SK_REG_OPEN "%s(1758): ERROR: Unable to open registry key using 32 bit registry: '%s'." +#define SK_REG_OPEN64 "%s(1759): ERROR: Unable to open registry key using 64 bit registry: '%s'." + +/* analysisd */ +#define FTS_LIST_ERROR "%s(1260): ERROR: Error initiating FTS list" +#define CRAFTED_IP "%s(1271): WARN: Invalid IP Address '%s'. Possible logging attack." +#define CRAFTED_USER "%s(1272): WARN: Invalid username '%s'. Possible logging attack." +#define INVALID_CAT "%s(1273): ERROR: Invalid category '%s' chosen." +#define INVALID_CONFIG "%s(1274): ERROR: Invalid configuration. Element '%s': %s." +#define INVALID_HOSTNAME "%s(1275): ERROR: Invalid hostname in syslog message: '%s'." +#define INVALID_GEOIP_DB "%s(1276): ERROR: Cannot open GeoIP database: '%s'." +#define INVALID_IGNORE_MD5DB "%s(1277) ERROR: Cannot open MD5 database: '%s'." +#define MD5_NOT_CHECKED "%s(1278) WARN: File with MD5 '%s' not processed." + +/* logcollector */ +#define SYSTEM_ERROR "%s(1600): ERROR: Internal error. Exiting.." + +/* remoted */ +#define NO_REM_CONN "%s(1750): ERROR: No remote connection configured. Exiting." +#define NO_CLIENT_KEYS "%s(1751): ERROR: File client.keys not found or empty." + + +/* 1760 - 1769 -- reserved for maild */ + +/* Active Response */ +#define AR_CMD_MISS "%s(1280): ERROR: Missing command options. " \ + "You must specify a 'name', 'executable' and 'expect'." +#define AR_MISS "%s(1281): ERROR: Missing options in the active response " \ + "configuration. " +#define ARQ_ERROR "%s(1301): ERROR: Unable to connect to active response queue." +#define AR_INV_LOC "%s(1302): ERROR: Invalid active response location: '%s'." +#define AR_INV_CMD "%s(1303): ERROR: Invalid command '%s' in the active response." +#define AR_DEF_AGENT "%s(1304): ERROR: No agent defined for response." +#define AR_NO_TIMEOUT "%s(1305): ERROR: Timeout not allowed for command: '%s'." + +#define EXECD_INV_MSG "%s(1310): WARN: Invalid active response (execd) message '%s'." +#define EXEC_INV_NAME "%s(1311): ERROR: Invalid command name '%s' provided." +#define EXEC_CMDERROR "%s(1312): ERROR: Error executing '%s': %s" +#define EXEC_INV_CONF "%s(1313): ERROR: Invalid active response config: '%s'." +#define EXEC_DISABLED "%s(1350): INFO: Active response disabled. Exiting." +#define EXEC_SHUTDOWN "%s(1314): INFO: Shutdown received. Deleting responses." + +#define AR_NOAGENT_ERROR "%s(1320): ERROR: Agent '%s' not found." + +/* List operations */ +#define LIST_ERROR "%s(1290): ERROR: Unable to create a new list (calloc)." +#define LIST_ADD_ERROR "%s(1291): ERROR: Error adding nodes to list." +#define LIST_SIZE_ERROR "%s(1292): ERROR: Error setting error size." +#define LIST_FREE_ERROR "%s(1293): ERROR: Error setting data free pointer." + +/* Log collector messages */ +#define MISS_LOG_FORMAT "%s(1901): ERROR: Missing 'log_format' element." +#define MISS_FILE "%s(1902): ERROR: Missing 'location' element." +#define INV_EVTLOG "%s(1903): ERROR: Invalid event log: '%s'." +#define NSTD_EVTLOG "%s(1907): INFO: Non-standard event log set: '%s'." +#define LOGC_FILE_ERROR "%s(1904): INFO: File not available, ignoring it: '%s'." +#define NO_FILE "%s(1905): INFO: No file configured to monitor." +#define PARSE_ERROR "%s(1906): ERROR: Error parsing file: '%s'." +#define READING_FILE "%s(1950): INFO: Analyzing file: '%s'." +#define READING_EVTLOG "%s(1951): INFO: Analyzing event log: '%s'." +#define READING_JOURNAL "%s(1951): INFO: Analyzing journald log: '%s'." +#define VAR_LOG_MON "%s(1952): INFO: Monitoring variable log file: '%s'." +#define INV_MULTILOG "%s(1953): ERROR: Invalid DJB multilog file: '%s'." + +/* Encryption/auth errors */ +#define INVALID_KEY "%s(1401): ERROR: Error reading authentication key: '%s'." +#define NO_AUTHFILE "%s(1402): ERROR: Authentication key file '%s' not found." +#define ENCFORMAT_ERROR "%s(1403): ERROR: Incorrectly formatted message from '%s'." +#define ENCKEY_ERROR "%s(1404): ERROR: Authentication error. Wrong key from '%s'." +#define ENCSIZE_ERROR "%s(1405): ERROR: Message size not valid: '%s'." +#define ENCSUM_ERROR "%s(1406): ERROR: Checksum mismatch on message from '%s'." +#define ENCTIME_ERROR "%s(1407): ERROR: Duplicated counter for '%s'." +#define ENC_IP_ERROR "%s(1408): ERROR: Invalid ID %s for the source ip: '%s'." +#define ENCFILE_CHANGED "%s(1409): INFO: Authentication file changed. Updating." +#define ENC_READ "%s(1410): INFO: Reading authentication keys file." + +/* Regex errors */ +#define REGEX_COMPILE "%s(1450): ERROR: Syntax error on regex: '%s': %d." +#define REGEX_SUBS "%s(1451): ERROR: Missing sub_strings on regex: '%s'." + +/* Mail errors */ +#define INVALID_SMTP "%s(1501): ERROR: Invalid SMTP Server: %s" +#define INVALID_MAIL "%s(1502): ERROR: Invalid Email Address: %s" + +/* Decoders */ +#define PPLUGIN_INV "%s(2101): ERROR: Parent decoder name invalid: '%s'." +#define PDUP_INV "%s(2102): ERROR: Duplicated decoder with prematch: '%s'." +#define PDUPFTS_INV "%s(2103): ERROR: Duplicated decoder with fts set: '%s'." +#define DUP_INV "%s(2104): ERROR: Invalid duplicated decoder: '%s'." +#define DEC_PLUGIN_ERR "%s(2105): ERROR: Error loading decoder options." +#define DECODER_ERROR "%s(2106): ERROR: Error adding decoder plugin." +#define DEC_REGEX_ERROR "%s(2107): ERROR: Decoder configuration error: '%s'." +#define DECODE_NOPRE "%s(2108): ERROR: No 'prematch' found in decoder: '%s'." +#define DUP_REGEX "%s(2109): ERROR: Duplicated offsets for same regex: '%s'." +#define INV_DECOPTION "%s(2110): ERROR: Invalid decoder argument for %s: '%s'." +#define DECODE_ADD "%s(2111): ERROR: Additional data to plugin decoder: '%s'." + +#define INV_OFFSET "%s(2120): ERROR: Invalid offset value: '%s'" +#define INV_ATTR "%s(2121): ERROR: Invalid decoder attribute: '%s'" + +/* os_zlib */ +#define COMPRESS_ERR "%s(2201): ERROR: Error compressing string: '%s'." +#define UNCOMPRESS_ERR "%s(2202): ERROR: Error uncompressing string." + +/* read defines */ +#define DEF_NOT_FOUND "%s(2301): ERROR: Definition not found for: '%s.%s'." +#define INV_DEF "%s(2302): ERROR: Invalid definition for %s.%s: '%s'." + +/* Agent errors */ +#define AG_WAIT_SERVER "%s(4101): WARN: Waiting for server reply (not started). Tried: '%s'." +#define AG_CONNECTED "%s(4102): INFO: Connected to server %s, port %s." +#define AG_USINGIP "%s(4103): INFO: Server IP address already set. Trying that before the hostname." +#define AG_INV_HOST "%s(4104): ERROR: Invalid hostname: '%s'." +#define AG_INV_IP "%s(4105): ERROR: No valid server IP found." +#define EVTLOG_OPEN "%s(4106): ERROR: Unable to open event log: '%s'." +#define EVTLOG_GETLAST "%s(4107): ERROR: Unable to query last event log from: '%s'." +#define EVTLOG_DUP "%s(4108): ERROR: Duplicated event log entry: '%s'." +#define AG_NOKEYS_EXIT "%s(4109): ERROR: Unable to start without auth keys. Exiting." +#define AG_MAX_ERROR "%s(4110): ERROR: Maximum number of agents '%d' reached." +#define AG_AX_AGENTS "%s(4111): INFO: Maximum number of agents allowed: '%d'." + +/* Rules reading errors */ +#define RL_INV_ROOT "%s(5101): ERROR: Invalid root element: '%s'." +#define RL_INV_RULE "%s(5102): ERROR: Invalid rule element: '%s'." +#define RL_INV_ENTRY "%s(5103): ERROR: Invalid rule on '%s'. Missing id/level." +#define RL_EMPTY_ATTR "%s(5104): ERROR: Rule attribute '%s' empty." +#define RL_INV_ATTR "%s(5105): ERROR: Invalid rule attributes inside file: '%s'." +#define RL_NO_OPT "%s(5106): ERROR: Rule '%d' without any options. "\ + "It may lead to false positives. Exiting. " + +/* Syslog output */ +#define XML_INV_CSYSLOG "%s(5301): ERROR: Invalid client-syslog configuration." + +/* Agentless */ +#define XML_INV_AGENTLESS "%s(7101): ERROR: Invalid agentless configuration." +#define XML_INV_MISSFREQ "%s(7102): ERROR: Frequency not set for the periodic option." +#define XML_INV_MISSOPTS "%s(7103): ERROR: Missing agentless options." + +/* Database messages */ +#define DBINIT_ERROR "%s(5201): ERROR: Error initializing database handler." +#define DBCONN_ERROR "%s(5202): ERROR: Error connecting to database '%s'(%s): ERROR: %s." +#define DBQUERY_ERROR "%s(5203): ERROR: Error executing query '%s'. Error: '%s'." +#define DB_GENERROR "%s(5204): ERROR: Database error. Unable to run query." +#define DB_MISS_CONFIG "%s(5205): ERROR: Missing database configuration. "\ + "It requires host, user, pass and database." +#define DB_CONFIGERR "%s(5206): ERROR: Database configuration error." +#define DB_COMPILED "%s(5207): ERROR: openarmor not compiled with support for '%s'." +#define DB_MAINERROR "%s(5208): ERROR: Multiple database errors. Exiting." +#define DB_CLOSING "%s(5209): INFO: Closing connection to database." +#define DB_ATTEMPT "%s(5210): INFO: Attempting to reconnect to database." + +/* Verbose messages */ +#define STARTUP_MSG "%s: INFO: Started (pid: %d)." +#define CHROOT_MSG "%s: INFO: Chrooted to directory: %s" +#define PRIVSEP_MSG "%s: INFO: Using user: %s" +#define MSG_SOCKET_SIZE "%s: INFO: (unix_domain) Maximum send buffer set to: '%d'." + +#define NO_SYSLOG "%s(1501): ERROR: No IP or network allowed in the access list" \ + " for syslog. No reason for running it. Exiting." +#define CONN_TO "%s: INFO: Connected to '%s' (%s queue)" +#define MAIL_DIS "%s: INFO: E-Mail notification disabled. Clean Exit." + +/* Debug Messages */ +#define STARTED_MSG "%s: DEBUG: Starting ..." +#define FOUND_USER "%s: DEBUG: Found user/group ..." +#define ASINIT "%s: DEBUG: Active response initialized ..." +#define READ_CONFIG "%s: DEBUG: Read configuration ..." + +/* Wait operations */ +#define WAITING_MSG "%s: WARN: Process locked. Waiting for permission..." +#define WAITING_FREE "%s: INFO: Lock free. Continuing..." +#define SERVER_UNAV "%s: WARN: Server unavailable. Setting lock." +#define SERVER_UP "%s: INFO: Server responded. Releasing lock." + +/* openarmor alert messages */ +#define OS_AD_STARTED "openarmor: openarmor started." +#define OS_AG_STARTED "openarmor: Agent started: '%s->%s'." +#define OS_AG_DISCON "openarmor: Agent disconnected: '%s'." + +#endif /* _ERROR_MESSAGES__H */ diff --git a/src/external/cJSON/LICENSE b/src/external/cJSON/LICENSE new file mode 100644 index 000000000..78deb0406 --- /dev/null +++ b/src/external/cJSON/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/src/external/cJSON/README b/src/external/cJSON/README new file mode 100644 index 000000000..7531c049a --- /dev/null +++ b/src/external/cJSON/README @@ -0,0 +1,247 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +Welcome to cJSON. + +cJSON aims to be the dumbest possible parser that you can get your job done with. +It's a single file of C, and a single header file. + +JSON is described best here: http://www.json.org/ +It's like XML, but fat-free. You use it to move data around, store things, or just +generally represent your program's state. + + +First up, how do I build? +Add cJSON.c to your project, and put cJSON.h somewhere in the header search path. +For example, to build the test app: + +gcc cJSON.c test.c -o test -lm +./test + + +As a library, cJSON exists to take away as much legwork as it can, but not get in your way. +As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it +in one of two modes: Auto and Manual. Let's have a quick run-through. + + +I lifted some JSON from this page: http://www.json.org/fatfree.html +That page inspired me to write cJSON, which is a parser that tries to share the same +philosophy as JSON itself. Simple, dumb, out of the way. + +Some JSON: +{ + "name": "Jack (\"Bee\") Nimble", + "format": { + "type": "rect", + "width": 1920, + "height": 1080, + "interlace": false, + "frame rate": 24 + } +} + +Assume that you got this from a file, a webserver, or magic JSON elves, whatever, +you have a char * to it. Everything is a cJSON struct. +Get it parsed: + cJSON *root = cJSON_Parse(my_json_string); + +This is an object. We're in C. We don't have objects. But we do have structs. +What's the framerate? + + cJSON *format = cJSON_GetObjectItem(root,"format"); + int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint; + + +Want to change the framerate? + cJSON_GetObjectItem(format,"frame rate")->valueint=25; + +Back to disk? + char *rendered=cJSON_Print(root); + +Finished? Delete the root (this takes care of everything else). + cJSON_Delete(root); + +That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers +before you dereference them. If you want to see how you'd build this struct in code? + cJSON *root,*fmt; + root=cJSON_CreateObject(); + cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble")); + cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject()); + cJSON_AddStringToObject(fmt,"type", "rect"); + cJSON_AddNumberToObject(fmt,"width", 1920); + cJSON_AddNumberToObject(fmt,"height", 1080); + cJSON_AddFalseToObject (fmt,"interlace"); + cJSON_AddNumberToObject(fmt,"frame rate", 24); + +Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup. +Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and +a few from elsewhere. + +What about manual mode? First up you need some detail. +Let's cover how the cJSON objects represent the JSON data. +cJSON doesn't distinguish arrays from objects in handling; just type. +Each cJSON has, potentially, a child, siblings, value, a name. + +The root object has: Object Type and a Child +The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling: +Sibling has type Object, name "format", and a child. +That child has type String, name "type", value "rect", and a sibling: +Sibling has type Number, name "width", value 1920, and a sibling: +Sibling has type Number, name "height", value 1080, and a sibling: +Sibling hs type False, name "interlace", and a sibling: +Sibling has type Number, name "frame rate", value 24 + +Here's the structure: +typedef struct cJSON { + struct cJSON *next,*prev; + struct cJSON *child; + + int type; + + char *valuestring; + int valueint; + double valuedouble; + + char *string; +} cJSON; + +By default all values are 0 unless set by virtue of being meaningful. + +next/prev is a doubly linked list of siblings. next takes you to your sibling, +prev takes you back from your sibling to you. +Only objects and arrays have a "child", and it's the head of the doubly linked list. +A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0. +The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in +cJSON.h + +A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read +valuedouble. + +Any entry which is in the linked list which is the child of an object will have a "string" +which is the "name" of the entry. When I said "name" in the above example, that's "string". +"string" is the JSON name for the 'variable name' if you will. + +Now you can trivially walk the lists, recursively, and parse as you please. +You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take +the root object, and traverse the structure (which is, formally, an N-tree), +and tokenise as you please. If you wanted to build a callback style parser, this is how +you'd do it (just an example, since these things are very specific): + +void parse_and_callback(cJSON *item,const char *prefix) +{ + while (item) + { + char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2); + sprintf(newprefix,"%s/%s",prefix,item->name); + int dorecurse=callback(newprefix, item->type, item); + if (item->child && dorecurse) parse_and_callback(item->child,newprefix); + item=item->next; + free(newprefix); + } +} + +The prefix process will build you a separated list, to simplify your callback handling. +The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or +let you invoke it per-item. For the item above, your callback might look like this: + +int callback(const char *name,int type,cJSON *item) +{ + if (!strcmp(name,"name")) { /* populate name */ } + else if (!strcmp(name,"format/type") { /* handle "rect" */ } + else if (!strcmp(name,"format/width") { /* 800 */ } + else if (!strcmp(name,"format/height") { /* 600 */ } + else if (!strcmp(name,"format/interlace") { /* false */ } + else if (!strcmp(name,"format/frame rate") { /* 24 */ } + return 1; +} + +Alternatively, you might like to parse iteratively. +You'd use: + +void parse_object(cJSON *item) +{ + int i; for (i=0;ichild; + while (subitem) + { + // handle subitem + if (subitem->child) parse_object(subitem->child); + + subitem=subitem->next; + } +} + +Of course, this should look familiar, since this is just a stripped-down version +of the callback-parser. + +This should cover most uses you'll find for parsing. The rest should be possible +to infer.. and if in doubt, read the source! There's not a lot of it! ;) + + +In terms of constructing JSON data, the example code above is the right way to do it. +You can, of course, hand your sub-objects to other functions to populate. +Also, if you find a use for it, you can manually build the objects. +For instance, suppose you wanted to build an array of objects? + +cJSON *objects[24]; + +cJSON *Create_array_of_anything(cJSON **items,int num) +{ + int i;cJSON *prev, *root=cJSON_CreateArray(); + for (i=0;i<24;i++) + { + if (!i) root->child=objects[i]; + else prev->next=objects[i], objects[i]->prev=prev; + prev=objects[i]; + } + return root; +} + +and simply: Create_array_of_anything(objects,24); + +cJSON doesn't make any assumptions about what order you create things in. +You can attach the objects, as above, and later add children to each +of those objects. + +As soon as you call cJSON_Print, it renders the structure to text. + + + +The test.c code shows how to handle a bunch of typical cases. If you uncomment +the code, it'll load, parse and print a bunch of test files, also from json.org, +which are more complex than I'd care to try and stash into a const char array[]. + + +Enjoy cJSON! + + +- Dave Gamble, Aug 2009 diff --git a/src/external/cJSON/README.md b/src/external/cJSON/README.md new file mode 100644 index 000000000..01971360a --- /dev/null +++ b/src/external/cJSON/README.md @@ -0,0 +1,529 @@ +# cJSON + +Ultralightweight JSON parser in ANSI C. + +## Table of contents +* [License](#license) +* [Usage](#usage) + * [Welcome to cJSON](#welcome-to-cjson) + * [Building](#building) + * [Copying the source](#copying-the-source) + * [CMake](#cmake) + * [Makefile](#makefile) + * [Including cJSON](#including-cjson) + * [Data Structure](#data-structure) + * [Working with the data structure](#working-with-the-data-structure) + * [Basic types](#basic-types) + * [Arrays](#arrays) + * [Objects](#objects) + * [Parsing JSON](#parsing-json) + * [Printing JSON](#printing-json) + * [Example](#example) + * [Printing](#printing) + * [Parsing](#parsing) + * [Caveats](#caveats) + * [Zero Character](#zero-character) + * [Character Encoding](#character-encoding) + * [C Standard](#c-standard) + * [Floating Point Numbers](#floating-point-numbers) + * [Deep Nesting Of Arrays And Objects](#deep-nesting-of-arrays-and-objects) + * [Thread Safety](#thread-safety) + * [Case Sensitivity](#case-sensitivity) + * [Duplicate Object Members](#duplicate-object-members) + * [Enjoy cJSON!](#enjoy-cjson) + +## License + +MIT License + +> Copyright (c) 2009-2017 Dave Gamble and cJSON contributors +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + +## Usage + +### Welcome to cJSON. + +cJSON aims to be the dumbest possible parser that you can get your job done with. +It's a single file of C, and a single header file. + +JSON is described best here: http://www.json.org/ +It's like XML, but fat-free. You use it to move data around, store things, or just +generally represent your program's state. + +As a library, cJSON exists to take away as much legwork as it can, but not get in your way. +As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it +in one of two modes: Auto and Manual. Let's have a quick run-through. + +I lifted some JSON from this page: http://www.json.org/fatfree.html +That page inspired me to write cJSON, which is a parser that tries to share the same +philosophy as JSON itself. Simple, dumb, out of the way. + +### Building + +There are several ways to incorporate cJSON into your project. + +#### copying the source +Because the entire library is only one C file and one header file, you can just copy `cJSON.h` and `cJSON.c` to your projects source and start using it. + +cJSON is written in ANSI C (C89) in order to support as many platforms and compilers as possible. + +#### CMake +With CMake, cJSON supports a full blown build system. This way you get the most features. CMake with an equal or higher version than 2.8.5 is supported. With CMake it is recommended to do an out of tree build, meaning the compiled files are put in a directory separate from the source files. So in order to build cJSON with CMake on a Unix platform, make a `build` directory and run CMake inside it. + +``` +mkdir build +cd build +cmake .. +``` + +This will create a Makefile and a bunch of other files. You can then compile it: + +``` +make +``` + +And install it with `make install` if you want. By default it installs the headers `/usr/local/include/cjson` and the libraries to `/usr/local/lib`. It also installs files for pkg-config to make it easier to detect and use an existing installation of CMake. And it installs CMake config files, that can be used by other CMake based projects to discover the library. + +You can change the build process with a list of different options that you can pass to CMake. Turn them on with `On` and off with `Off`: +* `-DENABLE_CJSON_TEST=On`: Enable building the tests. (on by default) +* `-DENABLE_CJSON_UTILS=On`: Enable building cJSON_Utils. (off by default) +* `-DENABLE_TARGET_EXPORT=On`: Enable the export of CMake targets. Turn off if it makes problems. (on by default) +* `-DENABLE_CUSTOM_COMPILER_FLAGS=On`: Enable custom compiler flags (currently for Clang, GCC and MSVC). Turn off if it makes problems. (on by default) +* `-DENABLE_VALGRIND=On`: Run tests with [valgrind](http://valgrind.org). (off by default) +* `-DENABLE_SANITIZERS=On`: Compile cJSON with [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) and [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) enabled (if possible). (off by default) +* `-DENABLE_SAFE_STACK`: Enable the [SafeStack](https://clang.llvm.org/docs/SafeStack.html) instrumentation pass. Currently only works with the Clang compiler. (off by default) +* `-DBUILD_SHARED_LIBS=On`: Build the shared libraries. (on by default) +* `-DBUILD_SHARED_AND_STATIC_LIBS=On`: Build both shared and static libraries. (off by default) +* `-DCMAKE_INSTALL_PREFIX=/usr`: Set a prefix for the installation. +* `-DENABLE_LOCALES=On`: Enable the usage of localeconv method. ( on by default ) +* `-DCJSON_OVERRIDE_BUILD_SHARED_LIBS=On`: Enable overriding the value of `BUILD_SHARED_LIBS` with `-DCJSON_BUILD_SHARED_LIBS`. + +If you are packaging cJSON for a distribution of Linux, you would probably take these steps for example: +``` +mkdir build +cd build +cmake .. -DENABLE_CJSON_UTILS=On -DENABLE_CJSON_TEST=Off -DCMAKE_INSTALL_PREFIX=/usr +make +make DESTDIR=$pkgdir install +``` + +On Windows CMake is usually used to create a Visual Studio solution file by running it inside the Developer Command Prompt for Visual Studio, for exact steps follow the official documentation from CMake and Microsoft and use the online search engine of your choice. The descriptions of the the options above still generally apply, although not all of them work on Windows. + +#### Makefile +If you don't have CMake available, but still have GNU make. You can use the makefile to build cJSON: + +Run this command in the directory with the source code and it will automatically compile static and shared libraries and a little test program. + +``` +make all +``` + +If you want, you can install the compiled library to your system using `make install`. By default it will install the headers in `/usr/local/include/cjson` and the libraries in `/usr/local/lib`. But you can change this behavior by setting the `PREFIX` and `DESTDIR` variables: `make PREFIX=/usr DESTDIR=temp install`. + +### Including cJSON +If you installed it via CMake or the Makefile, you can include cJSON like this: + +```c +#include +``` + +### Data Structure + +cJSON represents JSON data using the `cJSON` struct data type: + +```c +/* The cJSON structure: */ +typedef struct cJSON +{ + struct cJSON *next; + struct cJSON *prev; + struct cJSON *child; + int type; + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + double valuedouble; + char *string; +} cJSON; +``` + +An item of this type represents a JSON value. The type is stored in `type` as a bit-flag (**this means that you cannot find out the type by just comparing the value of `type`**). + +To check the type of an item, use the corresponding `cJSON_Is...` function. It does a `NULL` check followed by a type check and returns a boolean value if the item is of this type. + +The type can be one of the following: +* `cJSON_Invalid` (check with `cJSON_IsInvalid`): Represents an invalid item that doesn't contain any value. You automatically have this type if you set the item to all zero bytes. +* `cJSON_False` (check with `cJSON_IsFalse`): Represents a `false` boolean value. You can also check for boolean values in general with `cJSON_IsBool`. +* `cJSON_True` (check with `cJSON_IsTrue`): Represents a `true` boolean value. You can also check for boolean values in general with `cJSON_IsBool`. +* `cJSON_NULL` (check with `cJSON_IsNull`): Represents a `null` value. +* `cJSON_Number` (check with `cJSON_IsNumber`): Represents a number value. The value is stored as a double in `valuedouble` and also in `valueint`. If the number is outside of the range of an integer, `INT_MAX` or `INT_MIN` are used for `valueint`. +* `cJSON_String` (check with `cJSON_IsString`): Represents a string value. It is stored in the form of a zero terminated string in `valuestring`. +* `cJSON_Array` (check with `cJSON_IsArray`): Represent an array value. This is implemented by pointing `child` to a linked list of `cJSON` items that represent the values in the array. The elements are linked together using `next` and `prev`, where the first element has `prev == NULL` and the last element `next == NULL`. +* `cJSON_Object` (check with `cJSON_IsObject`): Represents an object value. Objects are stored same way as an array, the only difference is that the items in the object store their keys in `string`. +* `cJSON_Raw` (check with `cJSON_IsRaw`): Represents any kind of JSON that is stored as a zero terminated array of characters in `valuestring`. This can be used, for example, to avoid printing the same static JSON over and over again to save performance. cJSON will never create this type when parsing. Also note that cJSON doesn't check if it is valid JSON. + +Additionally there are the following two flags: +* `cJSON_IsReference`: Specifies that the item that `child` points to and/or `valuestring` is not owned by this item, it is only a reference. So `cJSON_Delete` and other functions will only deallocate this item, not it's children/valuestring. +* `cJSON_StringIsConst`: This means that `string` points to a constant string. This means that `cJSON_Delete` and other functions will not try to deallocate `string`. + +### Working with the data structure + +For every value type there is a `cJSON_Create...` function that can be used to create an item of that type. +All of these will allocate a `cJSON` struct that can later be deleted with `cJSON_Delete`. +Note that you have to delete them at some point, otherwise you will get a memory leak. +**Important**: If you have added an item to an array or an object already, you **mustn't** delete it with `cJSON_Delete`. Adding it to an array or object transfers its ownership so that when that array or object is deleted, it gets deleted as well. + +#### Basic types +* **null** is created with `cJSON_CreateNull` +* **booleans** are created with `cJSON_CreateTrue`, `cJSON_CreateFalse` or `cJSON_CreateBool` +* **numbers** are created with `cJSON_CreateNumber`. This will set both `valuedouble` and `valueint`. If the number is outside of the range of an integer, `INT_MAX` or `INT_MIN` are used for `valueint` +* **strings** are created with `cJSON_CreateString` (copies the string) or with `cJSON_CreateStringReference` (directly points to the string. This means that `valuestring` won't be deleted by `cJSON_Delete` and you are responsible for it's lifetime, useful for constants) + +#### Arrays + +You can create an empty array with `cJSON_CreateArray`. `cJSON_CreateArrayReference` can be used to create an array that doesn't "own" its content, so its content doesn't get deleted by `cJSON_Delete`. + +To add items to an array, use `cJSON_AddItemToArray` to append items to the end. +Using `cJSON_AddItemReferenceToArray` an element can be added as a reference to another item, array or string. This means that `cJSON_Delete` will not delete that items `child` or `valuestring` properties, so no double frees are occuring if they are already used elsewhere. +To insert items in the middle, use `cJSON_InsertItemInArray`. It will insert an item at the given 0 based index and shift all the existing items to the right. + +If you want to take an item out of an array at a given index and continue using it, use `cJSON_DetachItemFromArray`, it will return the detached item, so be sure to assign it to a pointer, otherwise you will have a memory leak. + +Deleting items is done with `cJSON_DeleteItemFromArray`. It works like `cJSON_DetachItemFromArray`, but deletes the detached item via `cJSON_Delete`. + +You can also replace an item in an array in place. Either with `cJSON_ReplaceItemInArray` using an index or with `cJSON_ReplaceItemViaPointer` given a pointer to an element. `cJSON_ReplaceItemViaPointer` will return `0` if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place. + +To get the size of an array, use `cJSON_GetArraySize`. Use `cJSON_GetArrayItem` to get an element at a given index. + +Because an array is stored as a linked list, iterating it via index is inefficient (`O(n²)`), so you can iterate over an array using the `cJSON_ArrayForEach` macro in `O(n)` time complexity. + +#### Objects + +You can create an empty object with `cJSON_CreateObject`. `cJSON_CreateObjectReference` can be used to create an object that doesn't "own" its content, so its content doesn't get deleted by `cJSON_Delete`. + +To add items to an object, use `cJSON_AddItemToObject`. Use `cJSON_AddItemToObjectCS` to add an item to an object with a name that is a constant or reference (key of the item, `string` in the `cJSON` struct), so that it doesn't get freed by `cJSON_Delete`. +Using `cJSON_AddItemReferenceToArray` an element can be added as a reference to another object, array or string. This means that `cJSON_Delete` will not delete that items `child` or `valuestring` properties, so no double frees are occuring if they are already used elsewhere. + +If you want to take an item out of an object, use `cJSON_DetachItemFromObjectCaseSensitive`, it will return the detached item, so be sure to assign it to a pointer, otherwise you will have a memory leak. + +Deleting items is done with `cJSON_DeleteItemFromObjectCaseSensitive`. It works like `cJSON_DetachItemFromObjectCaseSensitive` followed by `cJSON_Delete`. + +You can also replace an item in an object in place. Either with `cJSON_ReplaceItemInObjectCaseSensitive` using a key or with `cJSON_ReplaceItemViaPointer` given a pointer to an element. `cJSON_ReplaceItemViaPointer` will return `0` if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place. + +To get the size of an object, you can use `cJSON_GetArraySize`, this works because internally objects are stored as arrays. + +If you want to access an item in an object, use `cJSON_GetObjectItemCaseSensitive`. + +To iterate over an object, you can use the `cJSON_ArrayForEach` macro the same way as for arrays. + +cJSON also provides convenient helper functions for quickly creating a new item and adding it to an object, like `cJSON_AddNullToObject`. They return a pointer to the new item or `NULL` if they failed. + +### Parsing JSON + +Given some JSON in a zero terminated string, you can parse it with `cJSON_Parse`. + +```c +cJSON *json = cJSON_Parse(string); +``` + +It will parse the JSON and allocate a tree of `cJSON` items that represents it. Once it returns, you are fully responsible for deallocating it after use with `cJSON_Delete`. + +The allocator used by `cJSON_Parse` is `malloc` and `free` by default but can be changed (globally) with `cJSON_InitHooks`. + +If an error occurs a pointer to the position of the error in the input string can be accessed using `cJSON_GetErrorPtr`. Note though that this can produce race conditions in multithreading scenarios, in that case it is better to use `cJSON_ParseWithOpts` with `return_parse_end`. +By default, characters in the input string that follow the parsed JSON will not be considered as an error. + +If you want more options, use `cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)`. +`return_parse_end` returns a pointer to the end of the JSON in the input string or the position that an error occurs at (thereby replacing `cJSON_GetErrorPtr` in a thread safe way). `require_null_terminated`, if set to `1` will make it an error if the input string contains data after the JSON. + +### Printing JSON + +Given a tree of `cJSON` items, you can print them as a string using `cJSON_Print`. + +```c +char *string = cJSON_Print(json); +``` + +It will allocate a string and print a JSON representation of the tree into it. Once it returns, you are fully responsible for deallocating it after use with your allocator. (usually `free`, depends on what has been set with `cJSON_InitHooks`). + +`cJSON_Print` will print with whitespace for formatting. If you want to print without formatting, use `cJSON_PrintUnformatted`. + +If you have a rough idea of how big your resulting string will be, you can use `cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)`. `fmt` is a boolean to turn formatting with whitespace on and off. `prebuffer` specifies the first buffer size to use for printing. `cJSON_Print` currently uses 256 bytes for it's first buffer size. Once printing runs out of space, a new buffer is allocated and the old gets copied over before printing is continued. + +These dynamic buffer allocations can be completely avoided by using `cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)`. It takes a buffer to a pointer to print to and it's length. If the length is reached, printing will fail and it returns `0`. In case of success, `1` is returned. Note that you should provide 5 bytes more than is actually needed, because cJSON is not 100% accurate in estimating if the provided memory is enough. + +### Example +In this example we want to build and parse the following JSON: + +```json +{ + "name": "Awesome 4K", + "resolutions": [ + { + "width": 1280, + "height": 720 + }, + { + "width": 1920, + "height": 1080 + }, + { + "width": 3840, + "height": 2160 + } + ] +} +``` + +#### Printing +Let's build the above JSON and print it to a string: +```c +//create a monitor with a list of supported resolutions +char* create_monitor(void) +{ + const unsigned int resolution_numbers[3][2] = { + {1280, 720}, + {1920, 1080}, + {3840, 2160} + }; + char *string = NULL; + cJSON *name = NULL; + cJSON *resolutions = NULL; + cJSON *resolution = NULL; + cJSON *width = NULL; + cJSON *height = NULL; + size_t index = 0; + + cJSON *monitor = cJSON_CreateObject(); + if (monitor == NULL) + { + goto end; + } + + name = cJSON_CreateString("Awesome 4K"); + if (name == NULL) + { + goto end; + } + /* after creation was successful, immediately add it to the monitor, + * thereby transfering ownership of the pointer to it */ + cJSON_AddItemToObject(monitor, "name", name); + + resolutions = cJSON_CreateArray(); + if (resolutions == NULL) + { + goto end; + } + cJSON_AddItemToObject(monitor, "resolutions", resolutions); + + for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index) + { + resolution = cJSON_CreateObject(); + if (resolution == NULL) + { + goto end; + } + cJSON_AddItemToArray(resolutions, resolution); + + width = cJSON_CreateNumber(resolution_numbers[index][0]); + if (width == NULL) + { + goto end; + } + cJSON_AddItemToObject(resolution, "width", width); + + height = cJSON_CreateNumber(resolution_numbers[index][1]); + if (height == NULL) + { + goto end; + } + cJSON_AddItemToObject(resolution, "height", height); + } + + string = cJSON_Print(monitor); + if (string == NULL) + { + fprintf(stderr, "Failed to print monitor.\n"); + } + +end: + cJSON_Delete(monitor); + return string; +} +``` + +Alternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier: +```c +char *create_monitor_with_helpers(void) +{ + const unsigned int resolution_numbers[3][2] = { + {1280, 720}, + {1920, 1080}, + {3840, 2160} + }; + char *string = NULL; + cJSON *resolutions = NULL; + size_t index = 0; + + cJSON *monitor = cJSON_CreateObject(); + + if (cJSON_AddStringToObject(monitor, "name", "Awesome 4K") == NULL) + { + goto end; + } + + resolutions = cJSON_AddArrayToObject(monitor, "resolutions"); + if (resolutions == NULL) + { + goto end; + } + + for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index) + { + cJSON *resolution = cJSON_CreateObject(); + + if (cJSON_AddNumberToObject(resolution, "width", resolution_numbers[index][0]) == NULL) + { + goto end; + } + + if(cJSON_AddNumberToObject(resolution, "height", resolution_numbers[index][1]) == NULL) + { + goto end; + } + + cJSON_AddItemToArray(resolutions, resolution); + } + + string = cJSON_Print(monitor); + if (string == NULL) { + fprintf(stderr, "Failed to print monitor.\n"); + } + +end: + cJSON_Delete(monitor); + return string; +} +``` + +#### Parsing +In this example we will parse a JSON in the above format and check if the monitor supports a Full HD resolution while printing some diagnostic output: + +```c +/* return 1 if the monitor supports full hd, 0 otherwise */ +int supports_full_hd(const char * const monitor) +{ + const cJSON *resolution = NULL; + const cJSON *resolutions = NULL; + const cJSON *name = NULL; + int status = 0; + cJSON *monitor_json = cJSON_Parse(monitor); + if (monitor_json == NULL) + { + const char *error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) + { + fprintf(stderr, "Error before: %s\n", error_ptr); + } + status = 0; + goto end; + } + + name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name"); + if (cJSON_IsString(name) && (name->valuestring != NULL)) + { + printf("Checking monitor \"%s\"\n", name->valuestring); + } + + resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions"); + cJSON_ArrayForEach(resolution, resolutions) + { + cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, "width"); + cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, "height"); + + if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height)) + { + status = 0; + goto end; + } + + if ((width->valuedouble == 1920) && (height->valuedouble == 1080)) + { + status = 1; + goto end; + } + } + +end: + cJSON_Delete(monitor_json); + return status; +} +``` + +Note that there are no NULL checks except for the result of `cJSON_Parse` because `cJSON_GetObjectItemCaseSensitive` checks for `NULL` inputs already, so a `NULL` value is just propagated and `cJSON_IsNumber` and `cJSON_IsString` return `0` if the input is `NULL`. + +### Caveats + +#### Zero Character + +cJSON doesn't support strings that contain the zero character `'\0'` or `\u0000`. This is impossible with the current API because strings are zero terminated. + +#### Character Encoding + +cJSON only supports UTF-8 encoded input. In most cases it doesn't reject invalid UTF-8 as input though, it just propagates it through as is. As long as the input doesn't contain invalid UTF-8, the output will always be valid UTF-8. + +#### C Standard + +cJSON is written in ANSI C (or C89, C90). If your compiler or C library doesn't follow this standard, correct behavior is not guaranteed. + +NOTE: ANSI C is not C++ therefore it shouldn't be compiled with a C++ compiler. You can compile it with a C compiler and link it with your C++ code however. Although compiling with a C++ compiler might work, correct behavior is not guaranteed. + +#### Floating Point Numbers + +cJSON does not officially support any `double` implementations other than IEEE754 double precision floating point numbers. It might still work with other implementations but bugs with these will be considered invalid. + +The maximum length of a floating point literal that cJSON supports is currently 63 characters. + +#### Deep Nesting Of Arrays And Objects + +cJSON doesn't support arrays and objects that are nested too deeply because this would result in a stack overflow. To prevent this cJSON limits the depth to `CJSON_NESTING_LIMIT` which is 1000 by default but can be changed at compile time. + +#### Thread Safety + +In general cJSON is **not thread safe**. + +However it is thread safe under the following conditions: +* `cJSON_GetErrorPtr` is never used (the `return_parse_end` parameter of `cJSON_ParseWithOpts` can be used instead) +* `cJSON_InitHooks` is only ever called before using cJSON in any threads. +* `setlocale` is never called before all calls to cJSON functions have returned. + +#### Case Sensitivity + +When cJSON was originally created, it didn't follow the JSON standard and didn't make a distinction between uppercase and lowercase letters. If you want the correct, standard compliant, behavior, you need to use the `CaseSensitive` functions where available. + +#### Duplicate Object Members + +cJSON supports parsing and printing JSON that contains objects that have multiple members with the same name. `cJSON_GetObjectItemCaseSensitive` however will always only return the first one. + +# Enjoy cJSON! + +- Dave Gamble (original author) +- Max Bruckner (current maintainer) +- and the other [cJSON contributors](CONTRIBUTORS.md) diff --git a/src/external/cJSON/cJSON.c b/src/external/cJSON/cJSON.c new file mode 100644 index 000000000..d20c676ed --- /dev/null +++ b/src/external/cJSON/cJSON.c @@ -0,0 +1,2932 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#define true ((cJSON_bool)1) +#define false ((cJSON_bool)0) + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) { + if (!cJSON_IsString(item)) { + return NULL; + } + + return item->valuestring; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 1) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(*allocate)(size_t size); + void (*deallocate)(void *pointer); + void *(*reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dillimport '...' is not static */ +static void *internal_malloc(size_t size) +{ + return malloc(size); +} +static void internal_free(void *pointer) +{ + free(pointer); +} +static void *internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + if (newbuffer) + { + memcpy(newbuffer, p->buffer, p->offset + 1); + } + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26]; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if ((d * 0) != 0) + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occured */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = strlen((const char*)value) + sizeof(""); + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +#define cjson_min(a, b) ((a < b) ? a : b) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + buffer->buffer = NULL; + if (printed == NULL) { + goto fail; + } + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((len < 0) || (buf == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buf; + p.length = (size_t)len; + p.offset = 0; + p.noalloc = true; + p.format = fmt; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + if (!output_buffer->noalloc) + { + output_buffer->hooks.deallocate(output_buffer->buffer); + } + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* faile to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL)) + { + return false; + } + + child = array->child; + + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + } + else + { + /* append to the end */ + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + if ((object == NULL) || (string == NULL) || (item == NULL)) + { + return false; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + if (constant_key) + { + item->string = (char*)cast_away_const(string); + item->type |= cJSON_StringIsConst; + } + else + { + char *key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (key == NULL) + { + return false; + } + + item->string = key; + item->type &= ~cJSON_StringIsConst; + } + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return; + } + + add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return; + } + + add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item->prev != NULL) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + add_item_to_array(array, newitem); + return; + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (parent->child == item) + { + parent->child = replacement; + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return; + } + + cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); + + return true; +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = b ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + unsigned char *into = (unsigned char*)json; + + if (json == NULL) + { + return; + } + + while (*json) + { + if (*json == ' ') + { + json++; + } + else if (*json == '\t') + { + /* Whitespace characters. */ + json++; + } + else if (*json == '\r') + { + json++; + } + else if (*json=='\n') + { + json++; + } + else if ((*json == '/') && (json[1] == '/')) + { + /* double-slash comments, to end of line. */ + while (*json && (*json != '\n')) + { + json++; + } + } + else if ((*json == '/') && (json[1] == '*')) + { + /* multiline comments. */ + while (*json && !((*json == '*') && (json[1] == '/'))) + { + json++; + } + json += 2; + } + else if (*json == '\"') + { + /* string literals, which are \" sensitive. */ + *into++ = (unsigned char)*json++; + while (*json && (*json != '\"')) + { + if (*json == '\\') + { + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + else + { + /* All other characters. */ + *into++ = (unsigned char)*json++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (a->valuedouble == b->valuedouble) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/src/external/cJSON/cJSON.h b/src/external/cJSON/cJSON.h new file mode 100644 index 000000000..52101e117 --- /dev/null +++ b/src/external/cJSON/cJSON.h @@ -0,0 +1,277 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 1 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type __stdcall +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall +#endif +#else /* !WIN32 */ +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check if the item is a string and return its valuestring */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/arrray that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + + +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/external/cJSON/test.c b/src/external/cJSON/test.c new file mode 100644 index 000000000..66154e04b --- /dev/null +++ b/src/external/cJSON/test.c @@ -0,0 +1,268 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include "cJSON.h" + +/* Used by some code below as an example datatype. */ +struct record +{ + const char *precision; + double lat; + double lon; + const char *address; + const char *city; + const char *state; + const char *zip; + const char *country; +}; + + +/* Create a bunch of objects as demonstration. */ +static int print_preallocated(cJSON *root) +{ + /* declarations */ + char *out = NULL; + char *buf = NULL; + char *buf_fail = NULL; + size_t len = 0; + size_t len_fail = 0; + + /* formatted print */ + out = cJSON_Print(root); + + /* create buffer to succeed */ + /* the extra 5 bytes are because of inaccuracies when reserving memory */ + len = strlen(out) + 5; + buf = (char*)malloc(len); + if (buf == NULL) + { + printf("Failed to allocate memory.\n"); + exit(1); + } + + /* create buffer to fail */ + len_fail = strlen(out); + buf_fail = (char*)malloc(len_fail); + if (buf_fail == NULL) + { + printf("Failed to allocate memory.\n"); + exit(1); + } + + /* Print to buffer */ + if (!cJSON_PrintPreallocated(root, buf, (int)len, 1)) { + printf("cJSON_PrintPreallocated failed!\n"); + if (strcmp(out, buf) != 0) { + printf("cJSON_PrintPreallocated not the same as cJSON_Print!\n"); + printf("cJSON_Print result:\n%s\n", out); + printf("cJSON_PrintPreallocated result:\n%s\n", buf); + } + free(out); + free(buf_fail); + free(buf); + return -1; + } + + /* success */ + printf("%s\n", buf); + + /* force it to fail */ + if (cJSON_PrintPreallocated(root, buf_fail, (int)len_fail, 1)) { + printf("cJSON_PrintPreallocated failed to show error with insufficient memory!\n"); + printf("cJSON_Print result:\n%s\n", out); + printf("cJSON_PrintPreallocated result:\n%s\n", buf_fail); + free(out); + free(buf_fail); + free(buf); + return -1; + } + + free(out); + free(buf_fail); + free(buf); + return 0; +} + +/* Create a bunch of objects as demonstration. */ +static void create_objects(void) +{ + /* declare a few. */ + cJSON *root = NULL; + cJSON *fmt = NULL; + cJSON *img = NULL; + cJSON *thm = NULL; + cJSON *fld = NULL; + int i = 0; + + /* Our "days of the week" array: */ + const char *strings[7] = + { + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + }; + /* Our matrix: */ + int numbers[3][3] = + { + {0, -1, 0}, + {1, 0, 0}, + {0 ,0, 1} + }; + /* Our "gallery" item: */ + int ids[4] = { 116, 943, 234, 38793 }; + /* Our array of "records": */ + struct record fields[2] = + { + { + "zip", + 37.7668, + -1.223959e+2, + "", + "SAN FRANCISCO", + "CA", + "94107", + "US" + }, + { + "zip", + 37.371991, + -1.22026e+2, + "", + "SUNNYVALE", + "CA", + "94085", + "US" + } + }; + volatile double zero = 0.0; + + /* Here we construct some JSON standards, from the JSON site. */ + + /* Our "Video" datatype: */ + root = cJSON_CreateObject(); + cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble")); + cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject()); + cJSON_AddStringToObject(fmt, "type", "rect"); + cJSON_AddNumberToObject(fmt, "width", 1920); + cJSON_AddNumberToObject(fmt, "height", 1080); + cJSON_AddFalseToObject (fmt, "interlace"); + cJSON_AddNumberToObject(fmt, "frame rate", 24); + + /* Print to text */ + if (print_preallocated(root) != 0) { + cJSON_Delete(root); + exit(EXIT_FAILURE); + } + cJSON_Delete(root); + + /* Our "days of the week" array: */ + root = cJSON_CreateStringArray(strings, 7); + + if (print_preallocated(root) != 0) { + cJSON_Delete(root); + exit(EXIT_FAILURE); + } + cJSON_Delete(root); + + /* Our matrix: */ + root = cJSON_CreateArray(); + for (i = 0; i < 3; i++) + { + cJSON_AddItemToArray(root, cJSON_CreateIntArray(numbers[i], 3)); + } + + /* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */ + + if (print_preallocated(root) != 0) { + cJSON_Delete(root); + exit(EXIT_FAILURE); + } + cJSON_Delete(root); + + /* Our "gallery" item: */ + root = cJSON_CreateObject(); + cJSON_AddItemToObject(root, "Image", img = cJSON_CreateObject()); + cJSON_AddNumberToObject(img, "Width", 800); + cJSON_AddNumberToObject(img, "Height", 600); + cJSON_AddStringToObject(img, "Title", "View from 15th Floor"); + cJSON_AddItemToObject(img, "Thumbnail", thm = cJSON_CreateObject()); + cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943"); + cJSON_AddNumberToObject(thm, "Height", 125); + cJSON_AddStringToObject(thm, "Width", "100"); + cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4)); + + if (print_preallocated(root) != 0) { + cJSON_Delete(root); + exit(EXIT_FAILURE); + } + cJSON_Delete(root); + + /* Our array of "records": */ + root = cJSON_CreateArray(); + for (i = 0; i < 2; i++) + { + cJSON_AddItemToArray(root, fld = cJSON_CreateObject()); + cJSON_AddStringToObject(fld, "precision", fields[i].precision); + cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat); + cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon); + cJSON_AddStringToObject(fld, "Address", fields[i].address); + cJSON_AddStringToObject(fld, "City", fields[i].city); + cJSON_AddStringToObject(fld, "State", fields[i].state); + cJSON_AddStringToObject(fld, "Zip", fields[i].zip); + cJSON_AddStringToObject(fld, "Country", fields[i].country); + } + + /* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */ + + if (print_preallocated(root) != 0) { + cJSON_Delete(root); + exit(EXIT_FAILURE); + } + cJSON_Delete(root); + + root = cJSON_CreateObject(); + cJSON_AddNumberToObject(root, "number", 1.0 / zero); + + if (print_preallocated(root) != 0) { + cJSON_Delete(root); + exit(EXIT_FAILURE); + } + cJSON_Delete(root); +} + +int main(void) +{ + /* print the version */ + printf("Version: %s\n", cJSON_Version()); + + /* Now some samplecode for building objects concisely: */ + create_objects(); + + return 0; +} diff --git a/src/external/cJSON/tests/test1 b/src/external/cJSON/tests/test1 new file mode 100644 index 000000000..eacfbf5e6 --- /dev/null +++ b/src/external/cJSON/tests/test1 @@ -0,0 +1,22 @@ +{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +} diff --git a/src/external/cJSON/tests/test2 b/src/external/cJSON/tests/test2 new file mode 100644 index 000000000..5600991a4 --- /dev/null +++ b/src/external/cJSON/tests/test2 @@ -0,0 +1,11 @@ +{"menu": { + "id": "file", + "value": "File", + "popup": { + "menuitem": [ + {"value": "New", "onclick": "CreateNewDoc()"}, + {"value": "Open", "onclick": "OpenDoc()"}, + {"value": "Close", "onclick": "CloseDoc()"} + ] + } +}} diff --git a/src/external/cJSON/tests/test3 b/src/external/cJSON/tests/test3 new file mode 100644 index 000000000..5662b3774 --- /dev/null +++ b/src/external/cJSON/tests/test3 @@ -0,0 +1,26 @@ +{"widget": { + "debug": "on", + "window": { + "title": "Sample Konfabulator Widget", + "name": "main_window", + "width": 500, + "height": 500 + }, + "image": { + "src": "Images/Sun.png", + "name": "sun1", + "hOffset": 250, + "vOffset": 250, + "alignment": "center" + }, + "text": { + "data": "Click Here", + "size": 36, + "style": "bold", + "name": "text1", + "hOffset": 250, + "vOffset": 100, + "alignment": "center", + "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" + } +}} \ No newline at end of file diff --git a/src/external/cJSON/tests/test4 b/src/external/cJSON/tests/test4 new file mode 100644 index 000000000..d540b57f0 --- /dev/null +++ b/src/external/cJSON/tests/test4 @@ -0,0 +1,88 @@ +{"web-app": { + "servlet": [ + { + "servlet-name": "cofaxCDS", + "servlet-class": "org.cofax.cds.CDSServlet", + "init-param": { + "configGlossary:installationAt": "Philadelphia, PA", + "configGlossary:adminEmail": "ksm@pobox.com", + "configGlossary:poweredBy": "Cofax", + "configGlossary:poweredByIcon": "/images/cofax.gif", + "configGlossary:staticPath": "/content/static", + "templateProcessorClass": "org.cofax.WysiwygTemplate", + "templateLoaderClass": "org.cofax.FilesTemplateLoader", + "templatePath": "templates", + "templateOverridePath": "", + "defaultListTemplate": "listTemplate.htm", + "defaultFileTemplate": "articleTemplate.htm", + "useJSP": false, + "jspListTemplate": "listTemplate.jsp", + "jspFileTemplate": "articleTemplate.jsp", + "cachePackageTagsTrack": 200, + "cachePackageTagsStore": 200, + "cachePackageTagsRefresh": 60, + "cacheTemplatesTrack": 100, + "cacheTemplatesStore": 50, + "cacheTemplatesRefresh": 15, + "cachePagesTrack": 200, + "cachePagesStore": 100, + "cachePagesRefresh": 10, + "cachePagesDirtyRead": 10, + "searchEngineListTemplate": "forSearchEnginesList.htm", + "searchEngineFileTemplate": "forSearchEngines.htm", + "searchEngineRobotsDb": "WEB-INF/robots.db", + "useDataStore": true, + "dataStoreClass": "org.cofax.SqlDataStore", + "redirectionClass": "org.cofax.SqlRedirection", + "dataStoreName": "cofax", + "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", + "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", + "dataStoreUser": "sa", + "dataStorePassword": "dataStoreTestQuery", + "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", + "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", + "dataStoreInitConns": 10, + "dataStoreMaxConns": 100, + "dataStoreConnUsageLimit": 100, + "dataStoreLogLevel": "debug", + "maxUrlLength": 500}}, + { + "servlet-name": "cofaxEmail", + "servlet-class": "org.cofax.cds.EmailServlet", + "init-param": { + "mailHost": "mail1", + "mailHostOverride": "mail2"}}, + { + "servlet-name": "cofaxAdmin", + "servlet-class": "org.cofax.cds.AdminServlet"}, + + { + "servlet-name": "fileServlet", + "servlet-class": "org.cofax.cds.FileServlet"}, + { + "servlet-name": "cofaxTools", + "servlet-class": "org.cofax.cms.CofaxToolsServlet", + "init-param": { + "templatePath": "toolstemplates/", + "log": 1, + "logLocation": "/usr/local/tomcat/logs/CofaxTools.log", + "logMaxSize": "", + "dataLog": 1, + "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", + "dataLogMaxSize": "", + "removePageCache": "/content/admin/remove?cache=pages&id=", + "removeTemplateCache": "/content/admin/remove?cache=templates&id=", + "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", + "lookInContext": 1, + "adminGroupID": 4, + "betaServer": true}}], + "servlet-mapping": { + "cofaxCDS": "/", + "cofaxEmail": "/cofaxutil/aemail/*", + "cofaxAdmin": "/admin/*", + "fileServlet": "/static/*", + "cofaxTools": "/tools/*"}, + + "taglib": { + "taglib-uri": "cofax.tld", + "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} \ No newline at end of file diff --git a/src/external/cJSON/tests/test5 b/src/external/cJSON/tests/test5 new file mode 100644 index 000000000..49980ca25 --- /dev/null +++ b/src/external/cJSON/tests/test5 @@ -0,0 +1,27 @@ +{"menu": { + "header": "SVG Viewer", + "items": [ + {"id": "Open"}, + {"id": "OpenNew", "label": "Open New"}, + null, + {"id": "ZoomIn", "label": "Zoom In"}, + {"id": "ZoomOut", "label": "Zoom Out"}, + {"id": "OriginalView", "label": "Original View"}, + null, + {"id": "Quality"}, + {"id": "Pause"}, + {"id": "Mute"}, + null, + {"id": "Find", "label": "Find..."}, + {"id": "FindAgain", "label": "Find Again"}, + {"id": "Copy"}, + {"id": "CopyAgain", "label": "Copy Again"}, + {"id": "CopySVG", "label": "Copy SVG"}, + {"id": "ViewSVG", "label": "View SVG"}, + {"id": "ViewSource", "label": "View Source"}, + {"id": "SaveAs", "label": "Save As"}, + null, + {"id": "Help"}, + {"id": "About", "label": "About Adobe CVG Viewer..."} + ] +}} diff --git a/src/external/compat/aix/sys/queue.h b/src/external/compat/aix/sys/queue.h new file mode 100644 index 000000000..c387bdcf5 --- /dev/null +++ b/src/external/compat/aix/sys/queue.h @@ -0,0 +1,488 @@ +/* $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef SYS_QUEUE_H__ +#define SYS_QUEUE_H__ + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#ifndef _WIN32 +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} +#endif + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List access methods + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \ + for((var) = LIST_FIRST(head); \ + (var)!= LIST_END(head); \ + (var) = LIST_NEXT(var, field)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \ + LIST_FIRST(head) = LIST_END(head); \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ + (elm2)->field.le_next->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ + if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * tail queue access methods + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue access methods + */ +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_END(head) ((void *)(head)) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) +#define CIRCLEQ_EMPTY(head) \ + (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = CIRCLEQ_FIRST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_NEXT(var, field)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = CIRCLEQ_LAST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_PREV(var, field)) + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = CIRCLEQ_END(head); \ + (head)->cqh_last = CIRCLEQ_END(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = CIRCLEQ_END(head); \ + if ((head)->cqh_last == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = CIRCLEQ_END(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ + CIRCLEQ_END(head)) \ + (head).cqh_last = (elm2); \ + else \ + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ + CIRCLEQ_END(head)) \ + (head).cqh_first = (elm2); \ + else \ + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ +} while (0) + +#endif /* !SYS_QUEUE_H__ */ diff --git a/src/external/compat/imsg-buffer.c b/src/external/compat/imsg-buffer.c new file mode 100644 index 000000000..b4bc24bb3 --- /dev/null +++ b/src/external/compat/imsg-buffer.c @@ -0,0 +1,319 @@ +/* $OpenBSD: imsg-buffer.c,v 1.3 2013/11/13 20:40:24 benno Exp $ */ + +/* + * Copyright (c) 2003, 2004 Henning Brauer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENBSD + +#include "includes.h" + +#include +#include +#include +#include + +#include +#include +#include +#ifndef HAVE_EXPLICIT_BZERO +#include +#endif +#include + +#ifdef SOLARIS +#include +#endif + +#include "imsg.h" + +int ibuf_realloc(struct ibuf *, size_t); +void ibuf_enqueue(struct msgbuf *, struct ibuf *); +void ibuf_dequeue(struct msgbuf *, struct ibuf *); + +struct ibuf * +ibuf_open(size_t len) +{ + struct ibuf *buf; + + if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) + return (NULL); + if ((buf->buf = malloc(len)) == NULL) { + free(buf); + return (NULL); + } + buf->size = buf->max = len; + buf->fd = -1; + + return (buf); +} + +struct ibuf * +ibuf_dynamic(size_t len, size_t max) +{ + struct ibuf *buf; + + if (max < len) + return (NULL); + + if ((buf = ibuf_open(len)) == NULL) + return (NULL); + + if (max > 0) + buf->max = max; + + return (buf); +} + +int +ibuf_realloc(struct ibuf *buf, size_t len) +{ + u_char *b; + + /* on static buffers max is eq size and so the following fails */ + if (buf->wpos + len > buf->max) { + errno = ENOMEM; + return (-1); + } + + b = realloc(buf->buf, buf->wpos + len); + if (b == NULL) + return (-1); + buf->buf = b; + buf->size = buf->wpos + len; + + return (0); +} + +int +ibuf_add(struct ibuf *buf, const void *data, size_t len) +{ + if (buf->wpos + len > buf->size) + if (ibuf_realloc(buf, len) == -1) + return (-1); + + memcpy(buf->buf + buf->wpos, data, len); + buf->wpos += len; + return (0); +} + +void * +ibuf_reserve(struct ibuf *buf, size_t len) +{ + void *b; + + if (buf->wpos + len > buf->size) + if (ibuf_realloc(buf, len) == -1) + return (NULL); + + b = buf->buf + buf->wpos; + buf->wpos += len; + return (b); +} + +void * +ibuf_seek(struct ibuf *buf, size_t pos, size_t len) +{ + /* only allowed to seek in already written parts */ + if (pos + len > buf->wpos) + return (NULL); + + return (buf->buf + pos); +} + +size_t +ibuf_size(struct ibuf *buf) +{ + return (buf->wpos); +} + +size_t +ibuf_left(struct ibuf *buf) +{ + return (buf->max - buf->wpos); +} + +void +ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) +{ + ibuf_enqueue(msgbuf, buf); +} + +int +ibuf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct ibuf *buf; + unsigned int i = 0; + ssize_t n; + + bzero(&iov, sizeof(iov)); + TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; + i++; + } + +again: + if ((n = writev(msgbuf->fd, iov, i)) == -1) { + if (errno == EINTR) + goto again; + if (errno == ENOBUFS) + errno = EAGAIN; + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (0); + } + + msgbuf_drain(msgbuf, n); + + return (1); +} + +void +ibuf_free(struct ibuf *buf) +{ + free(buf->buf); + free(buf); +} + +void +msgbuf_init(struct msgbuf *msgbuf) +{ + msgbuf->queued = 0; + msgbuf->fd = -1; + TAILQ_INIT(&msgbuf->bufs); +} + +void +msgbuf_drain(struct msgbuf *msgbuf, size_t n) +{ + struct ibuf *buf, *next; + + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; + buf = next) { + next = TAILQ_NEXT(buf, entry); + if (buf->rpos + n >= buf->wpos) { + n -= buf->wpos - buf->rpos; + ibuf_dequeue(msgbuf, buf); + } else { + buf->rpos += n; + n = 0; + } + } +} + +void +msgbuf_clear(struct msgbuf *msgbuf) +{ + struct ibuf *buf; + + while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) + ibuf_dequeue(msgbuf, buf); +} + +int +msgbuf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct ibuf *buf; + unsigned int i = 0; + ssize_t n; + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + + bzero(&iov, sizeof(iov)); + bzero(&msg, sizeof(msg)); + TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { + if (i >= IOV_MAX) + break; + iov[i].iov_base = buf->buf + buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; + i++; + if (buf->fd != -1) + break; + } + + msg.msg_iov = iov; + msg.msg_iovlen = i; + + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + +again: + if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { + if (errno == EINTR) + goto again; + if (errno == ENOBUFS) + errno = EAGAIN; + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (0); + } + + /* + * assumption: fd got sent if sendmsg sent anything + * this works because fds are passed one at a time + */ + if (buf != NULL && buf->fd != -1) { + close(buf->fd); + buf->fd = -1; + } + + msgbuf_drain(msgbuf, n); + + return (1); +} + +void +ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) +{ + TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); + msgbuf->queued++; +} + +void +ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) +{ + TAILQ_REMOVE(&msgbuf->bufs, buf, entry); + + if (buf->fd != -1) + close(buf->fd); + + msgbuf->queued--; + ibuf_free(buf); +} + +#endif //OPENBSD + diff --git a/src/external/compat/imsg.c b/src/external/compat/imsg.c new file mode 100644 index 000000000..d6ff0f596 --- /dev/null +++ b/src/external/compat/imsg.c @@ -0,0 +1,334 @@ +/* $OpenBSD: imsg.c,v 1.5 2013/12/26 17:32:33 eric Exp $ */ + +/* + * Copyright (c) 2003, 2004 Henning Brauer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENBSD + +#include "includes.h" + +#include +#include +#include +#include + +#include +#include +#include +#ifndef HAVE_EXPLICIT_BZERO +#include +#endif +#include + +#include "imsg.h" + +int imsg_fd_overhead = 0; + +int imsg_get_fd(struct imsgbuf *); + +int +available_fds(unsigned int n) +{ + unsigned int i; + int ret, fds[256]; + + if (n > (sizeof(fds)/sizeof(fds[0]))) + return (1); + + ret = 0; + for (i = 0; i < n; i++) { + fds[i] = -1; + if ((fds[i] = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + ret = 1; + break; + } + } + + for (i = 0; i < n && fds[i] >= 0; i++) + close(fds[i]); + + return (ret); +} + +void +imsg_init(struct imsgbuf *ibuf, int fd) +{ + msgbuf_init(&ibuf->w); + bzero(&ibuf->r, sizeof(ibuf->r)); + ibuf->fd = fd; + ibuf->w.fd = fd; + ibuf->pid = getpid(); + TAILQ_INIT(&ibuf->fds); +} + +ssize_t +imsg_read(struct imsgbuf *ibuf) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int) * 1)]; + } cmsgbuf; + struct iovec iov; + ssize_t n = -1; + int fd; + struct imsg_fd *ifd; + + bzero(&msg, sizeof(msg)); + + iov.iov_base = ibuf->r.buf + ibuf->r.wpos; + iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + + if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) + return (-1); + +again: + if (available_fds(imsg_fd_overhead + + (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))) { + errno = EAGAIN; + free(ifd); + return (-1); + } + + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { + if (errno == EMSGSIZE) + goto fail; + if (errno != EINTR && errno != EAGAIN) + goto fail; + goto again; + } + + ibuf->r.wpos += n; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + int i; + int j; + + /* + * We only accept one file descriptor. Due to C + * padding rules, our control buffer might contain + * more than one fd, and we must close them. + */ + j = ((char *)cmsg + cmsg->cmsg_len - + (char *)CMSG_DATA(cmsg)) / sizeof(int); + for (i = 0; i < j; i++) { + fd = ((int *)CMSG_DATA(cmsg))[i]; + if (ifd != NULL) { + ifd->fd = fd; + TAILQ_INSERT_TAIL(&ibuf->fds, ifd, + entry); + ifd = NULL; + } else + close(fd); + } + } + /* we do not handle other ctl data level */ + } + +fail: + if (ifd) + free(ifd); + return (n); +} + +ssize_t +imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) +{ + size_t av, left, datalen; + + av = ibuf->r.wpos; + + if (IMSG_HEADER_SIZE > av) + return (0); + + memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); + if (imsg->hdr.len < IMSG_HEADER_SIZE || + imsg->hdr.len > MAX_IMSGSIZE) { + errno = ERANGE; + return (-1); + } + if (imsg->hdr.len > av) + return (0); + datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; + if ((imsg->data = malloc(datalen)) == NULL) + return (-1); + + if (imsg->hdr.flags & IMSGF_HASFD) + imsg->fd = imsg_get_fd(ibuf); + else + imsg->fd = -1; + + memcpy(imsg->data, ibuf->r.rptr, datalen); + + if (imsg->hdr.len < av) { + left = av - imsg->hdr.len; + memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left); + ibuf->r.wpos = left; + } else + ibuf->r.wpos = 0; + + return (datalen + IMSG_HEADER_SIZE); +} + +int +imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, + pid_t pid, int fd, const void *data, uint16_t datalen) +{ + struct ibuf *wbuf; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) + return (-1); + + if (imsg_add(wbuf, data, datalen) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +int +imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, + pid_t pid, int fd, const struct iovec *iov, int iovcnt) +{ + struct ibuf *wbuf; + int i, datalen = 0; + + for (i = 0; i < iovcnt; i++) + datalen += iov[i].iov_len; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) + return (-1); + + for (i = 0; i < iovcnt; i++) + if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +/* ARGSUSED */ +struct ibuf * +imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, + pid_t pid, uint16_t datalen) +{ + struct ibuf *wbuf; + struct imsg_hdr hdr; + + datalen += IMSG_HEADER_SIZE; + if (datalen > MAX_IMSGSIZE) { + errno = ERANGE; + return (NULL); + } + + hdr.type = type; + hdr.flags = 0; + hdr.peerid = peerid; + if ((hdr.pid = pid) == 0) + hdr.pid = ibuf->pid; + if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { + return (NULL); + } + if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) + return (NULL); + + return (wbuf); +} + +int +imsg_add(struct ibuf *msg, const void *data, uint16_t datalen) +{ + if (datalen) + if (ibuf_add(msg, data, datalen) == -1) { + ibuf_free(msg); + return (-1); + } + return (datalen); +} + +void +imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) +{ + struct imsg_hdr *hdr; + + hdr = (struct imsg_hdr *)msg->buf; + + hdr->flags &= ~IMSGF_HASFD; + if (msg->fd != -1) + hdr->flags |= IMSGF_HASFD; + + hdr->len = (uint16_t)msg->wpos; + + ibuf_close(&ibuf->w, msg); +} + +void +imsg_free(struct imsg *imsg) +{ + free(imsg->data); +} + +int +imsg_get_fd(struct imsgbuf *ibuf) +{ + int fd; + struct imsg_fd *ifd; + + if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + return (-1); + + fd = ifd->fd; + TAILQ_REMOVE(&ibuf->fds, ifd, entry); + free(ifd); + + return (fd); +} + +int +imsg_flush(struct imsgbuf *ibuf) +{ + while (ibuf->w.queued) + if (msgbuf_write(&ibuf->w) <= 0) + return (-1); + return (0); +} + +void +imsg_clear(struct imsgbuf *ibuf) +{ + int fd; + + msgbuf_clear(&ibuf->w); + while ((fd = imsg_get_fd(ibuf)) != -1) + close(fd); +} +#endif //OPENBSD + diff --git a/src/external/compat/imsg.h b/src/external/compat/imsg.h new file mode 100644 index 000000000..08725a58f --- /dev/null +++ b/src/external/compat/imsg.h @@ -0,0 +1,121 @@ +/* $OpenBSD: imsg.h,v 1.3 2013/12/26 17:32:33 eric Exp $ */ + +/* + * Copyright (c) 2006, 2007 Pierre-Yves Ritschard + * Copyright (c) 2006, 2007, 2008 Reyk Floeter + * Copyright (c) 2003, 2004 Henning Brauer + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENBSD + +#ifndef _IMSG_H_ +#define _IMSG_H_ + +#define IBUF_READ_SIZE 65535 +#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) +#define MAX_IMSGSIZE 16384 + +#include + +//#include "defines.h" + +struct ibuf { + TAILQ_ENTRY(ibuf) entry; + u_char *buf; + size_t size; + size_t max; + size_t wpos; + size_t rpos; + int fd; +}; + +struct msgbuf { + TAILQ_HEAD(, ibuf) bufs; + uint32_t queued; + int fd; +}; + +struct ibuf_read { + u_char buf[IBUF_READ_SIZE]; + u_char *rptr; + size_t wpos; +}; + +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + +struct imsgbuf { + TAILQ_HEAD(, imsg_fd) fds; + struct ibuf_read r; + struct msgbuf w; + int fd; + pid_t pid; +}; + +#define IMSGF_HASFD 1 + +struct imsg_hdr { + uint32_t type; + uint16_t len; + uint16_t flags; + uint32_t peerid; + uint32_t pid; +}; + +struct imsg { + struct imsg_hdr hdr; + int fd; + void *data; +}; + + +/* buffer.c */ +struct ibuf *ibuf_open(size_t); +struct ibuf *ibuf_dynamic(size_t, size_t); +int ibuf_add(struct ibuf *, const void *, size_t); +void *ibuf_reserve(struct ibuf *, size_t); +void *ibuf_seek(struct ibuf *, size_t, size_t); +size_t ibuf_size(struct ibuf *); +size_t ibuf_left(struct ibuf *); +void ibuf_close(struct msgbuf *, struct ibuf *); +int ibuf_write(struct msgbuf *); +void ibuf_free(struct ibuf *); +void msgbuf_init(struct msgbuf *); +void msgbuf_clear(struct msgbuf *); +int msgbuf_write(struct msgbuf *); +void msgbuf_drain(struct msgbuf *, size_t); + +/* imsg.c */ +int available_fds(unsigned int); +void imsg_init(struct imsgbuf *, int); +ssize_t imsg_read(struct imsgbuf *); +ssize_t imsg_get(struct imsgbuf *, struct imsg *); +int imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, + int, const void *, uint16_t); +int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, + int, const struct iovec *, int); +struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, + uint16_t); +int imsg_add(struct ibuf *, const void *, uint16_t); +void imsg_close(struct imsgbuf *, struct ibuf *); +void imsg_free(struct imsg *); +int imsg_flush(struct imsgbuf *); +void imsg_clear(struct imsgbuf *); + +#endif +#endif //OPENBSD + diff --git a/src/external/compat/includes.h b/src/external/compat/includes.h new file mode 100644 index 000000000..6b3c0c90f --- /dev/null +++ b/src/external/compat/includes.h @@ -0,0 +1,75 @@ +/* $OpenBSD: includes.h,v 1.54 2006/07/22 20:48:23 stevesk Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * This file includes most of the needed system headers. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef OPENBSD + +#ifndef INCLUDES_H +#define INCLUDES_H + +//#include "config.h" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* activate extra prototypes for glibc */ +#endif + +#include +#include /* For CMSG_* */ + +#ifdef HAVE_LIMITS_H +# include /* For PATH_MAX */ +#endif +#ifdef HAVE_BSTRING_H +# include +#endif + +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_MAILLOCK_H +# include /* For _PATH_MAILDIR */ +#endif +#ifdef HAVE_PATHS_H +# include +#endif + +#ifdef HAVE_RPC_TYPES_H +# include /* For INADDR_LOOPBACK */ +#endif +#ifdef USE_PAM +#if defined(HAVE_SECURITY_PAM_APPL_H) +# include +#elif defined (HAVE_PAM_PAM_APPL_H) +# include +#endif +#endif +#include + +/* chl */ +#ifdef HAVE_NETDB_H +# include +#endif +/* end of chl*/ + +#include /* For OPENSSL_VERSION_NUMBER */ + +//#include "defines.h" + +//#include "openbsd-compat.h" + +//#include "entropy.h" + +#endif /* INCLUDES_H */ +#endif //OPENBSD + diff --git a/src/external/compat/setproctitle.c b/src/external/compat/setproctitle.c new file mode 100644 index 000000000..3441c5e74 --- /dev/null +++ b/src/external/compat/setproctitle.c @@ -0,0 +1,179 @@ +/* Based on conf.c from UCB sendmail 8.8.8 */ + +/* + * Copyright 2003 Damien Miller + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef OPENBSD + +#include "includes.h" + +#ifndef HAVE_SETPROCTITLE + +#include +#include +#include +#include +#ifdef HAVE_SYS_PSTAT_H +#include +#endif +#include + +#if defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) +#include +#else +#include "bsd-vis.h" +#endif + +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ +#define SPT_REUSEARGV 2 /* cover argv with title information */ + +#ifndef SPT_TYPE +# define SPT_TYPE SPT_NONE +#endif + +#ifndef SPT_PADCHAR +# define SPT_PADCHAR '\0' +#endif + +#if SPT_TYPE == SPT_REUSEARGV +static char *argv_start = NULL; +static size_t argv_env_len = 0; +#endif + +#endif /* HAVE_SETPROCTITLE */ + +void +compat_init_setproctitle(int argc, char *argv[]) +{ +#if !defined(HAVE_SETPROCTITLE) && \ + defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV + extern char **environ; + char *lastargv = NULL; + char **envp = environ; + int i; + + /* + * NB: This assumes that argv has already been copied out of the + * way. This is true for sshd, but may not be true for other + * programs. Beware. + */ + + if (argc == 0 || argv[0] == NULL) + return; + + /* Fail if we can't allocate room for the new environment */ + for (i = 0; envp[i] != NULL; i++) + ; + if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { + environ = envp; /* put it back */ + return; + } + + /* + * Find the last argv string or environment variable within + * our process memory area. + */ + for (i = 0; i < argc; i++) { + if (lastargv == NULL || lastargv + 1 == argv[i]) + lastargv = argv[i] + strlen(argv[i]); + } + for (i = 0; envp[i] != NULL; i++) { + if (lastargv + 1 == envp[i]) + lastargv = envp[i] + strlen(envp[i]); + } + + argv[1] = NULL; + argv_start = argv[0]; + argv_env_len = lastargv - argv[0] - 1; + + /* + * Copy environment + * XXX - will truncate env on strdup fail + */ + for (i = 0; envp[i] != NULL; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; +#endif /* SPT_REUSEARGV */ +} + +#ifndef HAVE_SETPROCTITLE +void +setproctitle(const char *fmt, ...) +{ +#if SPT_TYPE != SPT_NONE + va_list ap; + char buf[1024], ptitle[1024]; + size_t len; + int r; + extern char *__progname; +#if SPT_TYPE == SPT_PSTAT + union pstun pst; +#endif + +#if SPT_TYPE == SPT_REUSEARGV + if (argv_env_len <= 0) + return; +#endif + + strlcpy(buf, __progname, sizeof(buf)); + + r = -1; + va_start(ap, fmt); + if (fmt != NULL) { + len = strlcat(buf, ": ", sizeof(buf)); + if (len < sizeof(buf)) + r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); + } + va_end(ap); + if (r == -1 || (size_t)r >= sizeof(buf) - len) + return; + strnvis(ptitle, buf, sizeof(ptitle), + VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); + +#if SPT_TYPE == SPT_PSTAT + pst.pst_command = ptitle; + pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); +#elif SPT_TYPE == SPT_REUSEARGV +/* debug("setproctitle: copy \"%s\" into len %d", + buf, argv_env_len); */ + len = strlcpy(argv_start, ptitle, argv_env_len); + for(; len < argv_env_len; len++) + argv_start[len] = SPT_PADCHAR; +#endif + +#endif /* SPT_NONE */ +} + +#endif /* HAVE_SETPROCTITLE */ + +#endif //OPENBSD + diff --git a/src/external/compat/strlcat.c b/src/external/compat/strlcat.c new file mode 100644 index 000000000..e064c2950 --- /dev/null +++ b/src/external/compat/strlcat.c @@ -0,0 +1,66 @@ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */ + +#ifndef OPENBSD + +#include "includes.h" +#ifndef HAVE_STRLCAT + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ +#endif // OPENBSD + diff --git a/src/external/compat/strlcpy.c b/src/external/compat/strlcpy.c new file mode 100644 index 000000000..8725550ba --- /dev/null +++ b/src/external/compat/strlcpy.c @@ -0,0 +1,63 @@ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */ + +#ifndef OPENBSD + +#include "includes.h" +#ifndef HAVE_STRLCPY + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCPY */ + +#endif //OPENBSD + diff --git a/src/external/lua b/src/external/lua new file mode 100644 index 000000000..3a6d5f42f --- /dev/null +++ b/src/external/lua @@ -0,0 +1 @@ +lua-5.2.3 \ No newline at end of file diff --git a/src/external/lua-5.2.3/Makefile b/src/external/lua-5.2.3/Makefile new file mode 100644 index 000000000..d2c7db4a2 --- /dev/null +++ b/src/external/lua-5.2.3/Makefile @@ -0,0 +1,114 @@ +# Makefile for installing Lua +# See doc/readme.html for installation and customization instructions. + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +# Where to install. The installation starts in the src and doc directories, +# so take care if INSTALL_TOP is not an absolute path. See the local target. +# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with +# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. +INSTALL_TOP= /usr/local +INSTALL_BIN= $(INSTALL_TOP)/bin +INSTALL_INC= $(INSTALL_TOP)/include +INSTALL_LIB= $(INSTALL_TOP)/lib +INSTALL_MAN= $(INSTALL_TOP)/man/man1 +INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V +INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V + +# How to install. If your install program does not support "-p", then +# you may have to run ranlib on the installed liblua.a. +INSTALL= install -p +INSTALL_EXEC= $(INSTALL) -m 0755 +INSTALL_DATA= $(INSTALL) -m 0644 +# +# If you don't have "install" you can use "cp" instead. +# INSTALL= cp -p +# INSTALL_EXEC= $(INSTALL) +# INSTALL_DATA= $(INSTALL) + +# Other utilities. +MKDIR= mkdir -p +RM= rm -f + +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= + +# Convenience platforms targets. +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +# What to install. +TO_BIN= lua luac +TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp +TO_LIB= liblua.a +TO_MAN= lua.1 luac.1 + +# Lua version and release. +V= 5.2 +R= $V.3 + +# Targets start here. +all: $(PLAT) + +$(PLATS) clean: + cd src && $(MAKE) $@ + +test: dummy + src/lua -v + +install: dummy + cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) + cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) + cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) + cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) + cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) + +uninstall: + cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN) + cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC) + cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB) + cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN) + +local: + $(MAKE) install INSTALL_TOP=../install + +none: + @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" + @echo " $(PLATS)" + @echo "See doc/readme.html for complete instructions." + +# make may get confused with test/ and install/ +dummy: + +# echo config parameters +echo: + @cd src && $(MAKE) -s echo + @echo "PLAT= $(PLAT)" + @echo "V= $V" + @echo "R= $R" + @echo "TO_BIN= $(TO_BIN)" + @echo "TO_INC= $(TO_INC)" + @echo "TO_LIB= $(TO_LIB)" + @echo "TO_MAN= $(TO_MAN)" + @echo "INSTALL_TOP= $(INSTALL_TOP)" + @echo "INSTALL_BIN= $(INSTALL_BIN)" + @echo "INSTALL_INC= $(INSTALL_INC)" + @echo "INSTALL_LIB= $(INSTALL_LIB)" + @echo "INSTALL_MAN= $(INSTALL_MAN)" + @echo "INSTALL_LMOD= $(INSTALL_LMOD)" + @echo "INSTALL_CMOD= $(INSTALL_CMOD)" + @echo "INSTALL_EXEC= $(INSTALL_EXEC)" + @echo "INSTALL_DATA= $(INSTALL_DATA)" + +# echo pkg-config data +pc: + @echo "version=$R" + @echo "prefix=$(INSTALL_TOP)" + @echo "libdir=$(INSTALL_LIB)" + @echo "includedir=$(INSTALL_INC)" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho + +# (end of Makefile) diff --git a/src/external/lua-5.2.3/README b/src/external/lua-5.2.3/README new file mode 100644 index 000000000..49033adb5 --- /dev/null +++ b/src/external/lua-5.2.3/README @@ -0,0 +1,6 @@ + +This is Lua 5.2.3, released on 11 Nov 2013. + +For installation instructions, license details, and +further information about Lua, see doc/readme.html. + diff --git a/src/external/lua-5.2.3/doc/contents.html b/src/external/lua-5.2.3/doc/contents.html new file mode 100644 index 000000000..0ce297da1 --- /dev/null +++ b/src/external/lua-5.2.3/doc/contents.html @@ -0,0 +1,533 @@ + + + +Lua 5.2 Reference Manual - contents + + + + + + + +
+

+ +Lua 5.2 Reference Manual +

+ +

+The reference manual is the official definition of the Lua language. +For a complete introduction to Lua programming, see the book +Programming in Lua. + +

+start +· +contents +· +index +


+ +Copyright © 2011–2013 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + + +

Contents

+ + +

Index

+ + + + + + + +
+

Lua functions

+

+_G
+_VERSION
+ +

+assert
+collectgarbage
+dofile
+error
+getmetatable
+ipairs
+load
+loadfile
+next
+pairs
+pcall
+print
+rawequal
+rawget
+rawlen
+rawset
+require
+select
+setmetatable
+tonumber
+tostring
+type
+xpcall
+ +

+bit32.arshift
+bit32.band
+bit32.bnot
+bit32.bor
+bit32.btest
+bit32.bxor
+bit32.extract
+bit32.lrotate
+bit32.lshift
+bit32.replace
+bit32.rrotate
+bit32.rshift
+ +

+coroutine.create
+coroutine.resume
+coroutine.running
+coroutine.status
+coroutine.wrap
+coroutine.yield
+ +

+debug.debug
+debug.getuservalue
+debug.gethook
+debug.getinfo
+debug.getlocal
+debug.getmetatable
+debug.getregistry
+debug.getupvalue
+debug.setuservalue
+debug.sethook
+debug.setlocal
+debug.setmetatable
+debug.setupvalue
+debug.traceback
+debug.upvalueid
+debug.upvaluejoin
+ +

+file:close
+file:flush
+file:lines
+file:read
+file:seek
+file:setvbuf
+file:write
+ +

+io.close
+io.flush
+io.input
+io.lines
+io.open
+io.output
+io.popen
+io.read
+io.stderr
+io.stdin
+io.stdout
+io.tmpfile
+io.type
+io.write
+ +

+

 

+

+math.abs
+math.acos
+math.asin
+math.atan
+math.atan2
+math.ceil
+math.cos
+math.cosh
+math.deg
+math.exp
+math.floor
+math.fmod
+math.frexp
+math.huge
+math.ldexp
+math.log
+math.max
+math.min
+math.modf
+math.pi
+math.pow
+math.rad
+math.random
+math.randomseed
+math.sin
+math.sinh
+math.sqrt
+math.tan
+math.tanh
+ +

+os.clock
+os.date
+os.difftime
+os.execute
+os.exit
+os.getenv
+os.remove
+os.rename
+os.setlocale
+os.time
+os.tmpname
+ +

+package.config
+package.cpath
+package.loaded
+package.loadlib
+package.path
+package.preload
+package.searchers
+package.searchpath
+ +

+string.byte
+string.char
+string.dump
+string.find
+string.format
+string.gmatch
+string.gsub
+string.len
+string.lower
+string.match
+string.rep
+string.reverse
+string.sub
+string.upper
+ +

+table.concat
+table.insert
+table.pack
+table.remove
+table.sort
+table.unpack
+ +

+

C API

+

+lua_Alloc
+lua_CFunction
+lua_Debug
+lua_Hook
+lua_Integer
+lua_Number
+lua_Reader
+lua_State
+lua_Unsigned
+lua_Writer
+ +

+lua_absindex
+lua_arith
+lua_atpanic
+lua_call
+lua_callk
+lua_checkstack
+lua_close
+lua_compare
+lua_concat
+lua_copy
+lua_createtable
+lua_dump
+lua_error
+lua_gc
+lua_getallocf
+lua_getctx
+lua_getfield
+lua_getglobal
+lua_gethook
+lua_gethookcount
+lua_gethookmask
+lua_getinfo
+lua_getlocal
+lua_getmetatable
+lua_getstack
+lua_gettable
+lua_gettop
+lua_getupvalue
+lua_getuservalue
+lua_insert
+lua_isboolean
+lua_iscfunction
+lua_isfunction
+lua_islightuserdata
+lua_isnil
+lua_isnone
+lua_isnoneornil
+lua_isnumber
+lua_isstring
+lua_istable
+lua_isthread
+lua_isuserdata
+lua_len
+lua_load
+lua_newstate
+lua_newtable
+lua_newthread
+lua_newuserdata
+lua_next
+lua_pcall
+lua_pcallk
+lua_pop
+lua_pushboolean
+lua_pushcclosure
+lua_pushcfunction
+lua_pushfstring
+lua_pushglobaltable
+lua_pushinteger
+lua_pushlightuserdata
+lua_pushliteral
+lua_pushlstring
+lua_pushnil
+lua_pushnumber
+lua_pushstring
+lua_pushthread
+lua_pushunsigned
+lua_pushvalue
+lua_pushvfstring
+lua_rawequal
+lua_rawget
+lua_rawgeti
+lua_rawgetp
+lua_rawlen
+lua_rawset
+lua_rawseti
+lua_rawsetp
+lua_register
+lua_remove
+lua_replace
+lua_resume
+lua_setallocf
+lua_setfield
+lua_setglobal
+lua_sethook
+lua_setlocal
+lua_setmetatable
+lua_settable
+lua_settop
+lua_setupvalue
+lua_setuservalue
+lua_status
+lua_toboolean
+lua_tocfunction
+lua_tointeger
+lua_tointegerx
+lua_tolstring
+lua_tonumber
+lua_tonumberx
+lua_topointer
+lua_tostring
+lua_tothread
+lua_tounsigned
+lua_tounsignedx
+lua_touserdata
+lua_type
+lua_typename
+lua_upvalueid
+lua_upvalueindex
+lua_upvaluejoin
+lua_version
+lua_xmove
+lua_yield
+lua_yieldk
+ +

+

auxiliary library

+

+luaL_Buffer
+luaL_Reg
+ +

+luaL_addchar
+luaL_addlstring
+luaL_addsize
+luaL_addstring
+luaL_addvalue
+luaL_argcheck
+luaL_argerror
+luaL_buffinit
+luaL_buffinitsize
+luaL_callmeta
+luaL_checkany
+luaL_checkint
+luaL_checkinteger
+luaL_checklong
+luaL_checklstring
+luaL_checknumber
+luaL_checkoption
+luaL_checkstack
+luaL_checkstring
+luaL_checktype
+luaL_checkudata
+luaL_checkunsigned
+luaL_checkversion
+luaL_dofile
+luaL_dostring
+luaL_error
+luaL_execresult
+luaL_fileresult
+luaL_getmetafield
+luaL_getmetatable
+luaL_getsubtable
+luaL_gsub
+luaL_len
+luaL_loadbuffer
+luaL_loadbufferx
+luaL_loadfile
+luaL_loadfilex
+luaL_loadstring
+luaL_newlib
+luaL_newlibtable
+luaL_newmetatable
+luaL_newstate
+luaL_openlibs
+luaL_optint
+luaL_optinteger
+luaL_optlong
+luaL_optlstring
+luaL_optnumber
+luaL_optstring
+luaL_optunsigned
+luaL_prepbuffer
+luaL_prepbuffsize
+luaL_pushresult
+luaL_pushresultsize
+luaL_ref
+luaL_requiref
+luaL_setfuncs
+luaL_setmetatable
+luaL_testudata
+luaL_tolstring
+luaL_traceback
+luaL_typename
+luaL_unref
+luaL_where
+ +

+ +
+ +Last update: +Tue Mar 12 11:22:18 BRT 2013 + + + + + diff --git a/src/external/lua-5.2.3/doc/logo.gif b/src/external/lua-5.2.3/doc/logo.gif new file mode 100644 index 000000000..2f5e4ac2e Binary files /dev/null and b/src/external/lua-5.2.3/doc/logo.gif differ diff --git a/src/external/lua-5.2.3/doc/lua.1 b/src/external/lua-5.2.3/doc/lua.1 new file mode 100644 index 000000000..1dbf04366 --- /dev/null +++ b/src/external/lua-5.2.3/doc/lua.1 @@ -0,0 +1,116 @@ +.\" $Id: lua.man,v 1.13 2011/11/16 17:16:53 lhf Exp $ +.TH LUA 1 "$Date: 2011/11/16 17:16:53 $" +.SH NAME +lua \- Lua interpreter +.SH SYNOPSIS +.B lua +[ +.I options +] +[ +.I script +[ +.I args +] +] +.SH DESCRIPTION +.B lua +is the standalone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +.BR luac , +the Lua compiler.) +.B lua +can be used as a batch interpreter and also interactively. +.LP +The given +.I options +are handled in order and then +the Lua program in file +.I script +is loaded and executed. +The given +.I args +are available to +.I script +as strings in a global table named +.BR arg . +If no options or arguments are given, +then +.B "\-v \-i" +is assumed when the standard input is a terminal; +otherwise, +.B "\-" +is assumed. +.LP +In interactive mode, +.B lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +If a line starts with +.BR '=' , +then +.B lua +evaluates and displays +the values of the expressions in the remainder of the line. +.LP +At the very start, +before even handling the command line, +.B lua +checks the contents of the environment variables +.B LUA_INIT_5_2 +or +.BR LUA_INIT , +in that order. +If the contents is of the form +.RI '@ filename ', +then +.I filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +.SH OPTIONS +.TP +.BI \-e " stat" +execute statement +.IR stat . +.TP +.B \-i +enter interactive mode after executing +.IR script . +.TP +.BI \-l " name" +execute the equivalent of +.IB name =require(' name ') +before executing +.IR script . +.TP +.B \-v +show version information. +.TP +.B \-E +ignore environment variables. +.TP +.B \-\- +stop handling options. +.TP +.B \- +stop handling options and execute the standard input as a file. +.SH "SEE ALSO" +.BR luac (1) +.br +The documentation at lua.org, +especially section 7 of the reference manual. +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +W. Celes +.\" EOF diff --git a/src/external/lua-5.2.3/doc/lua.css b/src/external/lua-5.2.3/doc/lua.css new file mode 100644 index 000000000..3d2443acf --- /dev/null +++ b/src/external/lua-5.2.3/doc/lua.css @@ -0,0 +1,96 @@ +html { + background-color: #F8F8F8 ; +} + +body { + border: solid #a0a0a0 1px ; + border-radius: 20px ; + padding: 26px ; + margin: 16px ; + color: #000000 ; + background-color: #FFFFFF ; + font-family: Helvetica, Arial, sans-serif ; + text-align: justify ; +} + +h1, h2, h3, h4 { + font-family: Verdana, Geneva, sans-serif ; + font-weight: normal ; + font-style: normal ; +} + +h2 { + padding-top: 0.4em ; + padding-bottom: 0.4em ; + padding-left: 0.8em ; + padding-right: 0.8em ; + background-color: #D0D0FF ; + border-radius: 8px ; + border: solid #a0a0a0 1px ; +} + +h3 { + padding-left: 0.5em ; + border-left: solid #D0D0FF 1em ; +} + +table h3 { + padding-left: 0px ; + border-left: none ; +} + +a:link { + color: #000080 ; + background-color: inherit ; + text-decoration: none ; +} + +a:visited { + background-color: inherit ; + text-decoration: none ; +} + +a:link:hover, a:visited:hover { + color: #000080 ; + background-color: #D0D0FF ; +} + +a:link:active, a:visited:active { + color: #FF0000 ; +} + +hr { + border: 0 ; + height: 1px ; + color: #a0a0a0 ; + background-color: #a0a0a0 ; + display: none ; +} + +table hr { + display: block ; +} + +:target { + background-color: #F8F8F8 ; + padding: 8px ; + border: solid #a0a0a0 2px ; + border-radius: 8px ; +} + +.footer { + color: gray ; + font-size: x-small ; +} + +input[type=text] { + border: solid #a0a0a0 2px ; + border-radius: 2em ; + -moz-border-radius: 2em ; + background-image: url('images/search.png') ; + background-repeat: no-repeat; + background-position: 4px center ; + padding-left: 20px ; + height: 2em ; +} + diff --git a/src/external/lua-5.2.3/doc/luac.1 b/src/external/lua-5.2.3/doc/luac.1 new file mode 100644 index 000000000..33a4ed00a --- /dev/null +++ b/src/external/lua-5.2.3/doc/luac.1 @@ -0,0 +1,118 @@ +.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ +.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" +.SH NAME +luac \- Lua compiler +.SH SYNOPSIS +.B luac +[ +.I options +] [ +.I filenames +] +.SH DESCRIPTION +.B luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files containing precompiled chunks +that can be later loaded and executed. +.LP +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +Precompiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +.B luac +simply allows those bytecodes to be saved in a file for later execution. +Precompiled chunks are not necessarily smaller than the corresponding source. +The main goal in precompiling is faster loading. +.LP +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +.B luac +produces a single output file containing the combined bytecodes +for all files given. +Executing the combined file is equivalent to executing the given files. +By default, +the output file is named +.BR luac.out , +but you can change this with the +.B \-o +option. +.LP +Precompiled chunks are +.I not +portable across different architectures. +Moreover, +the internal format of precompiled chunks +is likely to change when a new version of Lua is released. +Make sure you save the source files of all Lua programs that you precompile. +.LP +.SH OPTIONS +.TP +.B \-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +.B luac +loads +.B luac.out +and lists its contents. +Use +.B \-l \-l +for a full listing. +.TP +.BI \-o " file" +output to +.IR file , +instead of the default +.BR luac.out . +(You can use +.B "'\-'" +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be one of the given files because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +.TP +.B \-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +If no files are given, then +.B luac +loads +.B luac.out +and tests its contents. +No messages are displayed if the file loads without errors. +.TP +.B \-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +In particular, +line numbers and names of local variables are lost. +.TP +.B \-v +show version information. +.TP +.B \-\- +stop handling options. +.TP +.B \- +stop handling options and process standard input. +.SH "SEE ALSO" +.BR lua (1) +.br +The documentation at lua.org. +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +W. Celes +.\" EOF diff --git a/src/external/lua-5.2.3/doc/manual.css b/src/external/lua-5.2.3/doc/manual.css new file mode 100644 index 000000000..ca613cd9f --- /dev/null +++ b/src/external/lua-5.2.3/doc/manual.css @@ -0,0 +1,27 @@ +h3 code { + font-family: inherit ; + font-size: inherit ; +} + +pre, code { + font-size: 12pt ; +} + +span.apii { + float: right ; + font-family: inherit ; + font-style: normal ; + font-size: small ; + color: gray ; +} + +p+h1, ul+h1 { + font-style: normal ; + padding-top: 0.4em ; + padding-bottom: 0.4em ; + padding-left: 16px ; + margin-left: -16px ; + background-color: #D0D0FF ; + border-radius: 8px ; + border: solid #000080 1px ; +} diff --git a/src/external/lua-5.2.3/doc/manual.html b/src/external/lua-5.2.3/doc/manual.html new file mode 100644 index 000000000..85365363f --- /dev/null +++ b/src/external/lua-5.2.3/doc/manual.html @@ -0,0 +1,10507 @@ + + + + +Lua 5.2 Reference Manual + + + + + + + +
+

+ +Lua 5.2 Reference Manual +

+ +by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes +

+ +Copyright © 2011–2013 Lua.org, PUC-Rio. +Freely available under the terms of the +Lua license. + +


+

+ +contents +· +index + + +

+ + + + + + +

1 – Introduction

+ +

+Lua is an extension programming language designed to support +general procedural programming with data description +facilities. +It also offers good support for object-oriented programming, +functional programming, and data-driven programming. +Lua is intended to be used as a powerful, lightweight, +embeddable scripting language for any program that needs one. +Lua is implemented as a library, written in clean C, +the common subset of Standard C and C++. + + +

+Being an extension language, Lua has no notion of a "main" program: +it only works embedded in a host client, +called the embedding program or simply the host. +The host program can invoke functions to execute a piece of Lua code, +can write and read Lua variables, +and can register C functions to be called by Lua code. +Through the use of C functions, Lua can be augmented to cope with +a wide range of different domains, +thus creating customized programming languages sharing a syntactical framework. +The Lua distribution includes a sample host program called lua, +which uses the Lua library to offer a complete, standalone Lua interpreter, +for interactive or batch use. + + +

+Lua is free software, +and is provided as usual with no guarantees, +as stated in its license. +The implementation described in this manual is available +at Lua's official web site, www.lua.org. + + +

+Like any other reference manual, +this document is dry in places. +For a discussion of the decisions behind the design of Lua, +see the technical papers available at Lua's web site. +For a detailed introduction to programming in Lua, +see Roberto's book, Programming in Lua. + + + +

2 – Basic Concepts

+ +

+This section describes the basic concepts of the language. + + + +

2.1 – Values and Types

+ +

+Lua is a dynamically typed language. +This means that +variables do not have types; only values do. +There are no type definitions in the language. +All values carry their own type. + + +

+All values in Lua are first-class values. +This means that all values can be stored in variables, +passed as arguments to other functions, and returned as results. + + +

+There are eight basic types in Lua: +nil, boolean, number, +string, function, userdata, +thread, and table. +Nil is the type of the value nil, +whose main property is to be different from any other value; +it usually represents the absence of a useful value. +Boolean is the type of the values false and true. +Both nil and false make a condition false; +any other value makes it true. +Number represents real (double-precision floating-point) numbers. +Operations on numbers follow the same rules of +the underlying C implementation, +which, in turn, usually follows the IEEE 754 standard. +(It is easy to build Lua interpreters that use other +internal representations for numbers, +such as single-precision floats or long integers; +see file luaconf.h.) +String represents immutable sequences of bytes. + +Lua is 8-bit clean: +strings can contain any 8-bit value, +including embedded zeros ('\0'). + + +

+Lua can call (and manipulate) functions written in Lua and +functions written in C +(see §3.4.9). + + +

+The type userdata is provided to allow arbitrary C data to +be stored in Lua variables. +A userdata value is a pointer to a block of raw memory. +There are two kinds of userdata: +full userdata, where the block of memory is managed by Lua, +and light userdata, where the block of memory is managed by the host. +Userdata has no predefined operations in Lua, +except assignment and identity test. +By using metatables, +the programmer can define operations for full userdata values +(see §2.4). +Userdata values cannot be created or modified in Lua, +only through the C API. +This guarantees the integrity of data owned by the host program. + + +

+The type thread represents independent threads of execution +and it is used to implement coroutines (see §2.6). +Do not confuse Lua threads with operating-system threads. +Lua supports coroutines on all systems, +even those that do not support threads. + + +

+The type table implements associative arrays, +that is, arrays that can be indexed not only with numbers, +but with any Lua value except nil and NaN +(Not a Number, a special numeric value used to represent +undefined or unrepresentable results, such as 0/0). +Tables can be heterogeneous; +that is, they can contain values of all types (except nil). +Any key with value nil is not considered part of the table. +Conversely, any key that is not part of a table has +an associated value nil. + + +

+Tables are the sole data structuring mechanism in Lua; +they can be used to represent ordinary arrays, sequences, +symbol tables, sets, records, graphs, trees, etc. +To represent records, Lua uses the field name as an index. +The language supports this representation by +providing a.name as syntactic sugar for a["name"]. +There are several convenient ways to create tables in Lua +(see §3.4.8). + + +

+We use the term sequence to denote a table where +the set of all positive numeric keys is equal to {1..n} +for some integer n, +which is called the length of the sequence (see §3.4.6). + + +

+Like indices, +the values of table fields can be of any type. +In particular, +because functions are first-class values, +table fields can contain functions. +Thus tables can also carry methods (see §3.4.10). + + +

+The indexing of tables follows +the definition of raw equality in the language. +The expressions a[i] and a[j] +denote the same table element +if and only if i and j are raw equal +(that is, equal without metamethods). + + +

+Tables, functions, threads, and (full) userdata values are objects: +variables do not actually contain these values, +only references to them. +Assignment, parameter passing, and function returns +always manipulate references to such values; +these operations do not imply any kind of copy. + + +

+The library function type returns a string describing the type +of a given value (see §6.1). + + + + + +

2.2 – Environments and the Global Environment

+ +

+As will be discussed in §3.2 and §3.3.3, +any reference to a global name var is syntactically translated +to _ENV.var. +Moreover, every chunk is compiled in the scope of +an external local variable called _ENV (see §3.3.2), +so _ENV itself is never a global name in a chunk. + + +

+Despite the existence of this external _ENV variable and +the translation of global names, +_ENV is a completely regular name. +In particular, +you can define new variables and parameters with that name. +Each reference to a global name uses the _ENV that is +visible at that point in the program, +following the usual visibility rules of Lua (see §3.5). + + +

+Any table used as the value of _ENV is called an environment. + + +

+Lua keeps a distinguished environment called the global environment. +This value is kept at a special index in the C registry (see §4.5). +In Lua, the variable _G is initialized with this same value. + + +

+When Lua compiles a chunk, +it initializes the value of its _ENV upvalue +with the global environment (see load). +Therefore, by default, +global variables in Lua code refer to entries in the global environment. +Moreover, all standard libraries are loaded in the global environment +and several functions there operate on that environment. +You can use load (or loadfile) +to load a chunk with a different environment. +(In C, you have to load the chunk and then change the value +of its first upvalue.) + + +

+If you change the global environment in the registry +(through C code or the debug library), +all chunks loaded after the change will get the new environment. +Previously loaded chunks are not affected, however, +as each has its own reference to the environment in its _ENV variable. +Moreover, the variable _G +(which is stored in the original global environment) +is never updated by Lua. + + + + + +

2.3 – Error Handling

+ +

+Because Lua is an embedded extension language, +all Lua actions start from C code in the host program +calling a function from the Lua library (see lua_pcall). +Whenever an error occurs during +the compilation or execution of a Lua chunk, +control returns to the host, +which can take appropriate measures +(such as printing an error message). + + +

+Lua code can explicitly generate an error by calling the +error function. +If you need to catch errors in Lua, +you can use pcall or xpcall +to call a given function in protected mode. + + +

+Whenever there is an error, +an error object (also called an error message) +is propagated with information about the error. +Lua itself only generates errors where the error object is a string, +but programs may generate errors with +any value for the error object. + + +

+When you use xpcall or lua_pcall, +you may give a message handler +to be called in case of errors. +This function is called with the original error message +and returns a new error message. +It is called before the error unwinds the stack, +so that it can gather more information about the error, +for instance by inspecting the stack and creating a stack traceback. +This message handler is still protected by the protected call; +so, an error inside the message handler +will call the message handler again. +If this loop goes on, Lua breaks it and returns an appropriate message. + + + + + +

2.4 – Metatables and Metamethods

+ +

+Every value in Lua can have a metatable. +This metatable is an ordinary Lua table +that defines the behavior of the original value +under certain special operations. +You can change several aspects of the behavior +of operations over a value by setting specific fields in its metatable. +For instance, when a non-numeric value is the operand of an addition, +Lua checks for a function in the field "__add" of the value's metatable. +If it finds one, +Lua calls this function to perform the addition. + + +

+The keys in a metatable are derived from the event names; +the corresponding values are called metamethods. +In the previous example, the event is "add" +and the metamethod is the function that performs the addition. + + +

+You can query the metatable of any value +using the getmetatable function. + + +

+You can replace the metatable of tables +using the setmetatable function. +You cannot change the metatable of other types from Lua +(except by using the debug library); +you must use the C API for that. + + +

+Tables and full userdata have individual metatables +(although multiple tables and userdata can share their metatables). +Values of all other types share one single metatable per type; +that is, there is one single metatable for all numbers, +one for all strings, etc. +By default, a value has no metatable, +but the string library sets a metatable for the string type (see §6.4). + + +

+A metatable controls how an object behaves in arithmetic operations, +order comparisons, concatenation, length operation, and indexing. +A metatable also can define a function to be called +when a userdata or a table is garbage collected. +When Lua performs one of these operations over a value, +it checks whether this value has a metatable with the corresponding event. +If so, the value associated with that key (the metamethod) +controls how Lua will perform the operation. + + +

+Metatables control the operations listed next. +Each operation is identified by its corresponding name. +The key for each operation is a string with its name prefixed by +two underscores, '__'; +for instance, the key for operation "add" is the +string "__add". + + +

+The semantics of these operations is better explained by a Lua function +describing how the interpreter executes the operation. +The code shown here in Lua is only illustrative; +the real behavior is hard coded in the interpreter +and it is much more efficient than this simulation. +All functions used in these descriptions +(rawget, tonumber, etc.) +are described in §6.1. +In particular, to retrieve the metamethod of a given object, +we use the expression + +

+     metatable(obj)[event]
+

+This should be read as + +

+     rawget(getmetatable(obj) or {}, event)
+

+This means that the access to a metamethod does not invoke other metamethods, +and access to objects with no metatables does not fail +(it simply results in nil). + + +

+For the unary - and # operators, +the metamethod is called with a dummy second argument. +This extra argument is only to simplify Lua's internals; +it may be removed in future versions and therefore it is not present +in the following code. +(For most uses this extra argument is irrelevant.) + + + +

    + +
  • "add": +the + operation. + + + +

    +The function getbinhandler below defines how Lua chooses a handler +for a binary operation. +First, Lua tries the first operand. +If its type does not define a handler for the operation, +then Lua tries the second operand. + +

    +     function getbinhandler (op1, op2, event)
    +       return metatable(op1)[event] or metatable(op2)[event]
    +     end
    +

    +By using this function, +the behavior of the op1 + op2 is + +

    +     function add_event (op1, op2)
    +       local o1, o2 = tonumber(op1), tonumber(op2)
    +       if o1 and o2 then  -- both operands are numeric?
    +         return o1 + o2   -- '+' here is the primitive 'add'
    +       else  -- at least one of the operands is not numeric
    +         local h = getbinhandler(op1, op2, "__add")
    +         if h then
    +           -- call the handler with both operands
    +           return (h(op1, op2))
    +         else  -- no handler available: default behavior
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
  • "sub": +the - operation. + +Behavior similar to the "add" operation. +
  • + +
  • "mul": +the * operation. + +Behavior similar to the "add" operation. +
  • + +
  • "div": +the / operation. + +Behavior similar to the "add" operation. +
  • + +
  • "mod": +the % operation. + +Behavior similar to the "add" operation, +with the operation +o1 - floor(o1/o2)*o2 as the primitive operation. +
  • + +
  • "pow": +the ^ (exponentiation) operation. + +Behavior similar to the "add" operation, +with the function pow (from the C math library) +as the primitive operation. +
  • + +
  • "unm": +the unary - operation. + + +
    +     function unm_event (op)
    +       local o = tonumber(op)
    +       if o then  -- operand is numeric?
    +         return -o  -- '-' here is the primitive 'unm'
    +       else  -- the operand is not numeric.
    +         -- Try to get a handler from the operand
    +         local h = metatable(op).__unm
    +         if h then
    +           -- call the handler with the operand
    +           return (h(op))
    +         else  -- no handler available: default behavior
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
  • "concat": +the .. (concatenation) operation. + + +
    +     function concat_event (op1, op2)
    +       if (type(op1) == "string" or type(op1) == "number") and
    +          (type(op2) == "string" or type(op2) == "number") then
    +         return op1 .. op2  -- primitive string concatenation
    +       else
    +         local h = getbinhandler(op1, op2, "__concat")
    +         if h then
    +           return (h(op1, op2))
    +         else
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
  • "len": +the # operation. + + +
    +     function len_event (op)
    +       if type(op) == "string" then
    +         return strlen(op)      -- primitive string length
    +       else
    +         local h = metatable(op).__len
    +         if h then
    +           return (h(op))       -- call handler with the operand
    +         elseif type(op) == "table" then
    +           return #op              -- primitive table length
    +         else  -- no handler available: error
    +           error(···)
    +         end
    +       end
    +     end
    +

    +See §3.4.6 for a description of the length of a table. +

  • + +
  • "eq": +the == operation. + +The function getequalhandler defines how Lua chooses a metamethod +for equality. +A metamethod is selected only when both values +being compared have the same type +and the same metamethod for the selected operation, +and the values are either tables or full userdata. + +
    +     function getequalhandler (op1, op2)
    +       if type(op1) ~= type(op2) or
    +          (type(op1) ~= "table" and type(op1) ~= "userdata") then
    +         return nil     -- different values
    +       end
    +       local mm1 = metatable(op1).__eq
    +       local mm2 = metatable(op2).__eq
    +       if mm1 == mm2 then return mm1 else return nil end
    +     end
    +

    +The "eq" event is defined as follows: + +

    +     function eq_event (op1, op2)
    +       if op1 == op2 then   -- primitive equal?
    +         return true   -- values are equal
    +       end
    +       -- try metamethod
    +       local h = getequalhandler(op1, op2)
    +       if h then
    +         return not not h(op1, op2)
    +       else
    +         return false
    +       end
    +     end
    +

    +Note that the result is always a boolean. +

  • + +
  • "lt": +the < operation. + + +
    +     function lt_event (op1, op2)
    +       if type(op1) == "number" and type(op2) == "number" then
    +         return op1 < op2   -- numeric comparison
    +       elseif type(op1) == "string" and type(op2) == "string" then
    +         return op1 < op2   -- lexicographic comparison
    +       else
    +         local h = getbinhandler(op1, op2, "__lt")
    +         if h then
    +           return not not h(op1, op2)
    +         else
    +           error(···)
    +         end
    +       end
    +     end
    +

    +Note that the result is always a boolean. +

  • + +
  • "le": +the <= operation. + + +
    +     function le_event (op1, op2)
    +       if type(op1) == "number" and type(op2) == "number" then
    +         return op1 <= op2   -- numeric comparison
    +       elseif type(op1) == "string" and type(op2) == "string" then
    +         return op1 <= op2   -- lexicographic comparison
    +       else
    +         local h = getbinhandler(op1, op2, "__le")
    +         if h then
    +           return not not h(op1, op2)
    +         else
    +           h = getbinhandler(op1, op2, "__lt")
    +           if h then
    +             return not h(op2, op1)
    +           else
    +             error(···)
    +           end
    +         end
    +       end
    +     end
    +

    +Note that, in the absence of a "le" metamethod, +Lua tries the "lt", assuming that a <= b is +equivalent to not (b < a). + + +

    +As with the other comparison operators, +the result is always a boolean. +

  • + +
  • "index": +The indexing access table[key]. +Note that the metamethod is tried only +when key is not present in table. +(When table is not a table, +no key is ever present, +so the metamethod is always tried.) + + +
    +     function gettable_event (table, key)
    +       local h
    +       if type(table) == "table" then
    +         local v = rawget(table, key)
    +         -- if key is present, return raw value
    +         if v ~= nil then return v end
    +         h = metatable(table).__index
    +         if h == nil then return nil end
    +       else
    +         h = metatable(table).__index
    +         if h == nil then
    +           error(···)
    +         end
    +       end
    +       if type(h) == "function" then
    +         return (h(table, key))     -- call the handler
    +       else return h[key]           -- or repeat operation on it
    +       end
    +     end
    +

    +

  • + +
  • "newindex": +The indexing assignment table[key] = value. +Note that the metamethod is tried only +when key is not present in table. + + +
    +     function settable_event (table, key, value)
    +       local h
    +       if type(table) == "table" then
    +         local v = rawget(table, key)
    +         -- if key is present, do raw assignment
    +         if v ~= nil then rawset(table, key, value); return end
    +         h = metatable(table).__newindex
    +         if h == nil then rawset(table, key, value); return end
    +       else
    +         h = metatable(table).__newindex
    +         if h == nil then
    +           error(···)
    +         end
    +       end
    +       if type(h) == "function" then
    +         h(table, key,value)           -- call the handler
    +       else h[key] = value             -- or repeat operation on it
    +       end
    +     end
    +

    +

  • + +
  • "call": +called when Lua calls a value. + + +
    +     function function_event (func, ...)
    +       if type(func) == "function" then
    +         return func(...)   -- primitive call
    +       else
    +         local h = metatable(func).__call
    +         if h then
    +           return h(func, ...)
    +         else
    +           error(···)
    +         end
    +       end
    +     end
    +

    +

  • + +
+ + + + +

2.5 – Garbage Collection

+ +

+Lua performs automatic memory management. +This means that +you have to worry neither about allocating memory for new objects +nor about freeing it when the objects are no longer needed. +Lua manages memory automatically by running +a garbage collector to collect all dead objects +(that is, objects that are no longer accessible from Lua). +All memory used by Lua is subject to automatic management: +strings, tables, userdata, functions, threads, internal structures, etc. + + +

+Lua implements an incremental mark-and-sweep collector. +It uses two numbers to control its garbage-collection cycles: +the garbage-collector pause and +the garbage-collector step multiplier. +Both use percentage points as units +(e.g., a value of 100 means an internal value of 1). + + +

+The garbage-collector pause +controls how long the collector waits before starting a new cycle. +Larger values make the collector less aggressive. +Values smaller than 100 mean the collector will not wait to +start a new cycle. +A value of 200 means that the collector waits for the total memory in use +to double before starting a new cycle. + + +

+The garbage-collector step multiplier +controls the relative speed of the collector relative to +memory allocation. +Larger values make the collector more aggressive but also increase +the size of each incremental step. +Values smaller than 100 make the collector too slow and +can result in the collector never finishing a cycle. +The default is 200, +which means that the collector runs at "twice" +the speed of memory allocation. + + +

+If you set the step multiplier to a very large number +(larger than 10% of the maximum number of +bytes that the program may use), +the collector behaves like a stop-the-world collector. +If you then set the pause to 200, +the collector behaves as in old Lua versions, +doing a complete collection every time Lua doubles its +memory usage. + + +

+You can change these numbers by calling lua_gc in C +or collectgarbage in Lua. +You can also use these functions to control +the collector directly (e.g., stop and restart it). + + +

+As an experimental feature in Lua 5.2, +you can change the collector's operation mode +from incremental to generational. +A generational collector assumes that most objects die young, +and therefore it traverses only young (recently created) objects. +This behavior can reduce the time used by the collector, +but also increases memory usage (as old dead objects may accumulate). +To mitigate this second problem, +from time to time the generational collector performs a full collection. +Remember that this is an experimental feature; +you are welcome to try it, +but check your gains. + + + +

2.5.1 – Garbage-Collection Metamethods

+ +

+You can set garbage-collector metamethods for tables +and, using the C API, +for full userdata (see §2.4). +These metamethods are also called finalizers. +Finalizers allow you to coordinate Lua's garbage collection +with external resource management +(such as closing files, network or database connections, +or freeing your own memory). + + +

+For an object (table or userdata) to be finalized when collected, +you must mark it for finalization. + +You mark an object for finalization when you set its metatable +and the metatable has a field indexed by the string "__gc". +Note that if you set a metatable without a __gc field +and later create that field in the metatable, +the object will not be marked for finalization. +However, after an object is marked, +you can freely change the __gc field of its metatable. + + +

+When a marked object becomes garbage, +it is not collected immediately by the garbage collector. +Instead, Lua puts it in a list. +After the collection, +Lua does the equivalent of the following function +for each object in that list: + +

+     function gc_event (obj)
+       local h = metatable(obj).__gc
+       if type(h) == "function" then
+         h(obj)
+       end
+     end
+
+ +

+At the end of each garbage-collection cycle, +the finalizers for objects are called in +the reverse order that they were marked for collection, +among those collected in that cycle; +that is, the first finalizer to be called is the one associated +with the object marked last in the program. +The execution of each finalizer may occur at any point during +the execution of the regular code. + + +

+Because the object being collected must still be used by the finalizer, +it (and other objects accessible only through it) +must be resurrected by Lua. +Usually, this resurrection is transient, +and the object memory is freed in the next garbage-collection cycle. +However, if the finalizer stores the object in some global place +(e.g., a global variable), +then there is a permanent resurrection. +In any case, +the object memory is freed only when it becomes completely inaccessible; +its finalizer will never be called twice. + + +

+When you close a state (see lua_close), +Lua calls the finalizers of all objects marked for finalization, +following the reverse order that they were marked. +If any finalizer marks new objects for collection during that phase, +these new objects will not be finalized. + + + + + +

2.5.2 – Weak Tables

+ +

+A weak table is a table whose elements are +weak references. +A weak reference is ignored by the garbage collector. +In other words, +if the only references to an object are weak references, +then the garbage collector will collect that object. + + +

+A weak table can have weak keys, weak values, or both. +A table with weak keys allows the collection of its keys, +but prevents the collection of its values. +A table with both weak keys and weak values allows the collection of +both keys and values. +In any case, if either the key or the value is collected, +the whole pair is removed from the table. +The weakness of a table is controlled by the +__mode field of its metatable. +If the __mode field is a string containing the character 'k', +the keys in the table are weak. +If __mode contains 'v', +the values in the table are weak. + + +

+A table with weak keys and strong values +is also called an ephemeron table. +In an ephemeron table, +a value is considered reachable only if its key is reachable. +In particular, +if the only reference to a key comes through its value, +the pair is removed. + + +

+Any change in the weakness of a table may take effect only +at the next collect cycle. +In particular, if you change the weakness to a stronger mode, +Lua may still collect some items from that table +before the change takes effect. + + +

+Only objects that have an explicit construction +are removed from weak tables. +Values, such as numbers and light C functions, +are not subject to garbage collection, +and therefore are not removed from weak tables +(unless its associated value is collected). +Although strings are subject to garbage collection, +they do not have an explicit construction, +and therefore are not removed from weak tables. + + +

+Resurrected objects +(that is, objects being finalized +and objects accessible only through objects being finalized) +have a special behavior in weak tables. +They are removed from weak values before running their finalizers, +but are removed from weak keys only in the next collection +after running their finalizers, when such objects are actually freed. +This behavior allows the finalizer to access properties +associated with the object through weak tables. + + +

+If a weak table is among the resurrected objects in a collection cycle, +it may not be properly cleared until the next cycle. + + + + + + + +

2.6 – Coroutines

+ +

+Lua supports coroutines, +also called collaborative multithreading. +A coroutine in Lua represents an independent thread of execution. +Unlike threads in multithread systems, however, +a coroutine only suspends its execution by explicitly calling +a yield function. + + +

+You create a coroutine by calling coroutine.create. +Its sole argument is a function +that is the main function of the coroutine. +The create function only creates a new coroutine and +returns a handle to it (an object of type thread); +it does not start the coroutine. + + +

+You execute a coroutine by calling coroutine.resume. +When you first call coroutine.resume, +passing as its first argument +a thread returned by coroutine.create, +the coroutine starts its execution, +at the first line of its main function. +Extra arguments passed to coroutine.resume are passed on +to the coroutine main function. +After the coroutine starts running, +it runs until it terminates or yields. + + +

+A coroutine can terminate its execution in two ways: +normally, when its main function returns +(explicitly or implicitly, after the last instruction); +and abnormally, if there is an unprotected error. +In the first case, coroutine.resume returns true, +plus any values returned by the coroutine main function. +In case of errors, coroutine.resume returns false +plus an error message. + + +

+A coroutine yields by calling coroutine.yield. +When a coroutine yields, +the corresponding coroutine.resume returns immediately, +even if the yield happens inside nested function calls +(that is, not in the main function, +but in a function directly or indirectly called by the main function). +In the case of a yield, coroutine.resume also returns true, +plus any values passed to coroutine.yield. +The next time you resume the same coroutine, +it continues its execution from the point where it yielded, +with the call to coroutine.yield returning any extra +arguments passed to coroutine.resume. + + +

+Like coroutine.create, +the coroutine.wrap function also creates a coroutine, +but instead of returning the coroutine itself, +it returns a function that, when called, resumes the coroutine. +Any arguments passed to this function +go as extra arguments to coroutine.resume. +coroutine.wrap returns all the values returned by coroutine.resume, +except the first one (the boolean error code). +Unlike coroutine.resume, +coroutine.wrap does not catch errors; +any error is propagated to the caller. + + +

+As an example of how coroutines work, +consider the following code: + +

+     function foo (a)
+       print("foo", a)
+       return coroutine.yield(2*a)
+     end
+     
+     co = coroutine.create(function (a,b)
+           print("co-body", a, b)
+           local r = foo(a+1)
+           print("co-body", r)
+           local r, s = coroutine.yield(a+b, a-b)
+           print("co-body", r, s)
+           return b, "end"
+     end)
+     
+     print("main", coroutine.resume(co, 1, 10))
+     print("main", coroutine.resume(co, "r"))
+     print("main", coroutine.resume(co, "x", "y"))
+     print("main", coroutine.resume(co, "x", "y"))
+

+When you run it, it produces the following output: + +

+     co-body 1       10
+     foo     2
+     main    true    4
+     co-body r
+     main    true    11      -9
+     co-body x       y
+     main    true    10      end
+     main    false   cannot resume dead coroutine
+
+ +

+You can also create and manipulate coroutines through the C API: +see functions lua_newthread, lua_resume, +and lua_yield. + + + + + +

3 – The Language

+ +

+This section describes the lexis, the syntax, and the semantics of Lua. +In other words, +this section describes +which tokens are valid, +how they can be combined, +and what their combinations mean. + + +

+Language constructs will be explained using the usual extended BNF notation, +in which +{a} means 0 or more a's, and +[a] means an optional a. +Non-terminals are shown like non-terminal, +keywords are shown like kword, +and other terminal symbols are shown like ‘=’. +The complete syntax of Lua can be found in §9 +at the end of this manual. + + + +

3.1 – Lexical Conventions

+ +

+Lua is a free-form language. +It ignores spaces (including new lines) and comments +between lexical elements (tokens), +except as delimiters between names and keywords. + + +

+Names +(also called identifiers) +in Lua can be any string of letters, +digits, and underscores, +not beginning with a digit. +Identifiers are used to name variables, table fields, and labels. + + +

+The following keywords are reserved +and cannot be used as names: + + +

+     and       break     do        else      elseif    end
+     false     for       function  goto      if        in
+     local     nil       not       or        repeat    return
+     then      true      until     while
+
+ +

+Lua is a case-sensitive language: +and is a reserved word, but And and AND +are two different, valid names. +As a convention, names starting with an underscore followed by +uppercase letters (such as _VERSION) +are reserved for variables used by Lua. + + +

+The following strings denote other tokens: + +

+     +     -     *     /     %     ^     #
+     ==    ~=    <=    >=    <     >     =
+     (     )     {     }     [     ]     ::
+     ;     :     ,     .     ..    ...
+
+ +

+Literal strings +can be delimited by matching single or double quotes, +and can contain the following C-like escape sequences: +'\a' (bell), +'\b' (backspace), +'\f' (form feed), +'\n' (newline), +'\r' (carriage return), +'\t' (horizontal tab), +'\v' (vertical tab), +'\\' (backslash), +'\"' (quotation mark [double quote]), +and '\'' (apostrophe [single quote]). +A backslash followed by a real newline +results in a newline in the string. +The escape sequence '\z' skips the following span +of white-space characters, +including line breaks; +it is particularly useful to break and indent a long literal string +into multiple lines without adding the newlines and spaces +into the string contents. + + +

+A byte in a literal string can also be specified by its numerical value. +This can be done with the escape sequence \xXX, +where XX is a sequence of exactly two hexadecimal digits, +or with the escape sequence \ddd, +where ddd is a sequence of up to three decimal digits. +(Note that if a decimal escape is to be followed by a digit, +it must be expressed using exactly three digits.) +Strings in Lua can contain any 8-bit value, including embedded zeros, +which can be specified as '\0'. + + +

+Literal strings can also be defined using a long format +enclosed by long brackets. +We define an opening long bracket of level n as an opening +square bracket followed by n equal signs followed by another +opening square bracket. +So, an opening long bracket of level 0 is written as [[, +an opening long bracket of level 1 is written as [=[, +and so on. +A closing long bracket is defined similarly; +for instance, a closing long bracket of level 4 is written as ]====]. +A long literal starts with an opening long bracket of any level and +ends at the first closing long bracket of the same level. +It can contain any text except a closing bracket of the proper level. +Literals in this bracketed form can run for several lines, +do not interpret any escape sequences, +and ignore long brackets of any other level. +Any kind of end-of-line sequence +(carriage return, newline, carriage return followed by newline, +or newline followed by carriage return) +is converted to a simple newline. + + +

+Any byte in a literal string not +explicitly affected by the previous rules represents itself. +However, Lua opens files for parsing in text mode, +and the system file functions may have problems with +some control characters. +So, it is safer to represent +non-text data as a quoted literal with +explicit escape sequences for non-text characters. + + +

+For convenience, +when the opening long bracket is immediately followed by a newline, +the newline is not included in the string. +As an example, in a system using ASCII +(in which 'a' is coded as 97, +newline is coded as 10, and '1' is coded as 49), +the five literal strings below denote the same string: + +

+     a = 'alo\n123"'
+     a = "alo\n123\""
+     a = '\97lo\10\04923"'
+     a = [[alo
+     123"]]
+     a = [==[
+     alo
+     123"]==]
+
+ +

+A numerical constant can be written with an optional fractional part +and an optional decimal exponent, +marked by a letter 'e' or 'E'. +Lua also accepts hexadecimal constants, +which start with 0x or 0X. +Hexadecimal constants also accept an optional fractional part +plus an optional binary exponent, +marked by a letter 'p' or 'P'. +Examples of valid numerical constants are + +

+     3     3.0     3.1416     314.16e-2     0.31416E1
+     0xff  0x0.1E  0xA23p-4   0X1.921FB54442D18P+1
+
+ +

+A comment starts with a double hyphen (--) +anywhere outside a string. +If the text immediately after -- is not an opening long bracket, +the comment is a short comment, +which runs until the end of the line. +Otherwise, it is a long comment, +which runs until the corresponding closing long bracket. +Long comments are frequently used to disable code temporarily. + + + + + +

3.2 – Variables

+ +

+Variables are places that store values. +There are three kinds of variables in Lua: +global variables, local variables, and table fields. + + +

+A single name can denote a global variable or a local variable +(or a function's formal parameter, +which is a particular kind of local variable): + +

+	var ::= Name
+

+Name denotes identifiers, as defined in §3.1. + + +

+Any variable name is assumed to be global unless explicitly declared +as a local (see §3.3.7). +Local variables are lexically scoped: +local variables can be freely accessed by functions +defined inside their scope (see §3.5). + + +

+Before the first assignment to a variable, its value is nil. + + +

+Square brackets are used to index a table: + +

+	var ::= prefixexp ‘[’ exp ‘]’
+

+The meaning of accesses to table fields can be changed via metatables. +An access to an indexed variable t[i] is equivalent to +a call gettable_event(t,i). +(See §2.4 for a complete description of the +gettable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

+The syntax var.Name is just syntactic sugar for +var["Name"]: + +

+	var ::= prefixexp ‘.’ Name
+
+ +

+An access to a global variable x +is equivalent to _ENV.x. +Due to the way that chunks are compiled, +_ENV is never a global name (see §2.2). + + + + + +

3.3 – Statements

+ +

+Lua supports an almost conventional set of statements, +similar to those in Pascal or C. +This set includes +assignments, control structures, function calls, +and variable declarations. + + + +

3.3.1 – Blocks

+ +

+A block is a list of statements, +which are executed sequentially: + +

+	block ::= {stat}
+

+Lua has empty statements +that allow you to separate statements with semicolons, +start a block with a semicolon +or write two semicolons in sequence: + +

+	stat ::= ‘;’
+
+ +

+Function calls and assignments +can start with an open parenthesis. +This possibility leads to an ambiguity in Lua's grammar. +Consider the following fragment: + +

+     a = b + c
+     (print or io.write)('done')
+

+The grammar could see it in two ways: + +

+     a = b + c(print or io.write)('done')
+     
+     a = b + c; (print or io.write)('done')
+

+The current parser always sees such constructions +in the first way, +interpreting the open parenthesis +as the start of the arguments to a call. +To avoid this ambiguity, +it is a good practice to always precede with a semicolon +statements that start with a parenthesis: + +

+     ;(print or io.write)('done')
+
+ +

+A block can be explicitly delimited to produce a single statement: + +

+	stat ::= do block end
+

+Explicit blocks are useful +to control the scope of variable declarations. +Explicit blocks are also sometimes used to +add a return statement in the middle +of another block (see §3.3.4). + + + + + +

3.3.2 – Chunks

+ +

+The unit of compilation of Lua is called a chunk. +Syntactically, +a chunk is simply a block: + +

+	chunk ::= block
+
+ +

+Lua handles a chunk as the body of an anonymous function +with a variable number of arguments +(see §3.4.10). +As such, chunks can define local variables, +receive arguments, and return values. +Moreover, such anonymous function is compiled as in the +scope of an external local variable called _ENV (see §2.2). +The resulting function always has _ENV as its only upvalue, +even if it does not use that variable. + + +

+A chunk can be stored in a file or in a string inside the host program. +To execute a chunk, +Lua first precompiles the chunk into instructions for a virtual machine, +and then it executes the compiled code +with an interpreter for the virtual machine. + + +

+Chunks can also be precompiled into binary form; +see program luac for details. +Programs in source and compiled forms are interchangeable; +Lua automatically detects the file type and acts accordingly. + + + + + + +

3.3.3 – Assignment

+ +

+Lua allows multiple assignments. +Therefore, the syntax for assignment +defines a list of variables on the left side +and a list of expressions on the right side. +The elements in both lists are separated by commas: + +

+	stat ::= varlist ‘=’ explist
+	varlist ::= var {‘,’ var}
+	explist ::= exp {‘,’ exp}
+

+Expressions are discussed in §3.4. + + +

+Before the assignment, +the list of values is adjusted to the length of +the list of variables. +If there are more values than needed, +the excess values are thrown away. +If there are fewer values than needed, +the list is extended with as many nil's as needed. +If the list of expressions ends with a function call, +then all values returned by that call enter the list of values, +before the adjustment +(except when the call is enclosed in parentheses; see §3.4). + + +

+The assignment statement first evaluates all its expressions +and only then are the assignments performed. +Thus the code + +

+     i = 3
+     i, a[i] = i+1, 20
+

+sets a[3] to 20, without affecting a[4] +because the i in a[i] is evaluated (to 3) +before it is assigned 4. +Similarly, the line + +

+     x, y = y, x
+

+exchanges the values of x and y, +and + +

+     x, y, z = y, z, x
+

+cyclically permutes the values of x, y, and z. + + +

+The meaning of assignments to global variables +and table fields can be changed via metatables. +An assignment to an indexed variable t[i] = val is equivalent to +settable_event(t,i,val). +(See §2.4 for a complete description of the +settable_event function. +This function is not defined or callable in Lua. +We use it here only for explanatory purposes.) + + +

+An assignment to a global variable x = val +is equivalent to the assignment +_ENV.x = val (see §2.2). + + + + + +

3.3.4 – Control Structures

+The control structures +if, while, and repeat have the usual meaning and +familiar syntax: + + + + +

+	stat ::= while exp do block end
+	stat ::= repeat block until exp
+	stat ::= if exp then block {elseif exp then block} [else block] end
+

+Lua also has a for statement, in two flavors (see §3.3.5). + + +

+The condition expression of a +control structure can return any value. +Both false and nil are considered false. +All values different from nil and false are considered true +(in particular, the number 0 and the empty string are also true). + + +

+In the repeatuntil loop, +the inner block does not end at the until keyword, +but only after the condition. +So, the condition can refer to local variables +declared inside the loop block. + + +

+The goto statement transfers the program control to a label. +For syntactical reasons, +labels in Lua are considered statements too: + + + +

+	stat ::= goto Name
+	stat ::= label
+	label ::= ‘::’ Name ‘::’
+
+ +

+A label is visible in the entire block where it is defined, +except +inside nested blocks where a label with the same name is defined and +inside nested functions. +A goto may jump to any visible label as long as it does not +enter into the scope of a local variable. + + +

+Labels and empty statements are called void statements, +as they perform no actions. + + +

+The break statement terminates the execution of a +while, repeat, or for loop, +skipping to the next statement after the loop: + + +

+	stat ::= break
+

+A break ends the innermost enclosing loop. + + +

+The return statement is used to return values +from a function or a chunk (which is a function in disguise). + +Functions can return more than one value, +so the syntax for the return statement is + +

+	stat ::= return [explist] [‘;’]
+
+ +

+The return statement can only be written +as the last statement of a block. +If it is really necessary to return in the middle of a block, +then an explicit inner block can be used, +as in the idiom do return end, +because now return is the last statement in its (inner) block. + + + + + +

3.3.5 – For Statement

+ +

+ +The for statement has two forms: +one numeric and one generic. + + +

+The numeric for loop repeats a block of code while a +control variable runs through an arithmetic progression. +It has the following syntax: + +

+	stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
+

+The block is repeated for name starting at the value of +the first exp, until it passes the second exp by steps of the +third exp. +More precisely, a for statement like + +

+     for v = e1, e2, e3 do block end
+

+is equivalent to the code: + +

+     do
+       local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
+       if not (var and limit and step) then error() end
+       while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
+         local v = var
+         block
+         var = var + step
+       end
+     end
+

+Note the following: + +

    + +
  • +All three control expressions are evaluated only once, +before the loop starts. +They must all result in numbers. +
  • + +
  • +var, limit, and step are invisible variables. +The names shown here are for explanatory purposes only. +
  • + +
  • +If the third expression (the step) is absent, +then a step of 1 is used. +
  • + +
  • +You can use break to exit a for loop. +
  • + +
  • +The loop variable v is local to the loop; +you cannot use its value after the for ends or is broken. +If you need this value, +assign it to another variable before breaking or exiting the loop. +
  • + +
+ +

+The generic for statement works over functions, +called iterators. +On each iteration, the iterator function is called to produce a new value, +stopping when this new value is nil. +The generic for loop has the following syntax: + +

+	stat ::= for namelist in explist do block end
+	namelist ::= Name {‘,’ Name}
+

+A for statement like + +

+     for var_1, ···, var_n in explist do block end
+

+is equivalent to the code: + +

+     do
+       local f, s, var = explist
+       while true do
+         local var_1, ···, var_n = f(s, var)
+         if var_1 == nil then break end
+         var = var_1
+         block
+       end
+     end
+

+Note the following: + +

    + +
  • +explist is evaluated only once. +Its results are an iterator function, +a state, +and an initial value for the first iterator variable. +
  • + +
  • +f, s, and var are invisible variables. +The names are here for explanatory purposes only. +
  • + +
  • +You can use break to exit a for loop. +
  • + +
  • +The loop variables var_i are local to the loop; +you cannot use their values after the for ends. +If you need these values, +then assign them to other variables before breaking or exiting the loop. +
  • + +
+ + + + +

3.3.6 – Function Calls as Statements

+To allow possible side-effects, +function calls can be executed as statements: + +

+	stat ::= functioncall
+

+In this case, all returned values are thrown away. +Function calls are explained in §3.4.9. + + + + + +

3.3.7 – Local Declarations

+Local variables can be declared anywhere inside a block. +The declaration can include an initial assignment: + +

+	stat ::= local namelist [‘=’ explist]
+

+If present, an initial assignment has the same semantics +of a multiple assignment (see §3.3.3). +Otherwise, all variables are initialized with nil. + + +

+A chunk is also a block (see §3.3.2), +and so local variables can be declared in a chunk outside any explicit block. + + +

+The visibility rules for local variables are explained in §3.5. + + + + + + + +

3.4 – Expressions

+ +

+The basic expressions in Lua are the following: + +

+	exp ::= prefixexp
+	exp ::= nil | false | true
+	exp ::= Number
+	exp ::= String
+	exp ::= functiondef
+	exp ::= tableconstructor
+	exp ::= ‘...’
+	exp ::= exp binop exp
+	exp ::= unop exp
+	prefixexp ::= var | functioncall | ‘(’ exp ‘)’
+
+ +

+Numbers and literal strings are explained in §3.1; +variables are explained in §3.2; +function definitions are explained in §3.4.10; +function calls are explained in §3.4.9; +table constructors are explained in §3.4.8. +Vararg expressions, +denoted by three dots ('...'), can only be used when +directly inside a vararg function; +they are explained in §3.4.10. + + +

+Binary operators comprise arithmetic operators (see §3.4.1), +relational operators (see §3.4.3), logical operators (see §3.4.4), +and the concatenation operator (see §3.4.5). +Unary operators comprise the unary minus (see §3.4.1), +the unary not (see §3.4.4), +and the unary length operator (see §3.4.6). + + +

+Both function calls and vararg expressions can result in multiple values. +If a function call is used as a statement (see §3.3.6), +then its return list is adjusted to zero elements, +thus discarding all returned values. +If an expression is used as the last (or the only) element +of a list of expressions, +then no adjustment is made +(unless the expression is enclosed in parentheses). +In all other contexts, +Lua adjusts the result list to one element, +either discarding all values except the first one +or adding a single nil if there are no values. + + +

+Here are some examples: + +

+     f()                -- adjusted to 0 results
+     g(f(), x)          -- f() is adjusted to 1 result
+     g(x, f())          -- g gets x plus all results from f()
+     a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
+     a,b = ...          -- a gets the first vararg parameter, b gets
+                        -- the second (both a and b can get nil if there
+                        -- is no corresponding vararg parameter)
+     
+     a,b,c = x, f()     -- f() is adjusted to 2 results
+     a,b,c = f()        -- f() is adjusted to 3 results
+     return f()         -- returns all results from f()
+     return ...         -- returns all received vararg parameters
+     return x,y,f()     -- returns x, y, and all results from f()
+     {f()}              -- creates a list with all results from f()
+     {...}              -- creates a list with all vararg parameters
+     {f(), nil}         -- f() is adjusted to 1 result
+
+ +

+Any expression enclosed in parentheses always results in only one value. +Thus, +(f(x,y,z)) is always a single value, +even if f returns several values. +(The value of (f(x,y,z)) is the first value returned by f +or nil if f does not return any values.) + + + +

3.4.1 – Arithmetic Operators

+Lua supports the usual arithmetic operators: +the binary + (addition), +- (subtraction), * (multiplication), +/ (division), % (modulo), and ^ (exponentiation); +and unary - (mathematical negation). +If the operands are numbers, or strings that can be converted to +numbers (see §3.4.2), +then all operations have the usual meaning. +Exponentiation works for any exponent. +For instance, x^(-0.5) computes the inverse of the square root of x. +Modulo is defined as + +

+     a % b == a - math.floor(a/b)*b
+

+That is, it is the remainder of a division that rounds +the quotient towards minus infinity. + + + + + +

3.4.2 – Coercion

+ +

+Lua provides automatic conversion between +string and number values at run time. +Any arithmetic operation applied to a string tries to convert +this string to a number, following the rules of the Lua lexer. +(The string may have leading and trailing spaces and a sign.) +Conversely, whenever a number is used where a string is expected, +the number is converted to a string, in a reasonable format. +For complete control over how numbers are converted to strings, +use the format function from the string library +(see string.format). + + + + + +

3.4.3 – Relational Operators

+The relational operators in Lua are + +

+     ==    ~=    <     >     <=    >=
+

+These operators always result in false or true. + + +

+Equality (==) first compares the type of its operands. +If the types are different, then the result is false. +Otherwise, the values of the operands are compared. +Numbers and strings are compared in the usual way. +Tables, userdata, and threads +are compared by reference: +two objects are considered equal only if they are the same object. +Every time you create a new object +(a table, userdata, or thread), +this new object is different from any previously existing object. +Closures with the same reference are always equal. +Closures with any detectable difference +(different behavior, different definition) are always different. + + +

+You can change the way that Lua compares tables and userdata +by using the "eq" metamethod (see §2.4). + + +

+The conversion rules of §3.4.2 +do not apply to equality comparisons. +Thus, "0"==0 evaluates to false, +and t[0] and t["0"] denote different +entries in a table. + + +

+The operator ~= is exactly the negation of equality (==). + + +

+The order operators work as follows. +If both arguments are numbers, then they are compared as such. +Otherwise, if both arguments are strings, +then their values are compared according to the current locale. +Otherwise, Lua tries to call the "lt" or the "le" +metamethod (see §2.4). +A comparison a > b is translated to b < a +and a >= b is translated to b <= a. + + + + + +

3.4.4 – Logical Operators

+The logical operators in Lua are +and, or, and not. +Like the control structures (see §3.3.4), +all logical operators consider both false and nil as false +and anything else as true. + + +

+The negation operator not always returns false or true. +The conjunction operator and returns its first argument +if this value is false or nil; +otherwise, and returns its second argument. +The disjunction operator or returns its first argument +if this value is different from nil and false; +otherwise, or returns its second argument. +Both and and or use short-cut evaluation; +that is, +the second operand is evaluated only if necessary. +Here are some examples: + +

+     10 or 20            --> 10
+     10 or error()       --> 10
+     nil or "a"          --> "a"
+     nil and 10          --> nil
+     false and error()   --> false
+     false and nil       --> false
+     false or nil        --> nil
+     10 and 20           --> 20
+

+(In this manual, +--> indicates the result of the preceding expression.) + + + + + +

3.4.5 – Concatenation

+The string concatenation operator in Lua is +denoted by two dots ('..'). +If both operands are strings or numbers, then they are converted to +strings according to the rules mentioned in §3.4.2. +Otherwise, the __concat metamethod is called (see §2.4). + + + + + +

3.4.6 – The Length Operator

+ +

+The length operator is denoted by the unary prefix operator #. +The length of a string is its number of bytes +(that is, the usual meaning of string length when each +character is one byte). + + +

+A program can modify the behavior of the length operator for +any value but strings through the __len metamethod (see §2.4). + + +

+Unless a __len metamethod is given, +the length of a table t is only defined if the +table is a sequence, +that is, +the set of its positive numeric keys is equal to {1..n} +for some integer n. +In that case, n is its length. +Note that a table like + +

+     {10, 20, nil, 40}
+

+is not a sequence, because it has the key 4 +but does not have the key 3. +(So, there is no n such that the set {1..n} is equal +to the set of positive numeric keys of that table.) +Note, however, that non-numeric keys do not interfere +with whether a table is a sequence. + + + + + +

3.4.7 – Precedence

+Operator precedence in Lua follows the table below, +from lower to higher priority: + +

+     or
+     and
+     <     >     <=    >=    ~=    ==
+     ..
+     +     -
+     *     /     %
+     not   #     - (unary)
+     ^
+

+As usual, +you can use parentheses to change the precedences of an expression. +The concatenation ('..') and exponentiation ('^') +operators are right associative. +All other binary operators are left associative. + + + + + +

3.4.8 – Table Constructors

+Table constructors are expressions that create tables. +Every time a constructor is evaluated, a new table is created. +A constructor can be used to create an empty table +or to create a table and initialize some of its fields. +The general syntax for constructors is + +

+	tableconstructor ::= ‘{’ [fieldlist] ‘}’
+	fieldlist ::= field {fieldsep field} [fieldsep]
+	field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
+	fieldsep ::= ‘,’ | ‘;’
+
+ +

+Each field of the form [exp1] = exp2 adds to the new table an entry +with key exp1 and value exp2. +A field of the form name = exp is equivalent to +["name"] = exp. +Finally, fields of the form exp are equivalent to +[i] = exp, where i are consecutive numerical integers, +starting with 1. +Fields in the other formats do not affect this counting. +For example, + +

+     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
+

+is equivalent to + +

+     do
+       local t = {}
+       t[f(1)] = g
+       t[1] = "x"         -- 1st exp
+       t[2] = "y"         -- 2nd exp
+       t.x = 1            -- t["x"] = 1
+       t[3] = f(x)        -- 3rd exp
+       t[30] = 23
+       t[4] = 45          -- 4th exp
+       a = t
+     end
+
+ +

+If the last field in the list has the form exp +and the expression is a function call or a vararg expression, +then all values returned by this expression enter the list consecutively +(see §3.4.9). + + +

+The field list can have an optional trailing separator, +as a convenience for machine-generated code. + + + + + +

3.4.9 – Function Calls

+A function call in Lua has the following syntax: + +

+	functioncall ::= prefixexp args
+

+In a function call, +first prefixexp and args are evaluated. +If the value of prefixexp has type function, +then this function is called +with the given arguments. +Otherwise, the prefixexp "call" metamethod is called, +having as first parameter the value of prefixexp, +followed by the original call arguments +(see §2.4). + + +

+The form + +

+	functioncall ::= prefixexp ‘:’ Name args
+

+can be used to call "methods". +A call v:name(args) +is syntactic sugar for v.name(v,args), +except that v is evaluated only once. + + +

+Arguments have the following syntax: + +

+	args ::= ‘(’ [explist] ‘)’
+	args ::= tableconstructor
+	args ::= String
+

+All argument expressions are evaluated before the call. +A call of the form f{fields} is +syntactic sugar for f({fields}); +that is, the argument list is a single new table. +A call of the form f'string' +(or f"string" or f[[string]]) +is syntactic sugar for f('string'); +that is, the argument list is a single literal string. + + +

+A call of the form return functioncall is called +a tail call. +Lua implements proper tail calls +(or proper tail recursion): +in a tail call, +the called function reuses the stack entry of the calling function. +Therefore, there is no limit on the number of nested tail calls that +a program can execute. +However, a tail call erases any debug information about the +calling function. +Note that a tail call only happens with a particular syntax, +where the return has one single function call as argument; +this syntax makes the calling function return exactly +the returns of the called function. +So, none of the following examples are tail calls: + +

+     return (f(x))        -- results adjusted to 1
+     return 2 * f(x)
+     return x, f(x)       -- additional results
+     f(x); return         -- results discarded
+     return x or f(x)     -- results adjusted to 1
+
+ + + + +

3.4.10 – Function Definitions

+ +

+The syntax for function definition is + +

+	functiondef ::= function funcbody
+	funcbody ::= ‘(’ [parlist] ‘)’ block end
+
+ +

+The following syntactic sugar simplifies function definitions: + +

+	stat ::= function funcname funcbody
+	stat ::= local function Name funcbody
+	funcname ::= Name {‘.’ Name} [‘:’ Name]
+

+The statement + +

+     function f () body end
+

+translates to + +

+     f = function () body end
+

+The statement + +

+     function t.a.b.c.f () body end
+

+translates to + +

+     t.a.b.c.f = function () body end
+

+The statement + +

+     local function f () body end
+

+translates to + +

+     local f; f = function () body end
+

+not to + +

+     local f = function () body end
+

+(This only makes a difference when the body of the function +contains references to f.) + + +

+A function definition is an executable expression, +whose value has type function. +When Lua precompiles a chunk, +all its function bodies are precompiled too. +Then, whenever Lua executes the function definition, +the function is instantiated (or closed). +This function instance (or closure) +is the final value of the expression. + + +

+Parameters act as local variables that are +initialized with the argument values: + +

+	parlist ::= namelist [‘,’ ‘...’] | ‘...’
+

+When a function is called, +the list of arguments is adjusted to +the length of the list of parameters, +unless the function is a vararg function, +which is indicated by three dots ('...') +at the end of its parameter list. +A vararg function does not adjust its argument list; +instead, it collects all extra arguments and supplies them +to the function through a vararg expression, +which is also written as three dots. +The value of this expression is a list of all actual extra arguments, +similar to a function with multiple results. +If a vararg expression is used inside another expression +or in the middle of a list of expressions, +then its return list is adjusted to one element. +If the expression is used as the last element of a list of expressions, +then no adjustment is made +(unless that last expression is enclosed in parentheses). + + +

+As an example, consider the following definitions: + +

+     function f(a, b) end
+     function g(a, b, ...) end
+     function r() return 1,2,3 end
+

+Then, we have the following mapping from arguments to parameters and +to the vararg expression: + +

+     CALL            PARAMETERS
+     
+     f(3)             a=3, b=nil
+     f(3, 4)          a=3, b=4
+     f(3, 4, 5)       a=3, b=4
+     f(r(), 10)       a=1, b=10
+     f(r())           a=1, b=2
+     
+     g(3)             a=3, b=nil, ... -->  (nothing)
+     g(3, 4)          a=3, b=4,   ... -->  (nothing)
+     g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
+     g(5, r())        a=5, b=1,   ... -->  2  3
+
+ +

+Results are returned using the return statement (see §3.3.4). +If control reaches the end of a function +without encountering a return statement, +then the function returns with no results. + + +

+ +There is a system-dependent limit on the number of values +that a function may return. +This limit is guaranteed to be larger than 1000. + + +

+The colon syntax +is used for defining methods, +that is, functions that have an implicit extra parameter self. +Thus, the statement + +

+     function t.a.b.c:f (params) body end
+

+is syntactic sugar for + +

+     t.a.b.c.f = function (self, params) body end
+
+ + + + + + +

3.5 – Visibility Rules

+ +

+ +Lua is a lexically scoped language. +The scope of a local variable begins at the first statement after +its declaration and lasts until the last non-void statement +of the innermost block that includes the declaration. +Consider the following example: + +

+     x = 10                -- global variable
+     do                    -- new block
+       local x = x         -- new 'x', with value 10
+       print(x)            --> 10
+       x = x+1
+       do                  -- another block
+         local x = x+1     -- another 'x'
+         print(x)          --> 12
+       end
+       print(x)            --> 11
+     end
+     print(x)              --> 10  (the global one)
+
+ +

+Notice that, in a declaration like local x = x, +the new x being declared is not in scope yet, +and so the second x refers to the outside variable. + + +

+Because of the lexical scoping rules, +local variables can be freely accessed by functions +defined inside their scope. +A local variable used by an inner function is called +an upvalue, or external local variable, +inside the inner function. + + +

+Notice that each execution of a local statement +defines new local variables. +Consider the following example: + +

+     a = {}
+     local x = 20
+     for i=1,10 do
+       local y = 0
+       a[i] = function () y=y+1; return x+y end
+     end
+

+The loop creates ten closures +(that is, ten instances of the anonymous function). +Each of these closures uses a different y variable, +while all of them share the same x. + + + + + +

4 – The Application Program Interface

+ +

+ +This section describes the C API for Lua, that is, +the set of C functions available to the host program to communicate +with Lua. +All API functions and related types and constants +are declared in the header file lua.h. + + +

+Even when we use the term "function", +any facility in the API may be provided as a macro instead. +Except where stated otherwise, +all such macros use each of their arguments exactly once +(except for the first argument, which is always a Lua state), +and so do not generate any hidden side-effects. + + +

+As in most C libraries, +the Lua API functions do not check their arguments for validity or consistency. +However, you can change this behavior by compiling Lua +with the macro LUA_USE_APICHECK defined. + + + +

4.1 – The Stack

+ +

+Lua uses a virtual stack to pass values to and from C. +Each element in this stack represents a Lua value +(nil, number, string, etc.). + + +

+Whenever Lua calls C, the called function gets a new stack, +which is independent of previous stacks and of stacks of +C functions that are still active. +This stack initially contains any arguments to the C function +and it is where the C function pushes its results +to be returned to the caller (see lua_CFunction). + + +

+For convenience, +most query operations in the API do not follow a strict stack discipline. +Instead, they can refer to any element in the stack +by using an index: +A positive index represents an absolute stack position +(starting at 1); +a negative index represents an offset relative to the top of the stack. +More specifically, if the stack has n elements, +then index 1 represents the first element +(that is, the element that was pushed onto the stack first) +and +index n represents the last element; +index -1 also represents the last element +(that is, the element at the top) +and index -n represents the first element. + + + + + +

4.2 – Stack Size

+ +

+When you interact with the Lua API, +you are responsible for ensuring consistency. +In particular, +you are responsible for controlling stack overflow. +You can use the function lua_checkstack +to ensure that the stack has extra slots when pushing new elements. + + +

+Whenever Lua calls C, +it ensures that the stack has at least LUA_MINSTACK extra slots. +LUA_MINSTACK is defined as 20, +so that usually you do not have to worry about stack space +unless your code has loops pushing elements onto the stack. + + +

+When you call a Lua function +without a fixed number of results (see lua_call), +Lua ensures that the stack has enough size for all results, +but it does not ensure any extra space. +So, before pushing anything in the stack after such a call +you should use lua_checkstack. + + + + + +

4.3 – Valid and Acceptable Indices

+ +

+Any function in the API that receives stack indices +works only with valid indices or acceptable indices. + + +

+A valid index is an index that refers to a +real position within the stack, that is, +its position lies between 1 and the stack top +(1 ≤ abs(index) ≤ top). + +Usually, functions that can modify the value at an index +require valid indices. + + +

+Unless otherwise noted, +any function that accepts valid indices also accepts pseudo-indices, +which represent some Lua values that are accessible to C code +but which are not in the stack. +Pseudo-indices are used to access the registry +and the upvalues of a C function (see §4.4). + + +

+Functions that do not need a specific stack position, +but only a value in the stack (e.g., query functions), +can be called with acceptable indices. +An acceptable index can be any valid index, +including the pseudo-indices, +but it also can be any positive index after the stack top +within the space allocated for the stack, +that is, indices up to the stack size. +(Note that 0 is never an acceptable index.) +Except when noted otherwise, +functions in the API work with acceptable indices. + + +

+Acceptable indices serve to avoid extra tests +against the stack top when querying the stack. +For instance, a C function can query its third argument +without the need to first check whether there is a third argument, +that is, without the need to check whether 3 is a valid index. + + +

+For functions that can be called with acceptable indices, +any non-valid index is treated as if it +contains a value of a virtual type LUA_TNONE, +which behaves like a nil value. + + + + + +

4.4 – C Closures

+ +

+When a C function is created, +it is possible to associate some values with it, +thus creating a C closure +(see lua_pushcclosure); +these values are called upvalues and are +accessible to the function whenever it is called. + + +

+Whenever a C function is called, +its upvalues are located at specific pseudo-indices. +These pseudo-indices are produced by the macro +lua_upvalueindex. +The first value associated with a function is at position +lua_upvalueindex(1), and so on. +Any access to lua_upvalueindex(n), +where n is greater than the number of upvalues of the +current function (but not greater than 256), +produces an acceptable but invalid index. + + + + + +

4.5 – Registry

+ +

+Lua provides a registry, +a predefined table that can be used by any C code to +store whatever Lua values it needs to store. +The registry table is always located at pseudo-index +LUA_REGISTRYINDEX, +which is a valid index. +Any C library can store data into this table, +but it should take care to choose keys +that are different from those used +by other libraries, to avoid collisions. +Typically, you should use as key a string containing your library name, +or a light userdata with the address of a C object in your code, +or any Lua object created by your code. +As with global names, +string keys starting with an underscore followed by +uppercase letters are reserved for Lua. + + +

+The integer keys in the registry are used by the reference mechanism, +implemented by the auxiliary library, +and by some predefined values. +Therefore, integer keys should not be used for other purposes. + + +

+When you create a new Lua state, +its registry comes with some predefined values. +These predefined values are indexed with integer keys +defined as constants in lua.h. +The following constants are defined: + +

    +
  • LUA_RIDX_MAINTHREAD: At this index the registry has +the main thread of the state. +(The main thread is the one created together with the state.) +
  • + +
  • LUA_RIDX_GLOBALS: At this index the registry has +the global environment. +
  • +
+ + + + +

4.6 – Error Handling in C

+ +

+Internally, Lua uses the C longjmp facility to handle errors. +(You can also choose to use exceptions if you compile Lua as C++; +search for LUAI_THROW in the source code.) +When Lua faces any error +(such as a memory allocation error, type errors, syntax errors, +and runtime errors) +it raises an error; +that is, it does a long jump. +A protected environment uses setjmp +to set a recovery point; +any error jumps to the most recent active recovery point. + + +

+If an error happens outside any protected environment, +Lua calls a panic function (see lua_atpanic) +and then calls abort, +thus exiting the host application. +Your panic function can avoid this exit by +never returning +(e.g., doing a long jump to your own recovery point outside Lua). + + +

+The panic function runs as if it were a message handler (see §2.3); +in particular, the error message is at the top of the stack. +However, there is no guarantees about stack space. +To push anything on the stack, +the panic function should first check the available space (see §4.2). + + +

+Most functions in the API can throw an error, +for instance due to a memory allocation error. +The documentation for each function indicates whether +it can throw errors. + + +

+Inside a C function you can throw an error by calling lua_error. + + + + + +

4.7 – Handling Yields in C

+ +

+Internally, Lua uses the C longjmp facility to yield a coroutine. +Therefore, if a function foo calls an API function +and this API function yields +(directly or indirectly by calling another function that yields), +Lua cannot return to foo any more, +because the longjmp removes its frame from the C stack. + + +

+To avoid this kind of problem, +Lua raises an error whenever it tries to yield across an API call, +except for three functions: +lua_yieldk, lua_callk, and lua_pcallk. +All those functions receive a continuation function +(as a parameter called k) to continue execution after a yield. + + +

+We need to set some terminology to explain continuations. +We have a C function called from Lua which we will call +the original function. +This original function then calls one of those three functions in the C API, +which we will call the callee function, +that then yields the current thread. +(This can happen when the callee function is lua_yieldk, +or when the callee function is either lua_callk or lua_pcallk +and the function called by them yields.) + + +

+Suppose the running thread yields while executing the callee function. +After the thread resumes, +it eventually will finish running the callee function. +However, +the callee function cannot return to the original function, +because its frame in the C stack was destroyed by the yield. +Instead, Lua calls a continuation function, +which was given as an argument to the callee function. +As the name implies, +the continuation function should continue the task +of the original function. + + +

+Lua treats the continuation function as if it were the original function. +The continuation function receives the same Lua stack +from the original function, +in the same state it would be if the callee function had returned. +(For instance, +after a lua_callk the function and its arguments are +removed from the stack and replaced by the results from the call.) +It also has the same upvalues. +Whatever it returns is handled by Lua as if it were the return +of the original function. + + +

+The only difference in the Lua state between the original function +and its continuation is the result of a call to lua_getctx. + + + + + +

4.8 – Functions and Types

+ +

+Here we list all functions and types from the C API in +alphabetical order. +Each function has an indicator like this: +[-o, +p, x] + + +

+The first field, o, +is how many elements the function pops from the stack. +The second field, p, +is how many elements the function pushes onto the stack. +(Any function always pushes its results after popping its arguments.) +A field in the form x|y means the function can push (or pop) +x or y elements, +depending on the situation; +an interrogation mark '?' means that +we cannot know how many elements the function pops/pushes +by looking only at its arguments +(e.g., they may depend on what is on the stack). +The third field, x, +tells whether the function may throw errors: +'-' means the function never throws any error; +'e' means the function may throw errors; +'v' means the function may throw an error on purpose. + + + +


lua_absindex

+[-0, +0, –] +

int lua_absindex (lua_State *L, int idx);
+ +

+Converts the acceptable index idx into an absolute index +(that is, one that does not depend on the stack top). + + + + + +


lua_Alloc

+
typedef void * (*lua_Alloc) (void *ud,
+                             void *ptr,
+                             size_t osize,
+                             size_t nsize);
+ +

+The type of the memory-allocation function used by Lua states. +The allocator function must provide a +functionality similar to realloc, +but not exactly the same. +Its arguments are +ud, an opaque pointer passed to lua_newstate; +ptr, a pointer to the block being allocated/reallocated/freed; +osize, the original size of the block or some code about what +is being allocated; +nsize, the new size of the block. + + +

+When ptr is not NULL, +osize is the size of the block pointed by ptr, +that is, the size given when it was allocated or reallocated. + + +

+When ptr is NULL, +osize encodes the kind of object that Lua is allocating. +osize is any of +LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, +LUA_TUSERDATA, or LUA_TTHREAD when (and only when) +Lua is creating a new object of that type. +When osize is some other value, +Lua is allocating memory for something else. + + +

+Lua assumes the following behavior from the allocator function: + + +

+When nsize is zero, +the allocator should behave like free +and return NULL. + + +

+When nsize is not zero, +the allocator should behave like realloc. +The allocator returns NULL +if and only if it cannot fulfill the request. +Lua assumes that the allocator never fails when +osize >= nsize. + + +

+Here is a simple implementation for the allocator function. +It is used in the auxiliary library by luaL_newstate. + +

+     static void *l_alloc (void *ud, void *ptr, size_t osize,
+                                                size_t nsize) {
+       (void)ud;  (void)osize;  /* not used */
+       if (nsize == 0) {
+         free(ptr);
+         return NULL;
+       }
+       else
+         return realloc(ptr, nsize);
+     }
+

+Note that Standard C ensures +that free(NULL) has no effect and that +realloc(NULL, size) is equivalent to malloc(size). +This code assumes that realloc does not fail when shrinking a block. +(Although Standard C does not ensure this behavior, +it seems to be a safe assumption.) + + + + + +


lua_arith

+[-(2|1), +1, e] +

void lua_arith (lua_State *L, int op);
+ +

+Performs an arithmetic operation over the two values +(or one, in the case of negation) +at the top of the stack, +with the value at the top being the second operand, +pops these values, and pushes the result of the operation. +The function follows the semantics of the corresponding Lua operator +(that is, it may call metamethods). + + +

+The value of op must be one of the following constants: + +

+ + + + +

lua_atpanic

+[-0, +0, –] +

lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
+ +

+Sets a new panic function and returns the old one (see §4.6). + + + + + +


lua_call

+[-(nargs+1), +nresults, e] +

void lua_call (lua_State *L, int nargs, int nresults);
+ +

+Calls a function. + + +

+To call a function you must use the following protocol: +first, the function to be called is pushed onto the stack; +then, the arguments to the function are pushed +in direct order; +that is, the first argument is pushed first. +Finally you call lua_call; +nargs is the number of arguments that you pushed onto the stack. +All arguments and the function value are popped from the stack +when the function is called. +The function results are pushed onto the stack when the function returns. +The number of results is adjusted to nresults, +unless nresults is LUA_MULTRET. +In this case, all results from the function are pushed. +Lua takes care that the returned values fit into the stack space. +The function results are pushed onto the stack in direct order +(the first result is pushed first), +so that after the call the last result is on the top of the stack. + + +

+Any error inside the called function is propagated upwards +(with a longjmp). + + +

+The following example shows how the host program can do the +equivalent to this Lua code: + +

+     a = f("how", t.x, 14)
+

+Here it is in C: + +

+     lua_getglobal(L, "f");                  /* function to be called */
+     lua_pushstring(L, "how");                        /* 1st argument */
+     lua_getglobal(L, "t");                    /* table to be indexed */
+     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
+     lua_remove(L, -2);                  /* remove 't' from the stack */
+     lua_pushinteger(L, 14);                          /* 3rd argument */
+     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
+     lua_setglobal(L, "a");                         /* set global 'a' */
+

+Note that the code above is "balanced": +at its end, the stack is back to its original configuration. +This is considered good programming practice. + + + + + +


lua_callk

+[-(nargs + 1), +nresults, e] +

void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
+                lua_CFunction k);
+ +

+This function behaves exactly like lua_call, +but allows the called function to yield (see §4.7). + + + + + +


lua_CFunction

+
typedef int (*lua_CFunction) (lua_State *L);
+ +

+Type for C functions. + + +

+In order to communicate properly with Lua, +a C function must use the following protocol, +which defines the way parameters and results are passed: +a C function receives its arguments from Lua in its stack +in direct order (the first argument is pushed first). +So, when the function starts, +lua_gettop(L) returns the number of arguments received by the function. +The first argument (if any) is at index 1 +and its last argument is at index lua_gettop(L). +To return values to Lua, a C function just pushes them onto the stack, +in direct order (the first result is pushed first), +and returns the number of results. +Any other value in the stack below the results will be properly +discarded by Lua. +Like a Lua function, a C function called by Lua can also return +many results. + + +

+As an example, the following function receives a variable number +of numerical arguments and returns their average and sum: + +

+     static int foo (lua_State *L) {
+       int n = lua_gettop(L);    /* number of arguments */
+       lua_Number sum = 0;
+       int i;
+       for (i = 1; i <= n; i++) {
+         if (!lua_isnumber(L, i)) {
+           lua_pushstring(L, "incorrect argument");
+           lua_error(L);
+         }
+         sum += lua_tonumber(L, i);
+       }
+       lua_pushnumber(L, sum/n);        /* first result */
+       lua_pushnumber(L, sum);         /* second result */
+       return 2;                   /* number of results */
+     }
+
+ + + + +

lua_checkstack

+[-0, +0, –] +

int lua_checkstack (lua_State *L, int extra);
+ +

+Ensures that there are at least extra free stack slots in the stack. +It returns false if it cannot fulfill the request, +because it would cause the stack to be larger than a fixed maximum size +(typically at least a few thousand elements) or +because it cannot allocate memory for the new stack size. +This function never shrinks the stack; +if the stack is already larger than the new size, +it is left unchanged. + + + + + +


lua_close

+[-0, +0, –] +

void lua_close (lua_State *L);
+ +

+Destroys all objects in the given Lua state +(calling the corresponding garbage-collection metamethods, if any) +and frees all dynamic memory used by this state. +On several platforms, you may not need to call this function, +because all resources are naturally released when the host program ends. +On the other hand, long-running programs that create multiple states, +such as daemons or web servers, +might need to close states as soon as they are not needed. + + + + + +


lua_compare

+[-0, +0, e] +

int lua_compare (lua_State *L, int index1, int index2, int op);
+ +

+Compares two Lua values. +Returns 1 if the value at index index1 satisfies op +when compared with the value at index index2, +following the semantics of the corresponding Lua operator +(that is, it may call metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices is non valid. + + +

+The value of op must be one of the following constants: + +

    + +
  • LUA_OPEQ: compares for equality (==)
  • +
  • LUA_OPLT: compares for less than (<)
  • +
  • LUA_OPLE: compares for less or equal (<=)
  • + +
+ + + + +

lua_concat

+[-n, +1, e] +

void lua_concat (lua_State *L, int n);
+ +

+Concatenates the n values at the top of the stack, +pops them, and leaves the result at the top. +If n is 1, the result is the single value on the stack +(that is, the function does nothing); +if n is 0, the result is the empty string. +Concatenation is performed following the usual semantics of Lua +(see §3.4.5). + + + + + +


lua_copy

+[-0, +0, –] +

void lua_copy (lua_State *L, int fromidx, int toidx);
+ +

+Moves the element at index fromidx +into the valid index toidx +without shifting any element +(therefore replacing the value at that position). + + + + + +


lua_createtable

+[-0, +1, e] +

void lua_createtable (lua_State *L, int narr, int nrec);
+ +

+Creates a new empty table and pushes it onto the stack. +Parameter narr is a hint for how many elements the table +will have as a sequence; +parameter nrec is a hint for how many other elements +the table will have. +Lua may use these hints to preallocate memory for the new table. +This pre-allocation is useful for performance when you know in advance +how many elements the table will have. +Otherwise you can use the function lua_newtable. + + + + + +


lua_dump

+[-0, +0, e] +

int lua_dump (lua_State *L, lua_Writer writer, void *data);
+ +

+Dumps a function as a binary chunk. +Receives a Lua function on the top of the stack +and produces a binary chunk that, +if loaded again, +results in a function equivalent to the one dumped. +As it produces parts of the chunk, +lua_dump calls function writer (see lua_Writer) +with the given data +to write them. + + +

+The value returned is the error code returned by the last +call to the writer; +0 means no errors. + + +

+This function does not pop the Lua function from the stack. + + + + + +


lua_error

+[-1, +0, v] +

int lua_error (lua_State *L);
+ +

+Generates a Lua error. +The error message (which can actually be a Lua value of any type) +must be on the stack top. +This function does a long jump, +and therefore never returns +(see luaL_error). + + + + + +


lua_gc

+[-0, +0, e] +

int lua_gc (lua_State *L, int what, int data);
+ +

+Controls the garbage collector. + + +

+This function performs several tasks, +according to the value of the parameter what: + +

    + +
  • LUA_GCSTOP: +stops the garbage collector. +
  • + +
  • LUA_GCRESTART: +restarts the garbage collector. +
  • + +
  • LUA_GCCOLLECT: +performs a full garbage-collection cycle. +
  • + +
  • LUA_GCCOUNT: +returns the current amount of memory (in Kbytes) in use by Lua. +
  • + +
  • LUA_GCCOUNTB: +returns the remainder of dividing the current amount of bytes of +memory in use by Lua by 1024. +
  • + +
  • LUA_GCSTEP: +performs an incremental step of garbage collection. +The step "size" is controlled by data +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of data. +The function returns 1 if the step finished a +garbage-collection cycle. +
  • + +
  • LUA_GCSETPAUSE: +sets data as the new value +for the pause of the collector (see §2.5). +The function returns the previous value of the pause. +
  • + +
  • LUA_GCSETSTEPMUL: +sets data as the new value for the step multiplier of +the collector (see §2.5). +The function returns the previous value of the step multiplier. +
  • + +
  • LUA_GCISRUNNING: +returns a boolean that tells whether the collector is running +(i.e., not stopped). +
  • + +
  • LUA_GCGEN: +changes the collector to generational mode +(see §2.5). +
  • + +
  • LUA_GCINC: +changes the collector to incremental mode. +This is the default mode. +
  • + +
+ +

+For more details about these options, +see collectgarbage. + + + + + +


lua_getallocf

+[-0, +0, –] +

lua_Alloc lua_getallocf (lua_State *L, void **ud);
+ +

+Returns the memory-allocation function of a given state. +If ud is not NULL, Lua stores in *ud the +opaque pointer passed to lua_newstate. + + + + + +


lua_getctx

+[-0, +0, –] +

int lua_getctx (lua_State *L, int *ctx);
+ +

+This function is called by a continuation function (see §4.7) +to retrieve the status of the thread and a context information. + + +

+When called in the original function, +lua_getctx always returns LUA_OK +and does not change the value of its argument ctx. +When called inside a continuation function, +lua_getctx returns LUA_YIELD and sets +the value of ctx to be the context information +(the value passed as the ctx argument +to the callee together with the continuation function). + + +

+When the callee is lua_pcallk, +Lua may also call its continuation function +to handle errors during the call. +That is, upon an error in the function called by lua_pcallk, +Lua may not return to the original function +but instead may call the continuation function. +In that case, a call to lua_getctx will return the error code +(the value that would be returned by lua_pcallk); +the value of ctx will be set to the context information, +as in the case of a yield. + + + + + +


lua_getfield

+[-0, +1, e] +

void lua_getfield (lua_State *L, int index, const char *k);
+ +

+Pushes onto the stack the value t[k], +where t is the value at the given index. +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.4). + + + + + +


lua_getglobal

+[-0, +1, e] +

void lua_getglobal (lua_State *L, const char *name);
+ +

+Pushes onto the stack the value of the global name. + + + + + +


lua_getmetatable

+[-0, +(0|1), –] +

int lua_getmetatable (lua_State *L, int index);
+ +

+Pushes onto the stack the metatable of the value at the given index. +If the value does not have a metatable, +the function returns 0 and pushes nothing on the stack. + + + + + +


lua_gettable

+[-1, +1, e] +

void lua_gettable (lua_State *L, int index);
+ +

+Pushes onto the stack the value t[k], +where t is the value at the given index +and k is the value at the top of the stack. + + +

+This function pops the key from the stack +(putting the resulting value in its place). +As in Lua, this function may trigger a metamethod +for the "index" event (see §2.4). + + + + + +


lua_gettop

+[-0, +0, –] +

int lua_gettop (lua_State *L);
+ +

+Returns the index of the top element in the stack. +Because indices start at 1, +this result is equal to the number of elements in the stack +(and so 0 means an empty stack). + + + + + +


lua_getuservalue

+[-0, +1, –] +

void lua_getuservalue (lua_State *L, int index);
+ +

+Pushes onto the stack the Lua value associated with the userdata +at the given index. +This Lua value must be a table or nil. + + + + + +


lua_insert

+[-1, +1, –] +

void lua_insert (lua_State *L, int index);
+ +

+Moves the top element into the given valid index, +shifting up the elements above this index to open space. +This function cannot be called with a pseudo-index, +because a pseudo-index is not an actual stack position. + + + + + +


lua_Integer

+
typedef ptrdiff_t lua_Integer;
+ +

+The type used by the Lua API to represent signed integral values. + + +

+By default it is a ptrdiff_t, +which is usually the largest signed integral type the machine handles +"comfortably". + + + + + +


lua_isboolean

+[-0, +0, –] +

int lua_isboolean (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a boolean, +and 0 otherwise. + + + + + +


lua_iscfunction

+[-0, +0, –] +

int lua_iscfunction (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a C function, +and 0 otherwise. + + + + + +


lua_isfunction

+[-0, +0, –] +

int lua_isfunction (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a function +(either C or Lua), and 0 otherwise. + + + + + +


lua_islightuserdata

+[-0, +0, –] +

int lua_islightuserdata (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a light userdata, +and 0 otherwise. + + + + + +


lua_isnil

+[-0, +0, –] +

int lua_isnil (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is nil, +and 0 otherwise. + + + + + +


lua_isnone

+[-0, +0, –] +

int lua_isnone (lua_State *L, int index);
+ +

+Returns 1 if the given index is not valid, +and 0 otherwise. + + + + + +


lua_isnoneornil

+[-0, +0, –] +

int lua_isnoneornil (lua_State *L, int index);
+ +

+Returns 1 if the given index is not valid +or if the value at this index is nil, +and 0 otherwise. + + + + + +


lua_isnumber

+[-0, +0, –] +

int lua_isnumber (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a number +or a string convertible to a number, +and 0 otherwise. + + + + + +


lua_isstring

+[-0, +0, –] +

int lua_isstring (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a string +or a number (which is always convertible to a string), +and 0 otherwise. + + + + + +


lua_istable

+[-0, +0, –] +

int lua_istable (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a table, +and 0 otherwise. + + + + + +


lua_isthread

+[-0, +0, –] +

int lua_isthread (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a thread, +and 0 otherwise. + + + + + +


lua_isuserdata

+[-0, +0, –] +

int lua_isuserdata (lua_State *L, int index);
+ +

+Returns 1 if the value at the given index is a userdata +(either full or light), and 0 otherwise. + + + + + +


lua_len

+[-0, +1, e] +

void lua_len (lua_State *L, int index);
+ +

+Returns the "length" of the value at the given index; +it is equivalent to the '#' operator in Lua (see §3.4.6). +The result is pushed on the stack. + + + + + +


lua_load

+[-0, +1, –] +

int lua_load (lua_State *L,
+              lua_Reader reader,
+              void *data,
+              const char *source,
+              const char *mode);
+ +

+Loads a Lua chunk (without running it). +If there are no errors, +lua_load pushes the compiled chunk as a Lua +function on top of the stack. +Otherwise, it pushes an error message. + + +

+The return values of lua_load are: + +

    + +
  • LUA_OK: no errors;
  • + +
  • LUA_ERRSYNTAX: +syntax error during precompilation;
  • + +
  • LUA_ERRMEM: +memory allocation error;
  • + +
  • LUA_ERRGCMM: +error while running a __gc metamethod. +(This error has no relation with the chunk being loaded. +It is generated by the garbage collector.) +
  • + +
+ +

+The lua_load function uses a user-supplied reader function +to read the chunk (see lua_Reader). +The data argument is an opaque value passed to the reader function. + + +

+The source argument gives a name to the chunk, +which is used for error messages and in debug information (see §4.9). + + +

+lua_load automatically detects whether the chunk is text or binary +and loads it accordingly (see program luac). +The string mode works as in function load, +with the addition that +a NULL value is equivalent to the string "bt". + + +

+lua_load uses the stack internally, +so the reader function should always leave the stack +unmodified when returning. + + +

+If the resulting function has one upvalue, +this upvalue is set to the value of the global environment +stored at index LUA_RIDX_GLOBALS in the registry (see §4.5). +When loading main chunks, +this upvalue will be the _ENV variable (see §2.2). + + + + + +


lua_newstate

+[-0, +0, –] +

lua_State *lua_newstate (lua_Alloc f, void *ud);
+ +

+Creates a new thread running in a new, independent state. +Returns NULL if cannot create the thread or the state +(due to lack of memory). +The argument f is the allocator function; +Lua does all memory allocation for this state through this function. +The second argument, ud, is an opaque pointer that Lua +passes to the allocator in every call. + + + + + +


lua_newtable

+[-0, +1, e] +

void lua_newtable (lua_State *L);
+ +

+Creates a new empty table and pushes it onto the stack. +It is equivalent to lua_createtable(L, 0, 0). + + + + + +


lua_newthread

+[-0, +1, e] +

lua_State *lua_newthread (lua_State *L);
+ +

+Creates a new thread, pushes it on the stack, +and returns a pointer to a lua_State that represents this new thread. +The new thread returned by this function shares with the original thread +its global environment, +but has an independent execution stack. + + +

+There is no explicit function to close or to destroy a thread. +Threads are subject to garbage collection, +like any Lua object. + + + + + +


lua_newuserdata

+[-0, +1, e] +

void *lua_newuserdata (lua_State *L, size_t size);
+ +

+This function allocates a new block of memory with the given size, +pushes onto the stack a new full userdata with the block address, +and returns this address. +The host program can freely use this memory. + + + + + +


lua_next

+[-1, +(2|0), e] +

int lua_next (lua_State *L, int index);
+ +

+Pops a key from the stack, +and pushes a key–value pair from the table at the given index +(the "next" pair after the given key). +If there are no more elements in the table, +then lua_next returns 0 (and pushes nothing). + + +

+A typical traversal looks like this: + +

+     /* table is in the stack at index 't' */
+     lua_pushnil(L);  /* first key */
+     while (lua_next(L, t) != 0) {
+       /* uses 'key' (at index -2) and 'value' (at index -1) */
+       printf("%s - %s\n",
+              lua_typename(L, lua_type(L, -2)),
+              lua_typename(L, lua_type(L, -1)));
+       /* removes 'value'; keeps 'key' for next iteration */
+       lua_pop(L, 1);
+     }
+
+ +

+While traversing a table, +do not call lua_tolstring directly on a key, +unless you know that the key is actually a string. +Recall that lua_tolstring may change +the value at the given index; +this confuses the next call to lua_next. + + +

+See function next for the caveats of modifying +the table during its traversal. + + + + + +


lua_Number

+
typedef double lua_Number;
+ +

+The type of numbers in Lua. +By default, it is double, but that can be changed in luaconf.h. +Through this configuration file you can change +Lua to operate with another type for numbers (e.g., float or long). + + + + + +


lua_pcall

+[-(nargs + 1), +(nresults|1), –] +

int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
+ +

+Calls a function in protected mode. + + +

+Both nargs and nresults have the same meaning as +in lua_call. +If there are no errors during the call, +lua_pcall behaves exactly like lua_call. +However, if there is any error, +lua_pcall catches it, +pushes a single value on the stack (the error message), +and returns an error code. +Like lua_call, +lua_pcall always removes the function +and its arguments from the stack. + + +

+If msgh is 0, +then the error message returned on the stack +is exactly the original error message. +Otherwise, msgh is the stack index of a +message handler. +(In the current implementation, this index cannot be a pseudo-index.) +In case of runtime errors, +this function will be called with the error message +and its return value will be the message +returned on the stack by lua_pcall. + + +

+Typically, the message handler is used to add more debug +information to the error message, such as a stack traceback. +Such information cannot be gathered after the return of lua_pcall, +since by then the stack has unwound. + + +

+The lua_pcall function returns one of the following codes +(defined in lua.h): + +

    + +
  • LUA_OK (0): +success.
  • + +
  • LUA_ERRRUN: +a runtime error. +
  • + +
  • LUA_ERRMEM: +memory allocation error. +For such errors, Lua does not call the message handler. +
  • + +
  • LUA_ERRERR: +error while running the message handler. +
  • + +
  • LUA_ERRGCMM: +error while running a __gc metamethod. +(This error typically has no relation with the function being called. +It is generated by the garbage collector.) +
  • + +
+ + + + +

lua_pcallk

+[-(nargs + 1), +(nresults|1), –] +

int lua_pcallk (lua_State *L,
+                int nargs,
+                int nresults,
+                int errfunc,
+                int ctx,
+                lua_CFunction k);
+ +

+This function behaves exactly like lua_pcall, +but allows the called function to yield (see §4.7). + + + + + +


lua_pop

+[-n, +0, –] +

void lua_pop (lua_State *L, int n);
+ +

+Pops n elements from the stack. + + + + + +


lua_pushboolean

+[-0, +1, –] +

void lua_pushboolean (lua_State *L, int b);
+ +

+Pushes a boolean value with value b onto the stack. + + + + + +


lua_pushcclosure

+[-n, +1, e] +

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
+ +

+Pushes a new C closure onto the stack. + + +

+When a C function is created, +it is possible to associate some values with it, +thus creating a C closure (see §4.4); +these values are then accessible to the function whenever it is called. +To associate values with a C function, +first these values should be pushed onto the stack +(when there are multiple values, the first value is pushed first). +Then lua_pushcclosure +is called to create and push the C function onto the stack, +with the argument n telling how many values should be +associated with the function. +lua_pushcclosure also pops these values from the stack. + + +

+The maximum value for n is 255. + + +

+When n is zero, +this function creates a light C function, +which is just a pointer to the C function. +In that case, it never throws a memory error. + + + + + +


lua_pushcfunction

+[-0, +1, –] +

void lua_pushcfunction (lua_State *L, lua_CFunction f);
+ +

+Pushes a C function onto the stack. +This function receives a pointer to a C function +and pushes onto the stack a Lua value of type function that, +when called, invokes the corresponding C function. + + +

+Any function to be registered in Lua must +follow the correct protocol to receive its parameters +and return its results (see lua_CFunction). + + +

+lua_pushcfunction is defined as a macro: + +

+     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
+

+Note that f is used twice. + + + + + +


lua_pushfstring

+[-0, +1, e] +

const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
+ +

+Pushes onto the stack a formatted string +and returns a pointer to this string. +It is similar to the ANSI C function sprintf, +but has some important differences: + +

    + +
  • +You do not have to allocate space for the result: +the result is a Lua string and Lua takes care of memory allocation +(and deallocation, through garbage collection). +
  • + +
  • +The conversion specifiers are quite restricted. +There are no flags, widths, or precisions. +The conversion specifiers can only be +'%%' (inserts a '%' in the string), +'%s' (inserts a zero-terminated string, with no size restrictions), +'%f' (inserts a lua_Number), +'%p' (inserts a pointer as a hexadecimal numeral), +'%d' (inserts an int), and +'%c' (inserts an int as a byte). +
  • + +
+ + + + +

lua_pushglobaltable

+[-0, +1, –] +

void lua_pushglobaltable (lua_State *L);
+ +

+Pushes the global environment onto the stack. + + + + + +


lua_pushinteger

+[-0, +1, –] +

void lua_pushinteger (lua_State *L, lua_Integer n);
+ +

+Pushes a number with value n onto the stack. + + + + + +


lua_pushlightuserdata

+[-0, +1, –] +

void lua_pushlightuserdata (lua_State *L, void *p);
+ +

+Pushes a light userdata onto the stack. + + +

+Userdata represent C values in Lua. +A light userdata represents a pointer, a void*. +It is a value (like a number): +you do not create it, it has no individual metatable, +and it is not collected (as it was never created). +A light userdata is equal to "any" +light userdata with the same C address. + + + + + +


lua_pushliteral

+[-0, +1, e] +

const char *lua_pushliteral (lua_State *L, const char *s);
+ +

+This macro is equivalent to lua_pushlstring, +but can be used only when s is a literal string. +It automatically provides the string length. + + + + + +


lua_pushlstring

+[-0, +1, e] +

const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
+ +

+Pushes the string pointed to by s with size len +onto the stack. +Lua makes (or reuses) an internal copy of the given string, +so the memory at s can be freed or reused immediately after +the function returns. +The string can contain any binary data, +including embedded zeros. + + +

+Returns a pointer to the internal copy of the string. + + + + + +


lua_pushnil

+[-0, +1, –] +

void lua_pushnil (lua_State *L);
+ +

+Pushes a nil value onto the stack. + + + + + +


lua_pushnumber

+[-0, +1, –] +

void lua_pushnumber (lua_State *L, lua_Number n);
+ +

+Pushes a number with value n onto the stack. + + + + + +


lua_pushstring

+[-0, +1, e] +

const char *lua_pushstring (lua_State *L, const char *s);
+ +

+Pushes the zero-terminated string pointed to by s +onto the stack. +Lua makes (or reuses) an internal copy of the given string, +so the memory at s can be freed or reused immediately after +the function returns. + + +

+Returns a pointer to the internal copy of the string. + + +

+If s is NULL, pushes nil and returns NULL. + + + + + +


lua_pushthread

+[-0, +1, –] +

int lua_pushthread (lua_State *L);
+ +

+Pushes the thread represented by L onto the stack. +Returns 1 if this thread is the main thread of its state. + + + + + +


lua_pushunsigned

+[-0, +1, –] +

void lua_pushunsigned (lua_State *L, lua_Unsigned n);
+ +

+Pushes a number with value n onto the stack. + + + + + +


lua_pushvalue

+[-0, +1, –] +

void lua_pushvalue (lua_State *L, int index);
+ +

+Pushes a copy of the element at the given index +onto the stack. + + + + + +


lua_pushvfstring

+[-0, +1, e] +

const char *lua_pushvfstring (lua_State *L,
+                              const char *fmt,
+                              va_list argp);
+ +

+Equivalent to lua_pushfstring, except that it receives a va_list +instead of a variable number of arguments. + + + + + +


lua_rawequal

+[-0, +0, –] +

int lua_rawequal (lua_State *L, int index1, int index2);
+ +

+Returns 1 if the two values in indices index1 and +index2 are primitively equal +(that is, without calling metamethods). +Otherwise returns 0. +Also returns 0 if any of the indices are non valid. + + + + + +


lua_rawget

+[-1, +1, –] +

void lua_rawget (lua_State *L, int index);
+ +

+Similar to lua_gettable, but does a raw access +(i.e., without metamethods). + + + + + +


lua_rawgeti

+[-0, +1, –] +

void lua_rawgeti (lua_State *L, int index, int n);
+ +

+Pushes onto the stack the value t[n], +where t is the table at the given index. +The access is raw; +that is, it does not invoke metamethods. + + + + + +


lua_rawgetp

+[-0, +1, –] +

void lua_rawgetp (lua_State *L, int index, const void *p);
+ +

+Pushes onto the stack the value t[k], +where t is the table at the given index and +k is the pointer p represented as a light userdata. +The access is raw; +that is, it does not invoke metamethods. + + + + + +


lua_rawlen

+[-0, +0, –] +

size_t lua_rawlen (lua_State *L, int index);
+ +

+Returns the raw "length" of the value at the given index: +for strings, this is the string length; +for tables, this is the result of the length operator ('#') +with no metamethods; +for userdata, this is the size of the block of memory allocated +for the userdata; +for other values, it is 0. + + + + + +


lua_rawset

+[-2, +0, e] +

void lua_rawset (lua_State *L, int index);
+ +

+Similar to lua_settable, but does a raw assignment +(i.e., without metamethods). + + + + + +


lua_rawseti

+[-1, +0, e] +

void lua_rawseti (lua_State *L, int index, int n);
+ +

+Does the equivalent of t[n] = v, +where t is the table at the given index +and v is the value at the top of the stack. + + +

+This function pops the value from the stack. +The assignment is raw; +that is, it does not invoke metamethods. + + + + + +


lua_rawsetp

+[-1, +0, e] +

void lua_rawsetp (lua_State *L, int index, const void *p);
+ +

+Does the equivalent of t[k] = v, +where t is the table at the given index, +k is the pointer p represented as a light userdata, +and v is the value at the top of the stack. + + +

+This function pops the value from the stack. +The assignment is raw; +that is, it does not invoke metamethods. + + + + + +


lua_Reader

+
typedef const char * (*lua_Reader) (lua_State *L,
+                                    void *data,
+                                    size_t *size);
+ +

+The reader function used by lua_load. +Every time it needs another piece of the chunk, +lua_load calls the reader, +passing along its data parameter. +The reader must return a pointer to a block of memory +with a new piece of the chunk +and set size to the block size. +The block must exist until the reader function is called again. +To signal the end of the chunk, +the reader must return NULL or set size to zero. +The reader function may return pieces of any size greater than zero. + + + + + +


lua_register

+[-0, +0, e] +

void lua_register (lua_State *L, const char *name, lua_CFunction f);
+ +

+Sets the C function f as the new value of global name. +It is defined as a macro: + +

+     #define lua_register(L,n,f) \
+            (lua_pushcfunction(L, f), lua_setglobal(L, n))
+
+ + + + +

lua_remove

+[-1, +0, –] +

void lua_remove (lua_State *L, int index);
+ +

+Removes the element at the given valid index, +shifting down the elements above this index to fill the gap. +This function cannot be called with a pseudo-index, +because a pseudo-index is not an actual stack position. + + + + + +


lua_replace

+[-1, +0, –] +

void lua_replace (lua_State *L, int index);
+ +

+Moves the top element into the given valid index +without shifting any element +(therefore replacing the value at the given index), +and then pops the top element. + + + + + +


lua_resume

+[-?, +?, –] +

int lua_resume (lua_State *L, lua_State *from, int nargs);
+ +

+Starts and resumes a coroutine in a given thread. + + +

+To start a coroutine, +you push onto the thread stack the main function plus any arguments; +then you call lua_resume, +with nargs being the number of arguments. +This call returns when the coroutine suspends or finishes its execution. +When it returns, the stack contains all values passed to lua_yield, +or all values returned by the body function. +lua_resume returns +LUA_YIELD if the coroutine yields, +LUA_OK if the coroutine finishes its execution +without errors, +or an error code in case of errors (see lua_pcall). + + +

+In case of errors, +the stack is not unwound, +so you can use the debug API over it. +The error message is on the top of the stack. + + +

+To resume a coroutine, +you remove any results from the last lua_yield, +put on its stack only the values to +be passed as results from yield, +and then call lua_resume. + + +

+The parameter from represents the coroutine that is resuming L. +If there is no such coroutine, +this parameter can be NULL. + + + + + +


lua_setallocf

+[-0, +0, –] +

void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+ +

+Changes the allocator function of a given state to f +with user data ud. + + + + + +


lua_setfield

+[-1, +0, e] +

void lua_setfield (lua_State *L, int index, const char *k);
+ +

+Does the equivalent to t[k] = v, +where t is the value at the given index +and v is the value at the top of the stack. + + +

+This function pops the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.4). + + + + + +


lua_setglobal

+[-1, +0, e] +

void lua_setglobal (lua_State *L, const char *name);
+ +

+Pops a value from the stack and +sets it as the new value of global name. + + + + + +


lua_setmetatable

+[-1, +0, –] +

void lua_setmetatable (lua_State *L, int index);
+ +

+Pops a table from the stack and +sets it as the new metatable for the value at the given index. + + + + + +


lua_settable

+[-2, +0, e] +

void lua_settable (lua_State *L, int index);
+ +

+Does the equivalent to t[k] = v, +where t is the value at the given index, +v is the value at the top of the stack, +and k is the value just below the top. + + +

+This function pops both the key and the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see §2.4). + + + + + +


lua_settop

+[-?, +?, –] +

void lua_settop (lua_State *L, int index);
+ +

+Accepts any index, or 0, +and sets the stack top to this index. +If the new top is larger than the old one, +then the new elements are filled with nil. +If index is 0, then all stack elements are removed. + + + + + +


lua_setuservalue

+[-1, +0, –] +

void lua_setuservalue (lua_State *L, int index);
+ +

+Pops a table or nil from the stack and sets it as +the new value associated to the userdata at the given index. + + + + + +


lua_State

+
typedef struct lua_State lua_State;
+ +

+An opaque structure that points to a thread and indirectly +(through the thread) to the whole state of a Lua interpreter. +The Lua library is fully reentrant: +it has no global variables. +All information about a state is accessible through this structure. + + +

+A pointer to this structure must be passed as the first argument to +every function in the library, except to lua_newstate, +which creates a Lua state from scratch. + + + + + +


lua_status

+[-0, +0, –] +

int lua_status (lua_State *L);
+ +

+Returns the status of the thread L. + + +

+The status can be 0 (LUA_OK) for a normal thread, +an error code if the thread finished the execution +of a lua_resume with an error, +or LUA_YIELD if the thread is suspended. + + +

+You can only call functions in threads with status LUA_OK. +You can resume threads with status LUA_OK +(to start a new coroutine) or LUA_YIELD +(to resume a coroutine). + + + + + +


lua_toboolean

+[-0, +0, –] +

int lua_toboolean (lua_State *L, int index);
+ +

+Converts the Lua value at the given index to a C boolean +value (0 or 1). +Like all tests in Lua, +lua_toboolean returns true for any Lua value +different from false and nil; +otherwise it returns false. +(If you want to accept only actual boolean values, +use lua_isboolean to test the value's type.) + + + + + +


lua_tocfunction

+[-0, +0, –] +

lua_CFunction lua_tocfunction (lua_State *L, int index);
+ +

+Converts a value at the given index to a C function. +That value must be a C function; +otherwise, returns NULL. + + + + + +


lua_tointeger

+[-0, +0, –] +

lua_Integer lua_tointeger (lua_State *L, int index);
+ +

+Equivalent to lua_tointegerx with isnum equal to NULL. + + + + + +


lua_tointegerx

+[-0, +0, –] +

lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
+ +

+Converts the Lua value at the given index +to the signed integral type lua_Integer. +The Lua value must be a number or a string convertible to a number +(see §3.4.2); +otherwise, lua_tointegerx returns 0. + + +

+If the number is not an integer, +it is truncated in some non-specified way. + + +

+If isnum is not NULL, +its referent is assigned a boolean value that +indicates whether the operation succeeded. + + + + + +


lua_tolstring

+[-0, +0, e] +

const char *lua_tolstring (lua_State *L, int index, size_t *len);
+ +

+Converts the Lua value at the given index to a C string. +If len is not NULL, +it also sets *len with the string length. +The Lua value must be a string or a number; +otherwise, the function returns NULL. +If the value is a number, +then lua_tolstring also +changes the actual value in the stack to a string. +(This change confuses lua_next +when lua_tolstring is applied to keys during a table traversal.) + + +

+lua_tolstring returns a fully aligned pointer +to a string inside the Lua state. +This string always has a zero ('\0') +after its last character (as in C), +but can contain other zeros in its body. +Because Lua has garbage collection, +there is no guarantee that the pointer returned by lua_tolstring +will be valid after the corresponding value is removed from the stack. + + + + + +


lua_tonumber

+[-0, +0, –] +

lua_Number lua_tonumber (lua_State *L, int index);
+ +

+Equivalent to lua_tonumberx with isnum equal to NULL. + + + + + +


lua_tonumberx

+[-0, +0, –] +

lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
+ +

+Converts the Lua value at the given index +to the C type lua_Number (see lua_Number). +The Lua value must be a number or a string convertible to a number +(see §3.4.2); +otherwise, lua_tonumberx returns 0. + + +

+If isnum is not NULL, +its referent is assigned a boolean value that +indicates whether the operation succeeded. + + + + + +


lua_topointer

+[-0, +0, –] +

const void *lua_topointer (lua_State *L, int index);
+ +

+Converts the value at the given index to a generic +C pointer (void*). +The value can be a userdata, a table, a thread, or a function; +otherwise, lua_topointer returns NULL. +Different objects will give different pointers. +There is no way to convert the pointer back to its original value. + + +

+Typically this function is used only for debug information. + + + + + +


lua_tostring

+[-0, +0, e] +

const char *lua_tostring (lua_State *L, int index);
+ +

+Equivalent to lua_tolstring with len equal to NULL. + + + + + +


lua_tothread

+[-0, +0, –] +

lua_State *lua_tothread (lua_State *L, int index);
+ +

+Converts the value at the given index to a Lua thread +(represented as lua_State*). +This value must be a thread; +otherwise, the function returns NULL. + + + + + +


lua_tounsigned

+[-0, +0, –] +

lua_Unsigned lua_tounsigned (lua_State *L, int index);
+ +

+Equivalent to lua_tounsignedx with isnum equal to NULL. + + + + + +


lua_tounsignedx

+[-0, +0, –] +

lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);
+ +

+Converts the Lua value at the given index +to the unsigned integral type lua_Unsigned. +The Lua value must be a number or a string convertible to a number +(see §3.4.2); +otherwise, lua_tounsignedx returns 0. + + +

+If the number is not an integer, +it is truncated in some non-specified way. +If the number is outside the range of representable values, +it is normalized to the remainder of its division by +one more than the maximum representable value. + + +

+If isnum is not NULL, +its referent is assigned a boolean value that +indicates whether the operation succeeded. + + + + + +


lua_touserdata

+[-0, +0, –] +

void *lua_touserdata (lua_State *L, int index);
+ +

+If the value at the given index is a full userdata, +returns its block address. +If the value is a light userdata, +returns its pointer. +Otherwise, returns NULL. + + + + + +


lua_type

+[-0, +0, –] +

int lua_type (lua_State *L, int index);
+ +

+Returns the type of the value in the given valid index, +or LUA_TNONE for a non-valid (but acceptable) index. +The types returned by lua_type are coded by the following constants +defined in lua.h: +LUA_TNIL, +LUA_TNUMBER, +LUA_TBOOLEAN, +LUA_TSTRING, +LUA_TTABLE, +LUA_TFUNCTION, +LUA_TUSERDATA, +LUA_TTHREAD, +and +LUA_TLIGHTUSERDATA. + + + + + +


lua_typename

+[-0, +0, –] +

const char *lua_typename (lua_State *L, int tp);
+ +

+Returns the name of the type encoded by the value tp, +which must be one the values returned by lua_type. + + + + + +


lua_Unsigned

+
typedef unsigned long lua_Unsigned;
+ +

+The type used by the Lua API to represent unsigned integral values. +It must have at least 32 bits. + + +

+By default it is an unsigned int or an unsigned long, +whichever can hold 32-bit values. + + + + + +


lua_upvalueindex

+[-0, +0, –] +

int lua_upvalueindex (int i);
+ +

+Returns the pseudo-index that represents the i-th upvalue of +the running function (see §4.4). + + + + + +


lua_version

+[-0, +0, v] +

const lua_Number *lua_version (lua_State *L);
+ +

+Returns the address of the version number stored in the Lua core. +When called with a valid lua_State, +returns the address of the version used to create that state. +When called with NULL, +returns the address of the version running the call. + + + + + +


lua_Writer

+
typedef int (*lua_Writer) (lua_State *L,
+                           const void* p,
+                           size_t sz,
+                           void* ud);
+ +

+The type of the writer function used by lua_dump. +Every time it produces another piece of chunk, +lua_dump calls the writer, +passing along the buffer to be written (p), +its size (sz), +and the data parameter supplied to lua_dump. + + +

+The writer returns an error code: +0 means no errors; +any other value means an error and stops lua_dump from +calling the writer again. + + + + + +


lua_xmove

+[-?, +?, –] +

void lua_xmove (lua_State *from, lua_State *to, int n);
+ +

+Exchange values between different threads of the same state. + + +

+This function pops n values from the stack from, +and pushes them onto the stack to. + + + + + +


lua_yield

+[-?, +?, –] +

int lua_yield (lua_State *L, int nresults);
+ +

+This function is equivalent to lua_yieldk, +but it has no continuation (see §4.7). +Therefore, when the thread resumes, +it returns to the function that called +the function calling lua_yield. + + + + + +


lua_yieldk

+[-?, +?, –] +

int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);
+ +

+Yields a coroutine. + + +

+This function should only be called as the +return expression of a C function, as follows: + +

+     return lua_yieldk (L, n, i, k);
+

+When a C function calls lua_yieldk in that way, +the running coroutine suspends its execution, +and the call to lua_resume that started this coroutine returns. +The parameter nresults is the number of values from the stack +that are passed as results to lua_resume. + + +

+When the coroutine is resumed again, +Lua calls the given continuation function k to continue +the execution of the C function that yielded (see §4.7). +This continuation function receives the same stack +from the previous function, +with the results removed and +replaced by the arguments passed to lua_resume. +Moreover, +the continuation function may access the value ctx +by calling lua_getctx. + + + + + + + +

4.9 – The Debug Interface

+ +

+Lua has no built-in debugging facilities. +Instead, it offers a special interface +by means of functions and hooks. +This interface allows the construction of different +kinds of debuggers, profilers, and other tools +that need "inside information" from the interpreter. + + + +


lua_Debug

+
typedef struct lua_Debug {
+  int event;
+  const char *name;           /* (n) */
+  const char *namewhat;       /* (n) */
+  const char *what;           /* (S) */
+  const char *source;         /* (S) */
+  int currentline;            /* (l) */
+  int linedefined;            /* (S) */
+  int lastlinedefined;        /* (S) */
+  unsigned char nups;         /* (u) number of upvalues */
+  unsigned char nparams;      /* (u) number of parameters */
+  char isvararg;              /* (u) */
+  char istailcall;            /* (t) */
+  char short_src[LUA_IDSIZE]; /* (S) */
+  /* private part */
+  other fields
+} lua_Debug;
+ +

+A structure used to carry different pieces of +information about a function or an activation record. +lua_getstack fills only the private part +of this structure, for later use. +To fill the other fields of lua_Debug with useful information, +call lua_getinfo. + + +

+The fields of lua_Debug have the following meaning: + +

    + +
  • source: +the source of the chunk that created the function. +If source starts with a '@', +it means that the function was defined in a file where +the file name follows the '@'. +If source starts with a '=', +the remainder of its contents describe the source in a user-dependent manner. +Otherwise, +the function was defined in a string where +source is that string. +
  • + +
  • short_src: +a "printable" version of source, to be used in error messages. +
  • + +
  • linedefined: +the line number where the definition of the function starts. +
  • + +
  • lastlinedefined: +the line number where the definition of the function ends. +
  • + +
  • what: +the string "Lua" if the function is a Lua function, +"C" if it is a C function, +"main" if it is the main part of a chunk. +
  • + +
  • currentline: +the current line where the given function is executing. +When no line information is available, +currentline is set to -1. +
  • + +
  • name: +a reasonable name for the given function. +Because functions in Lua are first-class values, +they do not have a fixed name: +some functions can be the value of multiple global variables, +while others can be stored only in a table field. +The lua_getinfo function checks how the function was +called to find a suitable name. +If it cannot find a name, +then name is set to NULL. +
  • + +
  • namewhat: +explains the name field. +The value of namewhat can be +"global", "local", "method", +"field", "upvalue", or "" (the empty string), +according to how the function was called. +(Lua uses the empty string when no other option seems to apply.) +
  • + +
  • istailcall: +true if this function invocation was called by a tail call. +In this case, the caller of this level is not in the stack. +
  • + +
  • nups: +the number of upvalues of the function. +
  • + +
  • nparams: +the number of fixed parameters of the function +(always 0 for C functions). +
  • + +
  • isvararg: +true if the function is a vararg function +(always true for C functions). +
  • + +
+ + + + +

lua_gethook

+[-0, +0, –] +

lua_Hook lua_gethook (lua_State *L);
+ +

+Returns the current hook function. + + + + + +


lua_gethookcount

+[-0, +0, –] +

int lua_gethookcount (lua_State *L);
+ +

+Returns the current hook count. + + + + + +


lua_gethookmask

+[-0, +0, –] +

int lua_gethookmask (lua_State *L);
+ +

+Returns the current hook mask. + + + + + +


lua_getinfo

+[-(0|1), +(0|1|2), e] +

int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
+ +

+Gets information about a specific function or function invocation. + + +

+To get information about a function invocation, +the parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). + + +

+To get information about a function you push it onto the stack +and start the what string with the character '>'. +(In that case, +lua_getinfo pops the function from the top of the stack.) +For instance, to know in which line a function f was defined, +you can write the following code: + +

+     lua_Debug ar;
+     lua_getglobal(L, "f");  /* get global 'f' */
+     lua_getinfo(L, ">S", &ar);
+     printf("%d\n", ar.linedefined);
+
+ +

+Each character in the string what +selects some fields of the structure ar to be filled or +a value to be pushed on the stack: + +

    + +
  • 'n': fills in the field name and namewhat; +
  • + +
  • 'S': +fills in the fields source, short_src, +linedefined, lastlinedefined, and what; +
  • + +
  • 'l': fills in the field currentline; +
  • + +
  • 't': fills in the field istailcall; +
  • + +
  • 'u': fills in the fields +nups, nparams, and isvararg; +
  • + +
  • 'f': +pushes onto the stack the function that is +running at the given level; +
  • + +
  • 'L': +pushes onto the stack a table whose indices are the +numbers of the lines that are valid on the function. +(A valid line is a line with some associated code, +that is, a line where you can put a break point. +Non-valid lines include empty lines and comments.) +
  • + +
+ +

+This function returns 0 on error +(for instance, an invalid option in what). + + + + + +


lua_getlocal

+[-0, +(0|1), –] +

const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
+ +

+Gets information about a local variable of +a given activation record or a given function. + + +

+In the first case, +the parameter ar must be a valid activation record that was +filled by a previous call to lua_getstack or +given as argument to a hook (see lua_Hook). +The index n selects which local variable to inspect; +see debug.getlocal for details about variable indices +and names. + + +

+lua_getlocal pushes the variable's value onto the stack +and returns its name. + + +

+In the second case, ar should be NULL and the function +to be inspected must be at the top of the stack. +In this case, only parameters of Lua functions are visible +(as there is no information about what variables are active) +and no values are pushed onto the stack. + + +

+Returns NULL (and pushes nothing) +when the index is greater than +the number of active local variables. + + + + + +


lua_getstack

+[-0, +0, –] +

int lua_getstack (lua_State *L, int level, lua_Debug *ar);
+ +

+Gets information about the interpreter runtime stack. + + +

+This function fills parts of a lua_Debug structure with +an identification of the activation record +of the function executing at a given level. +Level 0 is the current running function, +whereas level n+1 is the function that has called level n +(except for tail calls, which do not count on the stack). +When there are no errors, lua_getstack returns 1; +when called with a level greater than the stack depth, +it returns 0. + + + + + +


lua_getupvalue

+[-0, +(0|1), –] +

const char *lua_getupvalue (lua_State *L, int funcindex, int n);
+ +

+Gets information about a closure's upvalue. +(For Lua functions, +upvalues are the external local variables that the function uses, +and that are consequently included in its closure.) +lua_getupvalue gets the index n of an upvalue, +pushes the upvalue's value onto the stack, +and returns its name. +funcindex points to the closure in the stack. +(Upvalues have no particular order, +as they are active through the whole function. +So, they are numbered in an arbitrary order.) + + +

+Returns NULL (and pushes nothing) +when the index is greater than the number of upvalues. +For C functions, this function uses the empty string "" +as a name for all upvalues. + + + + + +


lua_Hook

+
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+ +

+Type for debugging hook functions. + + +

+Whenever a hook is called, its ar argument has its field +event set to the specific event that triggered the hook. +Lua identifies these events with the following constants: +LUA_HOOKCALL, LUA_HOOKRET, +LUA_HOOKTAILCALL, LUA_HOOKLINE, +and LUA_HOOKCOUNT. +Moreover, for line events, the field currentline is also set. +To get the value of any other field in ar, +the hook must call lua_getinfo. + + +

+For call events, event can be LUA_HOOKCALL, +the normal value, or LUA_HOOKTAILCALL, for a tail call; +in this case, there will be no corresponding return event. + + +

+While Lua is running a hook, it disables other calls to hooks. +Therefore, if a hook calls back Lua to execute a function or a chunk, +this execution occurs without any calls to hooks. + + +

+Hook functions cannot have continuations, +that is, they cannot call lua_yieldk, +lua_pcallk, or lua_callk with a non-null k. + + +

+Hook functions can yield under the following conditions: +Only count and line events can yield +and they cannot yield any value; +to yield a hook function must finish its execution +calling lua_yield with nresults equal to zero. + + + + + +


lua_sethook

+[-0, +0, –] +

int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
+ +

+Sets the debugging hook function. + + +

+Argument f is the hook function. +mask specifies on which events the hook will be called: +it is formed by a bitwise or of the constants +LUA_MASKCALL, +LUA_MASKRET, +LUA_MASKLINE, +and LUA_MASKCOUNT. +The count argument is only meaningful when the mask +includes LUA_MASKCOUNT. +For each event, the hook is called as explained below: + +

    + +
  • The call hook: is called when the interpreter calls a function. +The hook is called just after Lua enters the new function, +before the function gets its arguments. +
  • + +
  • The return hook: is called when the interpreter returns from a function. +The hook is called just before Lua leaves the function. +There is no standard way to access the values +to be returned by the function. +
  • + +
  • The line hook: is called when the interpreter is about to +start the execution of a new line of code, +or when it jumps back in the code (even to the same line). +(This event only happens while Lua is executing a Lua function.) +
  • + +
  • The count hook: is called after the interpreter executes every +count instructions. +(This event only happens while Lua is executing a Lua function.) +
  • + +
+ +

+A hook is disabled by setting mask to zero. + + + + + +


lua_setlocal

+[-(0|1), +0, –] +

const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
+ +

+Sets the value of a local variable of a given activation record. +Parameters ar and n are as in lua_getlocal +(see lua_getlocal). +lua_setlocal assigns the value at the top of the stack +to the variable and returns its name. +It also pops the value from the stack. + + +

+Returns NULL (and pops nothing) +when the index is greater than +the number of active local variables. + + + + + +


lua_setupvalue

+[-(0|1), +0, –] +

const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+ +

+Sets the value of a closure's upvalue. +It assigns the value at the top of the stack +to the upvalue and returns its name. +It also pops the value from the stack. +Parameters funcindex and n are as in the lua_getupvalue +(see lua_getupvalue). + + +

+Returns NULL (and pops nothing) +when the index is greater than the number of upvalues. + + + + + +


lua_upvalueid

+[-0, +0, –] +

void *lua_upvalueid (lua_State *L, int funcindex, int n);
+ +

+Returns an unique identifier for the upvalue numbered n +from the closure at index funcindex. +Parameters funcindex and n are as in the lua_getupvalue +(see lua_getupvalue) +(but n cannot be greater than the number of upvalues). + + +

+These unique identifiers allow a program to check whether different +closures share upvalues. +Lua closures that share an upvalue +(that is, that access a same external local variable) +will return identical ids for those upvalue indices. + + + + + +


lua_upvaluejoin

+[-0, +0, –] +

void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
+                                    int funcindex2, int n2);
+ +

+Make the n1-th upvalue of the Lua closure at index funcindex1 +refer to the n2-th upvalue of the Lua closure at index funcindex2. + + + + + + + +

5 – The Auxiliary Library

+ +

+ +The auxiliary library provides several convenient functions +to interface C with Lua. +While the basic API provides the primitive functions for all +interactions between C and Lua, +the auxiliary library provides higher-level functions for some +common tasks. + + +

+All functions and types from the auxiliary library +are defined in header file lauxlib.h and +have a prefix luaL_. + + +

+All functions in the auxiliary library are built on +top of the basic API, +and so they provide nothing that cannot be done with that API. +Nevertheless, the use of the auxiliary library ensures +more consistency to your code. + + +

+Several functions in the auxiliary library use internally some +extra stack slots. +When a function in the auxiliary library uses less than five slots, +it does not check the stack size; +it simply assumes that there are enough slots. + + +

+Several functions in the auxiliary library are used to +check C function arguments. +Because the error message is formatted for arguments +(e.g., "bad argument #1"), +you should not use these functions for other stack values. + + +

+Functions called luaL_check* +always throw an error if the check is not satisfied. + + + +

5.1 – Functions and Types

+ +

+Here we list all functions and types from the auxiliary library +in alphabetical order. + + + +


luaL_addchar

+[-?, +?, e] +

void luaL_addchar (luaL_Buffer *B, char c);
+ +

+Adds the byte c to the buffer B +(see luaL_Buffer). + + + + + +


luaL_addlstring

+[-?, +?, e] +

void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
+ +

+Adds the string pointed to by s with length l to +the buffer B +(see luaL_Buffer). +The string can contain embedded zeros. + + + + + +


luaL_addsize

+[-?, +?, e] +

void luaL_addsize (luaL_Buffer *B, size_t n);
+ +

+Adds to the buffer B (see luaL_Buffer) +a string of length n previously copied to the +buffer area (see luaL_prepbuffer). + + + + + +


luaL_addstring

+[-?, +?, e] +

void luaL_addstring (luaL_Buffer *B, const char *s);
+ +

+Adds the zero-terminated string pointed to by s +to the buffer B +(see luaL_Buffer). +The string cannot contain embedded zeros. + + + + + +


luaL_addvalue

+[-1, +?, e] +

void luaL_addvalue (luaL_Buffer *B);
+ +

+Adds the value at the top of the stack +to the buffer B +(see luaL_Buffer). +Pops the value. + + +

+This is the only function on string buffers that can (and must) +be called with an extra element on the stack, +which is the value to be added to the buffer. + + + + + +


luaL_argcheck

+[-0, +0, v] +

void luaL_argcheck (lua_State *L,
+                    int cond,
+                    int arg,
+                    const char *extramsg);
+ +

+Checks whether cond is true. +If not, raises an error with a standard message. + + + + + +


luaL_argerror

+[-0, +0, v] +

int luaL_argerror (lua_State *L, int arg, const char *extramsg);
+ +

+Raises an error with a standard message +that includes extramsg as a comment. + + +

+This function never returns, +but it is an idiom to use it in C functions +as return luaL_argerror(args). + + + + + +


luaL_Buffer

+
typedef struct luaL_Buffer luaL_Buffer;
+ +

+Type for a string buffer. + + +

+A string buffer allows C code to build Lua strings piecemeal. +Its pattern of use is as follows: + +

    + +
  • First declare a variable b of type luaL_Buffer.
  • + +
  • Then initialize it with a call luaL_buffinit(L, &b).
  • + +
  • +Then add string pieces to the buffer calling any of +the luaL_add* functions. +
  • + +
  • +Finish by calling luaL_pushresult(&b). +This call leaves the final string on the top of the stack. +
  • + +
+ +

+If you know beforehand the total size of the resulting string, +you can use the buffer like this: + +

    + +
  • First declare a variable b of type luaL_Buffer.
  • + +
  • Then initialize it and preallocate a space of +size sz with a call luaL_buffinitsize(L, &b, sz).
  • + +
  • Then copy the string into that space.
  • + +
  • +Finish by calling luaL_pushresultsize(&b, sz), +where sz is the total size of the resulting string +copied into that space. +
  • + +
+ +

+During its normal operation, +a string buffer uses a variable number of stack slots. +So, while using a buffer, you cannot assume that you know where +the top of the stack is. +You can use the stack between successive calls to buffer operations +as long as that use is balanced; +that is, +when you call a buffer operation, +the stack is at the same level +it was immediately after the previous buffer operation. +(The only exception to this rule is luaL_addvalue.) +After calling luaL_pushresult the stack is back to its +level when the buffer was initialized, +plus the final string on its top. + + + + + +


luaL_buffinit

+[-0, +0, –] +

void luaL_buffinit (lua_State *L, luaL_Buffer *B);
+ +

+Initializes a buffer B. +This function does not allocate any space; +the buffer must be declared as a variable +(see luaL_Buffer). + + + + + +


luaL_buffinitsize

+[-?, +?, e] +

char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);
+ +

+Equivalent to the sequence +luaL_buffinit, luaL_prepbuffsize. + + + + + +


luaL_callmeta

+[-0, +(0|1), e] +

int luaL_callmeta (lua_State *L, int obj, const char *e);
+ +

+Calls a metamethod. + + +

+If the object at index obj has a metatable and this +metatable has a field e, +this function calls this field passing the object as its only argument. +In this case this function returns true and pushes onto the +stack the value returned by the call. +If there is no metatable or no metamethod, +this function returns false (without pushing any value on the stack). + + + + + +


luaL_checkany

+[-0, +0, v] +

void luaL_checkany (lua_State *L, int arg);
+ +

+Checks whether the function has an argument +of any type (including nil) at position arg. + + + + + +


luaL_checkint

+[-0, +0, v] +

int luaL_checkint (lua_State *L, int arg);
+ +

+Checks whether the function argument arg is a number +and returns this number cast to an int. + + + + + +


luaL_checkinteger

+[-0, +0, v] +

lua_Integer luaL_checkinteger (lua_State *L, int arg);
+ +

+Checks whether the function argument arg is a number +and returns this number cast to a lua_Integer. + + + + + +


luaL_checklong

+[-0, +0, v] +

long luaL_checklong (lua_State *L, int arg);
+ +

+Checks whether the function argument arg is a number +and returns this number cast to a long. + + + + + +


luaL_checklstring

+[-0, +0, v] +

const char *luaL_checklstring (lua_State *L, int arg, size_t *l);
+ +

+Checks whether the function argument arg is a string +and returns this string; +if l is not NULL fills *l +with the string's length. + + +

+This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


luaL_checknumber

+[-0, +0, v] +

lua_Number luaL_checknumber (lua_State *L, int arg);
+ +

+Checks whether the function argument arg is a number +and returns this number. + + + + + +


luaL_checkoption

+[-0, +0, v] +

int luaL_checkoption (lua_State *L,
+                      int arg,
+                      const char *def,
+                      const char *const lst[]);
+ +

+Checks whether the function argument arg is a string and +searches for this string in the array lst +(which must be NULL-terminated). +Returns the index in the array where the string was found. +Raises an error if the argument is not a string or +if the string cannot be found. + + +

+If def is not NULL, +the function uses def as a default value when +there is no argument arg or when this argument is nil. + + +

+This is a useful function for mapping strings to C enums. +(The usual convention in Lua libraries is +to use strings instead of numbers to select options.) + + + + + +


luaL_checkstack

+[-0, +0, v] +

void luaL_checkstack (lua_State *L, int sz, const char *msg);
+ +

+Grows the stack size to top + sz elements, +raising an error if the stack cannot grow to that size. +msg is an additional text to go into the error message +(or NULL for no additional text). + + + + + +


luaL_checkstring

+[-0, +0, v] +

const char *luaL_checkstring (lua_State *L, int arg);
+ +

+Checks whether the function argument arg is a string +and returns this string. + + +

+This function uses lua_tolstring to get its result, +so all conversions and caveats of that function apply here. + + + + + +


luaL_checktype

+[-0, +0, v] +

void luaL_checktype (lua_State *L, int arg, int t);
+ +

+Checks whether the function argument arg has type t. +See lua_type for the encoding of types for t. + + + + + +


luaL_checkudata

+[-0, +0, v] +

void *luaL_checkudata (lua_State *L, int arg, const char *tname);
+ +

+Checks whether the function argument arg is a userdata +of the type tname (see luaL_newmetatable) and +returns the userdata address (see lua_touserdata). + + + + + +


luaL_checkunsigned

+[-0, +0, v] +

lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);
+ +

+Checks whether the function argument arg is a number +and returns this number cast to a lua_Unsigned. + + + + + +


luaL_checkversion

+[-0, +0, –] +

void luaL_checkversion (lua_State *L);
+ +

+Checks whether the core running the call, +the core that created the Lua state, +and the code making the call are all using the same version of Lua. +Also checks whether the core running the call +and the core that created the Lua state +are using the same address space. + + + + + +


luaL_dofile

+[-0, +?, e] +

int luaL_dofile (lua_State *L, const char *filename);
+ +

+Loads and runs the given file. +It is defined as the following macro: + +

+     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
+

+It returns false if there are no errors +or true in case of errors. + + + + + +


luaL_dostring

+[-0, +?, –] +

int luaL_dostring (lua_State *L, const char *str);
+ +

+Loads and runs the given string. +It is defined as the following macro: + +

+     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
+

+It returns false if there are no errors +or true in case of errors. + + + + + +


luaL_error

+[-0, +0, v] +

int luaL_error (lua_State *L, const char *fmt, ...);
+ +

+Raises an error. +The error message format is given by fmt +plus any extra arguments, +following the same rules of lua_pushfstring. +It also adds at the beginning of the message the file name and +the line number where the error occurred, +if this information is available. + + +

+This function never returns, +but it is an idiom to use it in C functions +as return luaL_error(args). + + + + + +


luaL_execresult

+[-0, +3, e] +

int luaL_execresult (lua_State *L, int stat);
+ +

+This function produces the return values for +process-related functions in the standard library +(os.execute and io.close). + + + + + +


luaL_fileresult

+[-0, +(1|3), e] +

int luaL_fileresult (lua_State *L, int stat, const char *fname);
+ +

+This function produces the return values for +file-related functions in the standard library +(io.open, os.rename, file:seek, etc.). + + + + + +


luaL_getmetafield

+[-0, +(0|1), e] +

int luaL_getmetafield (lua_State *L, int obj, const char *e);
+ +

+Pushes onto the stack the field e from the metatable +of the object at index obj. +If the object does not have a metatable, +or if the metatable does not have this field, +returns false and pushes nothing. + + + + + +


luaL_getmetatable

+[-0, +1, –] +

void luaL_getmetatable (lua_State *L, const char *tname);
+ +

+Pushes onto the stack the metatable associated with name tname +in the registry (see luaL_newmetatable). + + + + + +


luaL_getsubtable

+[-0, +1, e] +

int luaL_getsubtable (lua_State *L, int idx, const char *fname);
+ +

+Ensures that the value t[fname], +where t is the value at index idx, +is a table, +and pushes that table onto the stack. +Returns true if it finds a previous table there +and false if it creates a new table. + + + + + +


luaL_gsub

+[-0, +1, e] +

const char *luaL_gsub (lua_State *L,
+                       const char *s,
+                       const char *p,
+                       const char *r);
+ +

+Creates a copy of string s by replacing +any occurrence of the string p +with the string r. +Pushes the resulting string on the stack and returns it. + + + + + +


luaL_len

+[-0, +0, e] +

int luaL_len (lua_State *L, int index);
+ +

+Returns the "length" of the value at the given index +as a number; +it is equivalent to the '#' operator in Lua (see §3.4.6). +Raises an error if the result of the operation is not a number. +(This case only can happen through metamethods.) + + + + + +


luaL_loadbuffer

+[-0, +1, –] +

int luaL_loadbuffer (lua_State *L,
+                     const char *buff,
+                     size_t sz,
+                     const char *name);
+ +

+Equivalent to luaL_loadbufferx with mode equal to NULL. + + + + + +


luaL_loadbufferx

+[-0, +1, –] +

int luaL_loadbufferx (lua_State *L,
+                      const char *buff,
+                      size_t sz,
+                      const char *name,
+                      const char *mode);
+ +

+Loads a buffer as a Lua chunk. +This function uses lua_load to load the chunk in the +buffer pointed to by buff with size sz. + + +

+This function returns the same results as lua_load. +name is the chunk name, +used for debug information and error messages. +The string mode works as in function lua_load. + + + + + +


luaL_loadfile

+[-0, +1, e] +

int luaL_loadfile (lua_State *L, const char *filename);
+ +

+Equivalent to luaL_loadfilex with mode equal to NULL. + + + + + +


luaL_loadfilex

+[-0, +1, e] +

int luaL_loadfilex (lua_State *L, const char *filename,
+                                            const char *mode);
+ +

+Loads a file as a Lua chunk. +This function uses lua_load to load the chunk in the file +named filename. +If filename is NULL, +then it loads from the standard input. +The first line in the file is ignored if it starts with a #. + + +

+The string mode works as in function lua_load. + + +

+This function returns the same results as lua_load, +but it has an extra error code LUA_ERRFILE +if it cannot open/read the file or the file has a wrong mode. + + +

+As lua_load, this function only loads the chunk; +it does not run it. + + + + + +


luaL_loadstring

+[-0, +1, –] +

int luaL_loadstring (lua_State *L, const char *s);
+ +

+Loads a string as a Lua chunk. +This function uses lua_load to load the chunk in +the zero-terminated string s. + + +

+This function returns the same results as lua_load. + + +

+Also as lua_load, this function only loads the chunk; +it does not run it. + + + + + +


luaL_newlib

+[-0, +1, e] +

void luaL_newlib (lua_State *L, const luaL_Reg *l);
+ +

+Creates a new table and registers there +the functions in list l. +It is implemented as the following macro: + +

+     (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+
+ + + + +

luaL_newlibtable

+[-0, +1, e] +

void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);
+ +

+Creates a new table with a size optimized +to store all entries in the array l +(but does not actually store them). +It is intended to be used in conjunction with luaL_setfuncs +(see luaL_newlib). + + +

+It is implemented as a macro. +The array l must be the actual array, +not a pointer to it. + + + + + +


luaL_newmetatable

+[-0, +1, e] +

int luaL_newmetatable (lua_State *L, const char *tname);
+ +

+If the registry already has the key tname, +returns 0. +Otherwise, +creates a new table to be used as a metatable for userdata, +adds it to the registry with key tname, +and returns 1. + + +

+In both cases pushes onto the stack the final value associated +with tname in the registry. + + + + + +


luaL_newstate

+[-0, +0, –] +

lua_State *luaL_newstate (void);
+ +

+Creates a new Lua state. +It calls lua_newstate with an +allocator based on the standard C realloc function +and then sets a panic function (see §4.6) that prints +an error message to the standard error output in case of fatal +errors. + + +

+Returns the new state, +or NULL if there is a memory allocation error. + + + + + +


luaL_openlibs

+[-0, +0, e] +

void luaL_openlibs (lua_State *L);
+ +

+Opens all standard Lua libraries into the given state. + + + + + +


luaL_optint

+[-0, +0, v] +

int luaL_optint (lua_State *L, int arg, int d);
+ +

+If the function argument arg is a number, +returns this number cast to an int. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


luaL_optinteger

+[-0, +0, v] +

lua_Integer luaL_optinteger (lua_State *L,
+                             int arg,
+                             lua_Integer d);
+ +

+If the function argument arg is a number, +returns this number cast to a lua_Integer. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


luaL_optlong

+[-0, +0, v] +

long luaL_optlong (lua_State *L, int arg, long d);
+ +

+If the function argument arg is a number, +returns this number cast to a long. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


luaL_optlstring

+[-0, +0, v] +

const char *luaL_optlstring (lua_State *L,
+                             int arg,
+                             const char *d,
+                             size_t *l);
+ +

+If the function argument arg is a string, +returns this string. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + +

+If l is not NULL, +fills the position *l with the result's length. + + + + + +


luaL_optnumber

+[-0, +0, v] +

lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);
+ +

+If the function argument arg is a number, +returns this number. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


luaL_optstring

+[-0, +0, v] +

const char *luaL_optstring (lua_State *L,
+                            int arg,
+                            const char *d);
+ +

+If the function argument arg is a string, +returns this string. +If this argument is absent or is nil, +returns d. +Otherwise, raises an error. + + + + + +


luaL_optunsigned

+[-0, +0, v] +

lua_Unsigned luaL_optunsigned (lua_State *L,
+                               int arg,
+                               lua_Unsigned u);
+ +

+If the function argument arg is a number, +returns this number cast to a lua_Unsigned. +If this argument is absent or is nil, +returns u. +Otherwise, raises an error. + + + + + +


luaL_prepbuffer

+[-?, +?, e] +

char *luaL_prepbuffer (luaL_Buffer *B);
+ +

+Equivalent to luaL_prepbuffsize +with the predefined size LUAL_BUFFERSIZE. + + + + + +


luaL_prepbuffsize

+[-?, +?, e] +

char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);
+ +

+Returns an address to a space of size sz +where you can copy a string to be added to buffer B +(see luaL_Buffer). +After copying the string into this space you must call +luaL_addsize with the size of the string to actually add +it to the buffer. + + + + + +


luaL_pushresult

+[-?, +1, e] +

void luaL_pushresult (luaL_Buffer *B);
+ +

+Finishes the use of buffer B leaving the final string on +the top of the stack. + + + + + +


luaL_pushresultsize

+[-?, +1, e] +

void luaL_pushresultsize (luaL_Buffer *B, size_t sz);
+ +

+Equivalent to the sequence luaL_addsize, luaL_pushresult. + + + + + +


luaL_ref

+[-1, +0, e] +

int luaL_ref (lua_State *L, int t);
+ +

+Creates and returns a reference, +in the table at index t, +for the object at the top of the stack (and pops the object). + + +

+A reference is a unique integer key. +As long as you do not manually add integer keys into table t, +luaL_ref ensures the uniqueness of the key it returns. +You can retrieve an object referred by reference r +by calling lua_rawgeti(L, t, r). +Function luaL_unref frees a reference and its associated object. + + +

+If the object at the top of the stack is nil, +luaL_ref returns the constant LUA_REFNIL. +The constant LUA_NOREF is guaranteed to be different +from any reference returned by luaL_ref. + + + + + +


luaL_Reg

+
typedef struct luaL_Reg {
+  const char *name;
+  lua_CFunction func;
+} luaL_Reg;
+ +

+Type for arrays of functions to be registered by +luaL_setfuncs. +name is the function name and func is a pointer to +the function. +Any array of luaL_Reg must end with an sentinel entry +in which both name and func are NULL. + + + + + +


luaL_requiref

+[-0, +1, e] +

void luaL_requiref (lua_State *L, const char *modname,
+                    lua_CFunction openf, int glb);
+ +

+Calls function openf with string modname as an argument +and sets the call result in package.loaded[modname], +as if that function has been called through require. + + +

+If glb is true, +also stores the result into global modname. + + +

+Leaves a copy of that result on the stack. + + + + + +


luaL_setfuncs

+[-nup, +0, e] +

void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
+ +

+Registers all functions in the array l +(see luaL_Reg) into the table on the top of the stack +(below optional upvalues, see next). + + +

+When nup is not zero, +all functions are created sharing nup upvalues, +which must be previously pushed on the stack +on top of the library table. +These values are popped from the stack after the registration. + + + + + +


luaL_setmetatable

+[-0, +0, –] +

void luaL_setmetatable (lua_State *L, const char *tname);
+ +

+Sets the metatable of the object at the top of the stack +as the metatable associated with name tname +in the registry (see luaL_newmetatable). + + + + + +


luaL_testudata

+[-0, +0, e] +

void *luaL_testudata (lua_State *L, int arg, const char *tname);
+ +

+This function works like luaL_checkudata, +except that, when the test fails, +it returns NULL instead of throwing an error. + + + + + +


luaL_tolstring

+[-0, +1, e] +

const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
+ +

+Converts any Lua value at the given index to a C string +in a reasonable format. +The resulting string is pushed onto the stack and also +returned by the function. +If len is not NULL, +the function also sets *len with the string length. + + +

+If the value has a metatable with a "__tostring" field, +then luaL_tolstring calls the corresponding metamethod +with the value as argument, +and uses the result of the call as its result. + + + + + +


luaL_traceback

+[-0, +1, e] +

void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
+                     int level);
+ +

+Creates and pushes a traceback of the stack L1. +If msg is not NULL it is appended +at the beginning of the traceback. +The level parameter tells at which level +to start the traceback. + + + + + +


luaL_typename

+[-0, +0, –] +

const char *luaL_typename (lua_State *L, int index);
+ +

+Returns the name of the type of the value at the given index. + + + + + +


luaL_unref

+[-0, +0, –] +

void luaL_unref (lua_State *L, int t, int ref);
+ +

+Releases reference ref from the table at index t +(see luaL_ref). +The entry is removed from the table, +so that the referred object can be collected. +The reference ref is also freed to be used again. + + +

+If ref is LUA_NOREF or LUA_REFNIL, +luaL_unref does nothing. + + + + + +


luaL_where

+[-0, +1, e] +

void luaL_where (lua_State *L, int lvl);
+ +

+Pushes onto the stack a string identifying the current position +of the control at level lvl in the call stack. +Typically this string has the following format: + +

+     chunkname:currentline:
+

+Level 0 is the running function, +level 1 is the function that called the running function, +etc. + + +

+This function is used to build a prefix for error messages. + + + + + + + +

6 – Standard Libraries

+ +

+The standard Lua libraries provide useful functions +that are implemented directly through the C API. +Some of these functions provide essential services to the language +(e.g., type and getmetatable); +others provide access to "outside" services (e.g., I/O); +and others could be implemented in Lua itself, +but are quite useful or have critical performance requirements that +deserve an implementation in C (e.g., table.sort). + + +

+All libraries are implemented through the official C API +and are provided as separate C modules. +Currently, Lua has the following standard libraries: + +

    + +
  • basic library (§6.1);
  • + +
  • coroutine library (§6.2);
  • + +
  • package library (§6.3);
  • + +
  • string manipulation (§6.4);
  • + +
  • table manipulation (§6.5);
  • + +
  • mathematical functions (§6.6) (sin, log, etc.);
  • + +
  • bitwise operations (§6.7);
  • + +
  • input and output (§6.8);
  • + +
  • operating system facilities (§6.9);
  • + +
  • debug facilities (§6.10).
  • + +

+Except for the basic and the package libraries, +each library provides all its functions as fields of a global table +or as methods of its objects. + + +

+To have access to these libraries, +the C host program should call the luaL_openlibs function, +which opens all standard libraries. +Alternatively, +the host program can open them individually by using +luaL_requiref to call +luaopen_base (for the basic library), +luaopen_package (for the package library), +luaopen_coroutine (for the coroutine library), +luaopen_string (for the string library), +luaopen_table (for the table library), +luaopen_math (for the mathematical library), +luaopen_bit32 (for the bit library), +luaopen_io (for the I/O library), +luaopen_os (for the Operating System library), +and luaopen_debug (for the debug library). +These functions are declared in lualib.h. + + + +

6.1 – Basic Functions

+ +

+The basic library provides core functions to Lua. +If you do not include this library in your application, +you should check carefully whether you need to provide +implementations for some of its facilities. + + +

+


assert (v [, message])

+Issues an error when +the value of its argument v is false (i.e., nil or false); +otherwise, returns all its arguments. +message is an error message; +when absent, it defaults to "assertion failed!" + + + + +

+


collectgarbage ([opt [, arg]])

+ + +

+This function is a generic interface to the garbage collector. +It performs different functions according to its first argument, opt: + +

    + +
  • "collect": +performs a full garbage-collection cycle. +This is the default option. +
  • + +
  • "stop": +stops automatic execution of the garbage collector. +The collector will run only when explicitly invoked, +until a call to restart it. +
  • + +
  • "restart": +restarts automatic execution of the garbage collector. +
  • + +
  • "count": +returns the total memory in use by Lua (in Kbytes) and +a second value with the total memory in bytes modulo 1024. +The first value has a fractional part, +so the following equality is always true: + +
    +     k, b = collectgarbage("count")
    +     assert(k*1024 == math.floor(k)*1024 + b)
    +

    +(The second result is useful when Lua is compiled +with a non floating-point type for numbers.) +

  • + +
  • "step": +performs a garbage-collection step. +The step "size" is controlled by arg +(larger values mean more steps) in a non-specified way. +If you want to control the step size +you must experimentally tune the value of arg. +Returns true if the step finished a collection cycle. +
  • + +
  • "setpause": +sets arg as the new value for the pause of +the collector (see §2.5). +Returns the previous value for pause. +
  • + +
  • "setstepmul": +sets arg as the new value for the step multiplier of +the collector (see §2.5). +Returns the previous value for step. +
  • + +
  • "isrunning": +returns a boolean that tells whether the collector is running +(i.e., not stopped). +
  • + +
  • "generational": +changes the collector to generational mode. +This is an experimental feature (see §2.5). +
  • + +
  • "incremental": +changes the collector to incremental mode. +This is the default mode. +
  • + +
+ + + +

+


dofile ([filename])

+Opens the named file and executes its contents as a Lua chunk. +When called without arguments, +dofile executes the contents of the standard input (stdin). +Returns all values returned by the chunk. +In case of errors, dofile propagates the error +to its caller (that is, dofile does not run in protected mode). + + + + +

+


error (message [, level])

+Terminates the last protected function called +and returns message as the error message. +Function error never returns. + + +

+Usually, error adds some information about the error position +at the beginning of the message, if the message is a string. +The level argument specifies how to get the error position. +With level 1 (the default), the error position is where the +error function was called. +Level 2 points the error to where the function +that called error was called; and so on. +Passing a level 0 avoids the addition of error position information +to the message. + + + + +

+


_G

+A global variable (not a function) that +holds the global environment (see §2.2). +Lua itself does not use this variable; +changing its value does not affect any environment, +nor vice-versa. + + + + +

+


getmetatable (object)

+ + +

+If object does not have a metatable, returns nil. +Otherwise, +if the object's metatable has a "__metatable" field, +returns the associated value. +Otherwise, returns the metatable of the given object. + + + + +

+


ipairs (t)

+ + +

+If t has a metamethod __ipairs, +calls it with t as argument and returns the first three +results from the call. + + +

+Otherwise, +returns three values: an iterator function, the table t, and 0, +so that the construction + +

+     for i,v in ipairs(t) do body end
+

+will iterate over the pairs (1,t[1]), (2,t[2]), ..., +up to the first integer key absent from the table. + + + + +

+


load (ld [, source [, mode [, env]]])

+ + +

+Loads a chunk. + + +

+If ld is a string, the chunk is this string. +If ld is a function, +load calls it repeatedly to get the chunk pieces. +Each call to ld must return a string that concatenates +with previous results. +A return of an empty string, nil, or no value signals the end of the chunk. + + +

+If there are no syntactic errors, +returns the compiled chunk as a function; +otherwise, returns nil plus the error message. + + +

+If the resulting function has upvalues, +the first upvalue is set to the value of env, +if that parameter is given, +or to the value of the global environment. +(When you load a main chunk, +the resulting function will always have exactly one upvalue, +the _ENV variable (see §2.2). +When you load a binary chunk created from a function (see string.dump), +the resulting function can have arbitrary upvalues.) + + +

+source is used as the source of the chunk for error messages +and debug information (see §4.9). +When absent, +it defaults to ld, if ld is a string, +or to "=(load)" otherwise. + + +

+The string mode controls whether the chunk can be text or binary +(that is, a precompiled chunk). +It may be the string "b" (only binary chunks), +"t" (only text chunks), +or "bt" (both binary and text). +The default is "bt". + + + + +

+


loadfile ([filename [, mode [, env]]])

+ + +

+Similar to load, +but gets the chunk from file filename +or from the standard input, +if no file name is given. + + + + +

+


next (table [, index])

+ + +

+Allows a program to traverse all fields of a table. +Its first argument is a table and its second argument +is an index in this table. +next returns the next index of the table +and its associated value. +When called with nil as its second argument, +next returns an initial index +and its associated value. +When called with the last index, +or with nil in an empty table, +next returns nil. +If the second argument is absent, then it is interpreted as nil. +In particular, +you can use next(t) to check whether a table is empty. + + +

+The order in which the indices are enumerated is not specified, +even for numeric indices. +(To traverse a table in numeric order, +use a numerical for.) + + +

+The behavior of next is undefined if, +during the traversal, +you assign any value to a non-existent field in the table. +You may however modify existing fields. +In particular, you may clear existing fields. + + + + +

+


pairs (t)

+ + +

+If t has a metamethod __pairs, +calls it with t as argument and returns the first three +results from the call. + + +

+Otherwise, +returns three values: the next function, the table t, and nil, +so that the construction + +

+     for k,v in pairs(t) do body end
+

+will iterate over all key–value pairs of table t. + + +

+See function next for the caveats of modifying +the table during its traversal. + + + + +

+


pcall (f [, arg1, ···])

+ + +

+Calls function f with +the given arguments in protected mode. +This means that any error inside f is not propagated; +instead, pcall catches the error +and returns a status code. +Its first result is the status code (a boolean), +which is true if the call succeeds without errors. +In such case, pcall also returns all results from the call, +after this first result. +In case of any error, pcall returns false plus the error message. + + + + +

+


print (···)

+Receives any number of arguments +and prints their values to stdout, +using the tostring function to convert each argument to a string. +print is not intended for formatted output, +but only as a quick way to show a value, +for instance for debugging. +For complete control over the output, +use string.format and io.write. + + + + +

+


rawequal (v1, v2)

+Checks whether v1 is equal to v2, +without invoking any metamethod. +Returns a boolean. + + + + +

+


rawget (table, index)

+Gets the real value of table[index], +without invoking any metamethod. +table must be a table; +index may be any value. + + + + +

+


rawlen (v)

+Returns the length of the object v, +which must be a table or a string, +without invoking any metamethod. +Returns an integer number. + + + + +

+


rawset (table, index, value)

+Sets the real value of table[index] to value, +without invoking any metamethod. +table must be a table, +index any value different from nil and NaN, +and value any Lua value. + + +

+This function returns table. + + + + +

+


select (index, ···)

+ + +

+If index is a number, +returns all arguments after argument number index; +a negative number indexes from the end (-1 is the last argument). +Otherwise, index must be the string "#", +and select returns the total number of extra arguments it received. + + + + +

+


setmetatable (table, metatable)

+ + +

+Sets the metatable for the given table. +(You cannot change the metatable of other types from Lua, only from C.) +If metatable is nil, +removes the metatable of the given table. +If the original metatable has a "__metatable" field, +raises an error. + + +

+This function returns table. + + + + +

+


tonumber (e [, base])

+ + +

+When called with no base, +tonumber tries to convert its argument to a number. +If the argument is already a number or +a string convertible to a number (see §3.4.2), +then tonumber returns this number; +otherwise, it returns nil. + + +

+When called with base, +then e should be a string to be interpreted as +an integer numeral in that base. +The base may be any integer between 2 and 36, inclusive. +In bases above 10, the letter 'A' (in either upper or lower case) +represents 10, 'B' represents 11, and so forth, +with 'Z' representing 35. +If the string e is not a valid numeral in the given base, +the function returns nil. + + + + +

+


tostring (v)

+Receives a value of any type and +converts it to a string in a reasonable format. +(For complete control of how numbers are converted, +use string.format.) + + +

+If the metatable of v has a "__tostring" field, +then tostring calls the corresponding value +with v as argument, +and uses the result of the call as its result. + + + + +

+


type (v)

+Returns the type of its only argument, coded as a string. +The possible results of this function are +"nil" (a string, not the value nil), +"number", +"string", +"boolean", +"table", +"function", +"thread", +and "userdata". + + + + +

+


_VERSION

+A global variable (not a function) that +holds a string containing the current interpreter version. +The current contents of this variable is "Lua 5.2". + + + + +

+


xpcall (f, msgh [, arg1, ···])

+ + +

+This function is similar to pcall, +except that it sets a new message handler msgh. + + + + + + + +

6.2 – Coroutine Manipulation

+ +

+The operations related to coroutines comprise a sub-library of +the basic library and come inside the table coroutine. +See §2.6 for a general description of coroutines. + + +

+


coroutine.create (f)

+ + +

+Creates a new coroutine, with body f. +f must be a Lua function. +Returns this new coroutine, +an object with type "thread". + + + + +

+


coroutine.resume (co [, val1, ···])

+ + +

+Starts or continues the execution of coroutine co. +The first time you resume a coroutine, +it starts running its body. +The values val1, ... are passed +as the arguments to the body function. +If the coroutine has yielded, +resume restarts it; +the values val1, ... are passed +as the results from the yield. + + +

+If the coroutine runs without any errors, +resume returns true plus any values passed to yield +(if the coroutine yields) or any values returned by the body function +(if the coroutine terminates). +If there is any error, +resume returns false plus the error message. + + + + +

+


coroutine.running ()

+ + +

+Returns the running coroutine plus a boolean, +true when the running coroutine is the main one. + + + + +

+


coroutine.status (co)

+ + +

+Returns the status of coroutine co, as a string: +"running", +if the coroutine is running (that is, it called status); +"suspended", if the coroutine is suspended in a call to yield, +or if it has not started running yet; +"normal" if the coroutine is active but not running +(that is, it has resumed another coroutine); +and "dead" if the coroutine has finished its body function, +or if it has stopped with an error. + + + + +

+


coroutine.wrap (f)

+ + +

+Creates a new coroutine, with body f. +f must be a Lua function. +Returns a function that resumes the coroutine each time it is called. +Any arguments passed to the function behave as the +extra arguments to resume. +Returns the same values returned by resume, +except the first boolean. +In case of error, propagates the error. + + + + +

+


coroutine.yield (···)

+ + +

+Suspends the execution of the calling coroutine. +Any arguments to yield are passed as extra results to resume. + + + + + + + +

6.3 – Modules

+ +

+The package library provides basic +facilities for loading modules in Lua. +It exports one function directly in the global environment: +require. +Everything else is exported in a table package. + + +

+


require (modname)

+ + +

+Loads the given module. +The function starts by looking into the package.loaded table +to determine whether modname is already loaded. +If it is, then require returns the value stored +at package.loaded[modname]. +Otherwise, it tries to find a loader for the module. + + +

+To find a loader, +require is guided by the package.searchers sequence. +By changing this sequence, +we can change how require looks for a module. +The following explanation is based on the default configuration +for package.searchers. + + +

+First require queries package.preload[modname]. +If it has a value, +this value (which should be a function) is the loader. +Otherwise require searches for a Lua loader using the +path stored in package.path. +If that also fails, it searches for a C loader using the +path stored in package.cpath. +If that also fails, +it tries an all-in-one loader (see package.searchers). + + +

+Once a loader is found, +require calls the loader with two arguments: +modname and an extra value dependent on how it got the loader. +(If the loader came from a file, +this extra value is the file name.) +If the loader returns any non-nil value, +require assigns the returned value to package.loaded[modname]. +If the loader does not return a non-nil value and +has not assigned any value to package.loaded[modname], +then require assigns true to this entry. +In any case, require returns the +final value of package.loaded[modname]. + + +

+If there is any error loading or running the module, +or if it cannot find any loader for the module, +then require raises an error. + + + + +

+


package.config

+ + +

+A string describing some compile-time configurations for packages. +This string is a sequence of lines: + +

    + +
  • The first line is the directory separator string. +Default is '\' for Windows and '/' for all other systems.
  • + +
  • The second line is the character that separates templates in a path. +Default is ';'.
  • + +
  • The third line is the string that marks the +substitution points in a template. +Default is '?'.
  • + +
  • The fourth line is a string that, in a path in Windows, +is replaced by the executable's directory. +Default is '!'.
  • + +
  • The fifth line is a mark to ignore all text before it +when building the luaopen_ function name. +Default is '-'.
  • + +
+ + + +

+


package.cpath

+ + +

+The path used by require to search for a C loader. + + +

+Lua initializes the C path package.cpath in the same way +it initializes the Lua path package.path, +using the environment variable LUA_CPATH_5_2 +or the environment variable LUA_CPATH +or a default path defined in luaconf.h. + + + + +

+


package.loaded

+ + +

+A table used by require to control which +modules are already loaded. +When you require a module modname and +package.loaded[modname] is not false, +require simply returns the value stored there. + + +

+This variable is only a reference to the real table; +assignments to this variable do not change the +table used by require. + + + + +

+


package.loadlib (libname, funcname)

+ + +

+Dynamically links the host program with the C library libname. + + +

+If funcname is "*", +then it only links with the library, +making the symbols exported by the library +available to other dynamically linked libraries. +Otherwise, +it looks for a function funcname inside the library +and returns this function as a C function. +So, funcname must follow the lua_CFunction prototype +(see lua_CFunction). + + +

+This is a low-level function. +It completely bypasses the package and module system. +Unlike require, +it does not perform any path searching and +does not automatically adds extensions. +libname must be the complete file name of the C library, +including if necessary a path and an extension. +funcname must be the exact name exported by the C library +(which may depend on the C compiler and linker used). + + +

+This function is not supported by Standard C. +As such, it is only available on some platforms +(Windows, Linux, Mac OS X, Solaris, BSD, +plus other Unix systems that support the dlfcn standard). + + + + +

+


package.path

+ + +

+The path used by require to search for a Lua loader. + + +

+At start-up, Lua initializes this variable with +the value of the environment variable LUA_PATH_5_2 or +the environment variable LUA_PATH or +with a default path defined in luaconf.h, +if those environment variables are not defined. +Any ";;" in the value of the environment variable +is replaced by the default path. + + + + +

+


package.preload

+ + +

+A table to store loaders for specific modules +(see require). + + +

+This variable is only a reference to the real table; +assignments to this variable do not change the +table used by require. + + + + +

+


package.searchers

+ + +

+A table used by require to control how to load modules. + + +

+Each entry in this table is a searcher function. +When looking for a module, +require calls each of these searchers in ascending order, +with the module name (the argument given to require) as its +sole parameter. +The function can return another function (the module loader) +plus an extra value that will be passed to that loader, +or a string explaining why it did not find that module +(or nil if it has nothing to say). + + +

+Lua initializes this table with four searcher functions. + + +

+The first searcher simply looks for a loader in the +package.preload table. + + +

+The second searcher looks for a loader as a Lua library, +using the path stored at package.path. +The search is done as described in function package.searchpath. + + +

+The third searcher looks for a loader as a C library, +using the path given by the variable package.cpath. +Again, +the search is done as described in function package.searchpath. +For instance, +if the C path is the string + +

+     "./?.so;./?.dll;/usr/local/?/init.so"
+

+the searcher for module foo +will try to open the files ./foo.so, ./foo.dll, +and /usr/local/foo/init.so, in that order. +Once it finds a C library, +this searcher first uses a dynamic link facility to link the +application with the library. +Then it tries to find a C function inside the library to +be used as the loader. +The name of this C function is the string "luaopen_" +concatenated with a copy of the module name where each dot +is replaced by an underscore. +Moreover, if the module name has a hyphen, +its prefix up to (and including) the first hyphen is removed. +For instance, if the module name is a.v1-b.c, +the function name will be luaopen_b_c. + + +

+The fourth searcher tries an all-in-one loader. +It searches the C path for a library for +the root name of the given module. +For instance, when requiring a.b.c, +it will search for a C library for a. +If found, it looks into it for an open function for +the submodule; +in our example, that would be luaopen_a_b_c. +With this facility, a package can pack several C submodules +into one single library, +with each submodule keeping its original open function. + + +

+All searchers except the first one (preload) return as the extra value +the file name where the module was found, +as returned by package.searchpath. +The first searcher returns no extra value. + + + + +

+


package.searchpath (name, path [, sep [, rep]])

+ + +

+Searches for the given name in the given path. + + +

+A path is a string containing a sequence of +templates separated by semicolons. +For each template, +the function replaces each interrogation mark (if any) +in the template with a copy of name +wherein all occurrences of sep +(a dot, by default) +were replaced by rep +(the system's directory separator, by default), +and then tries to open the resulting file name. + + +

+For instance, if the path is the string + +

+     "./?.lua;./?.lc;/usr/local/?/init.lua"
+

+the search for the name foo.a +will try to open the files +./foo/a.lua, ./foo/a.lc, and +/usr/local/foo/a/init.lua, in that order. + + +

+Returns the resulting name of the first file that it can +open in read mode (after closing the file), +or nil plus an error message if none succeeds. +(This error message lists all file names it tried to open.) + + + + + + + +

6.4 – String Manipulation

+ +

+This library provides generic functions for string manipulation, +such as finding and extracting substrings, and pattern matching. +When indexing a string in Lua, the first character is at position 1 +(not at 0, as in C). +Indices are allowed to be negative and are interpreted as indexing backwards, +from the end of the string. +Thus, the last character is at position -1, and so on. + + +

+The string library provides all its functions inside the table +string. +It also sets a metatable for strings +where the __index field points to the string table. +Therefore, you can use the string functions in object-oriented style. +For instance, string.byte(s,i) +can be written as s:byte(i). + + +

+The string library assumes one-byte character encodings. + + +

+


string.byte (s [, i [, j]])

+Returns the internal numerical codes of the characters s[i], +s[i+1], ..., s[j]. +The default value for i is 1; +the default value for j is i. +These indices are corrected +following the same rules of function string.sub. + + +

+Numerical codes are not necessarily portable across platforms. + + + + +

+


string.char (···)

+Receives zero or more integers. +Returns a string with length equal to the number of arguments, +in which each character has the internal numerical code equal +to its corresponding argument. + + +

+Numerical codes are not necessarily portable across platforms. + + + + +

+


string.dump (function)

+ + +

+Returns a string containing a binary representation of the given function, +so that a later load on this string returns +a copy of the function (but with new upvalues). + + + + +

+


string.find (s, pattern [, init [, plain]])

+ + +

+Looks for the first match of +pattern in the string s. +If it finds a match, then find returns the indices of s +where this occurrence starts and ends; +otherwise, it returns nil. +A third, optional numerical argument init specifies +where to start the search; +its default value is 1 and can be negative. +A value of true as a fourth, optional argument plain +turns off the pattern matching facilities, +so the function does a plain "find substring" operation, +with no characters in pattern being considered magic. +Note that if plain is given, then init must be given as well. + + +

+If the pattern has captures, +then in a successful match +the captured values are also returned, +after the two indices. + + + + +

+


string.format (formatstring, ···)

+ + +

+Returns a formatted version of its variable number of arguments +following the description given in its first argument (which must be a string). +The format string follows the same rules as the ANSI C function sprintf. +The only differences are that the options/modifiers +*, h, L, l, n, +and p are not supported +and that there is an extra option, q. +The q option formats a string between double quotes, +using escape sequences when necessary to ensure that +it can safely be read back by the Lua interpreter. +For instance, the call + +

+     string.format('%q', 'a string with "quotes" and \n new line')
+

+may produce the string: + +

+     "a string with \"quotes\" and \
+      new line"
+
+ +

+Options +A and a (when available), +E, e, f, +G, and g all expect a number as argument. +Options c, d, +i, o, u, X, and x +also expect a number, +but the range of that number may be limited by +the underlying C implementation. +For options o, u, X, and x, +the number cannot be negative. +Option q expects a string; +option s expects a string without embedded zeros. +If the argument to option s is not a string, +it is converted to one following the same rules of tostring. + + + + +

+


string.gmatch (s, pattern)

+Returns an iterator function that, +each time it is called, +returns the next captures from pattern over the string s. +If pattern specifies no captures, +then the whole match is produced in each call. + + +

+As an example, the following loop +will iterate over all the words from string s, +printing one per line: + +

+     s = "hello world from Lua"
+     for w in string.gmatch(s, "%a+") do
+       print(w)
+     end
+

+The next example collects all pairs key=value from the +given string into a table: + +

+     t = {}
+     s = "from=world, to=Lua"
+     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
+       t[k] = v
+     end
+
+ +

+For this function, a caret '^' at the start of a pattern does not +work as an anchor, as this would prevent the iteration. + + + + +

+


string.gsub (s, pattern, repl [, n])

+Returns a copy of s +in which all (or the first n, if given) +occurrences of the pattern have been +replaced by a replacement string specified by repl, +which can be a string, a table, or a function. +gsub also returns, as its second value, +the total number of matches that occurred. +The name gsub comes from Global SUBstitution. + + +

+If repl is a string, then its value is used for replacement. +The character % works as an escape character: +any sequence in repl of the form %d, +with d between 1 and 9, +stands for the value of the d-th captured substring. +The sequence %0 stands for the whole match. +The sequence %% stands for a single %. + + +

+If repl is a table, then the table is queried for every match, +using the first capture as the key. + + +

+If repl is a function, then this function is called every time a +match occurs, with all captured substrings passed as arguments, +in order. + + +

+In any case, +if the pattern specifies no captures, +then it behaves as if the whole pattern was inside a capture. + + +

+If the value returned by the table query or by the function call +is a string or a number, +then it is used as the replacement string; +otherwise, if it is false or nil, +then there is no replacement +(that is, the original match is kept in the string). + + +

+Here are some examples: + +

+     x = string.gsub("hello world", "(%w+)", "%1 %1")
+     --> x="hello hello world world"
+     
+     x = string.gsub("hello world", "%w+", "%0 %0", 1)
+     --> x="hello hello world"
+     
+     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
+     --> x="world hello Lua from"
+     
+     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
+     --> x="home = /home/roberto, user = roberto"
+     
+     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
+           return load(s)()
+         end)
+     --> x="4+5 = 9"
+     
+     local t = {name="lua", version="5.2"}
+     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
+     --> x="lua-5.2.tar.gz"
+
+ + + +

+


string.len (s)

+Receives a string and returns its length. +The empty string "" has length 0. +Embedded zeros are counted, +so "a\000bc\000" has length 5. + + + + +

+


string.lower (s)

+Receives a string and returns a copy of this string with all +uppercase letters changed to lowercase. +All other characters are left unchanged. +The definition of what an uppercase letter is depends on the current locale. + + + + +

+


string.match (s, pattern [, init])

+Looks for the first match of +pattern in the string s. +If it finds one, then match returns +the captures from the pattern; +otherwise it returns nil. +If pattern specifies no captures, +then the whole match is returned. +A third, optional numerical argument init specifies +where to start the search; +its default value is 1 and can be negative. + + + + +

+


string.rep (s, n [, sep])

+Returns a string that is the concatenation of n copies of +the string s separated by the string sep. +The default value for sep is the empty string +(that is, no separator). + + + + +

+


string.reverse (s)

+Returns a string that is the string s reversed. + + + + +

+


string.sub (s, i [, j])

+Returns the substring of s that +starts at i and continues until j; +i and j can be negative. +If j is absent, then it is assumed to be equal to -1 +(which is the same as the string length). +In particular, +the call string.sub(s,1,j) returns a prefix of s +with length j, +and string.sub(s, -i) returns a suffix of s +with length i. + + +

+If, after the translation of negative indices, +i is less than 1, +it is corrected to 1. +If j is greater than the string length, +it is corrected to that length. +If, after these corrections, +i is greater than j, +the function returns the empty string. + + + + +

+


string.upper (s)

+Receives a string and returns a copy of this string with all +lowercase letters changed to uppercase. +All other characters are left unchanged. +The definition of what a lowercase letter is depends on the current locale. + + + +

6.4.1 – Patterns

+ + +

Character Class:

+A character class is used to represent a set of characters. +The following combinations are allowed in describing a character class: + +

    + +
  • x: +(where x is not one of the magic characters +^$()%.[]*+-?) +represents the character x itself. +
  • + +
  • .: (a dot) represents all characters.
  • + +
  • %a: represents all letters.
  • + +
  • %c: represents all control characters.
  • + +
  • %d: represents all digits.
  • + +
  • %g: represents all printable characters except space.
  • + +
  • %l: represents all lowercase letters.
  • + +
  • %p: represents all punctuation characters.
  • + +
  • %s: represents all space characters.
  • + +
  • %u: represents all uppercase letters.
  • + +
  • %w: represents all alphanumeric characters.
  • + +
  • %x: represents all hexadecimal digits.
  • + +
  • %x: (where x is any non-alphanumeric character) +represents the character x. +This is the standard way to escape the magic characters. +Any punctuation character (even the non magic) +can be preceded by a '%' +when used to represent itself in a pattern. +
  • + +
  • [set]: +represents the class which is the union of all +characters in set. +A range of characters can be specified by +separating the end characters of the range, +in ascending order, with a '-', +All classes %x described above can also be used as +components in set. +All other characters in set represent themselves. +For example, [%w_] (or [_%w]) +represents all alphanumeric characters plus the underscore, +[0-7] represents the octal digits, +and [0-7%l%-] represents the octal digits plus +the lowercase letters plus the '-' character. + + +

    +The interaction between ranges and classes is not defined. +Therefore, patterns like [%a-z] or [a-%%] +have no meaning. +

  • + +
  • [^set]: +represents the complement of set, +where set is interpreted as above. +
  • + +

+For all classes represented by single letters (%a, %c, etc.), +the corresponding uppercase letter represents the complement of the class. +For instance, %S represents all non-space characters. + + +

+The definitions of letter, space, and other character groups +depend on the current locale. +In particular, the class [a-z] may not be equivalent to %l. + + + + + +

Pattern Item:

+A pattern item can be + +

    + +
  • +a single character class, +which matches any single character in the class; +
  • + +
  • +a single character class followed by '*', +which matches 0 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
  • + +
  • +a single character class followed by '+', +which matches 1 or more repetitions of characters in the class. +These repetition items will always match the longest possible sequence; +
  • + +
  • +a single character class followed by '-', +which also matches 0 or more repetitions of characters in the class. +Unlike '*', +these repetition items will always match the shortest possible sequence; +
  • + +
  • +a single character class followed by '?', +which matches 0 or 1 occurrence of a character in the class; +
  • + +
  • +%n, for n between 1 and 9; +such item matches a substring equal to the n-th captured string +(see below); +
  • + +
  • +%bxy, where x and y are two distinct characters; +such item matches strings that start with x, end with y, +and where the x and y are balanced. +This means that, if one reads the string from left to right, +counting +1 for an x and -1 for a y, +the ending y is the first y where the count reaches 0. +For instance, the item %b() matches expressions with +balanced parentheses. +
  • + +
  • +%f[set], a frontier pattern; +such item matches an empty string at any position such that +the next character belongs to set +and the previous character does not belong to set. +The set set is interpreted as previously described. +The beginning and the end of the subject are handled as if +they were the character '\0'. +
  • + +
+ + + + +

Pattern:

+A pattern is a sequence of pattern items. +A caret '^' at the beginning of a pattern anchors the match at the +beginning of the subject string. +A '$' at the end of a pattern anchors the match at the +end of the subject string. +At other positions, +'^' and '$' have no special meaning and represent themselves. + + + + + +

Captures:

+A pattern can contain sub-patterns enclosed in parentheses; +they describe captures. +When a match succeeds, the substrings of the subject string +that match captures are stored (captured) for future use. +Captures are numbered according to their left parentheses. +For instance, in the pattern "(a*(.)%w(%s*))", +the part of the string matching "a*(.)%w(%s*)" is +stored as the first capture (and therefore has number 1); +the character matching "." is captured with number 2, +and the part matching "%s*" has number 3. + + +

+As a special case, the empty capture () captures +the current string position (a number). +For instance, if we apply the pattern "()aa()" on the +string "flaaap", there will be two captures: 3 and 5. + + + + + + + + + + + +

6.5 – Table Manipulation

+ +

+This library provides generic functions for table manipulation. +It provides all its functions inside the table table. + + +

+Remember that, whenever an operation needs the length of a table, +the table should be a proper sequence +or have a __len metamethod (see §3.4.6). +All functions ignore non-numeric keys +in tables given as arguments. + + +

+For performance reasons, +all table accesses (get/set) performed by these functions are raw. + + +

+


table.concat (list [, sep [, i [, j]]])

+ + +

+Given a list where all elements are strings or numbers, +returns the string list[i]..sep..list[i+1] ··· sep..list[j]. +The default value for sep is the empty string, +the default for i is 1, +and the default for j is #list. +If i is greater than j, returns the empty string. + + + + +

+


table.insert (list, [pos,] value)

+ + +

+Inserts element value at position pos in list, +shifting up the elements +list[pos], list[pos+1], ···, list[#list]. +The default value for pos is #list+1, +so that a call table.insert(t,x) inserts x at the end +of list t. + + + + +

+


table.pack (···)

+ + +

+Returns a new table with all parameters stored into keys 1, 2, etc. +and with a field "n" with the total number of parameters. +Note that the resulting table may not be a sequence. + + + + +

+


table.remove (list [, pos])

+ + +

+Removes from list the element at position pos, +returning the value of the removed element. +When pos is an integer between 1 and #list, +it shifts down the elements +list[pos+1], list[pos+2], ···, list[#list] +and erases element list[#list]; +The index pos can also be 0 when #list is 0, +or #list + 1; +in those cases, the function erases the element list[pos]. + + +

+The default value for pos is #list, +so that a call table.remove(t) removes the last element +of list t. + + + + +

+


table.sort (list [, comp])

+ + +

+Sorts list elements in a given order, in-place, +from list[1] to list[#list]. +If comp is given, +then it must be a function that receives two list elements +and returns true when the first element must come +before the second in the final order +(so that not comp(list[i+1],list[i]) will be true after the sort). +If comp is not given, +then the standard Lua operator < is used instead. + + +

+The sort algorithm is not stable; +that is, elements considered equal by the given order +may have their relative positions changed by the sort. + + + + +

+


table.unpack (list [, i [, j]])

+ + +

+Returns the elements from the given table. +This function is equivalent to + +

+     return list[i], list[i+1], ···, list[j]
+

+By default, i is 1 and j is #list. + + + + + + + +

6.6 – Mathematical Functions

+ +

+This library is an interface to the standard C math library. +It provides all its functions inside the table math. + + +

+


math.abs (x)

+ + +

+Returns the absolute value of x. + + + + +

+


math.acos (x)

+ + +

+Returns the arc cosine of x (in radians). + + + + +

+


math.asin (x)

+ + +

+Returns the arc sine of x (in radians). + + + + +

+


math.atan (x)

+ + +

+Returns the arc tangent of x (in radians). + + + + +

+


math.atan2 (y, x)

+ + +

+Returns the arc tangent of y/x (in radians), +but uses the signs of both parameters to find the +quadrant of the result. +(It also handles correctly the case of x being zero.) + + + + +

+


math.ceil (x)

+ + +

+Returns the smallest integer larger than or equal to x. + + + + +

+


math.cos (x)

+ + +

+Returns the cosine of x (assumed to be in radians). + + + + +

+


math.cosh (x)

+ + +

+Returns the hyperbolic cosine of x. + + + + +

+


math.deg (x)

+ + +

+Returns the angle x (given in radians) in degrees. + + + + +

+


math.exp (x)

+ + +

+Returns the value ex. + + + + +

+


math.floor (x)

+ + +

+Returns the largest integer smaller than or equal to x. + + + + +

+


math.fmod (x, y)

+ + +

+Returns the remainder of the division of x by y +that rounds the quotient towards zero. + + + + +

+


math.frexp (x)

+ + +

+Returns m and e such that x = m2e, +e is an integer and the absolute value of m is +in the range [0.5, 1) +(or zero when x is zero). + + + + +

+


math.huge

+ + +

+The value HUGE_VAL, +a value larger than or equal to any other numerical value. + + + + +

+


math.ldexp (m, e)

+ + +

+Returns m2e (e should be an integer). + + + + +

+


math.log (x [, base])

+ + +

+Returns the logarithm of x in the given base. +The default for base is e +(so that the function returns the natural logarithm of x). + + + + +

+


math.max (x, ···)

+ + +

+Returns the maximum value among its arguments. + + + + +

+


math.min (x, ···)

+ + +

+Returns the minimum value among its arguments. + + + + +

+


math.modf (x)

+ + +

+Returns two numbers, +the integral part of x and the fractional part of x. + + + + +

+


math.pi

+ + +

+The value of π. + + + + +

+


math.pow (x, y)

+ + +

+Returns xy. +(You can also use the expression x^y to compute this value.) + + + + +

+


math.rad (x)

+ + +

+Returns the angle x (given in degrees) in radians. + + + + +

+


math.random ([m [, n]])

+ + +

+This function is an interface to the simple +pseudo-random generator function rand provided by Standard C. +(No guarantees can be given for its statistical properties.) + + +

+When called without arguments, +returns a uniform pseudo-random real number +in the range [0,1). +When called with an integer number m, +math.random returns +a uniform pseudo-random integer in the range [1, m]. +When called with two integer numbers m and n, +math.random returns a uniform pseudo-random +integer in the range [m, n]. + + + + +

+


math.randomseed (x)

+ + +

+Sets x as the "seed" +for the pseudo-random generator: +equal seeds produce equal sequences of numbers. + + + + +

+


math.sin (x)

+ + +

+Returns the sine of x (assumed to be in radians). + + + + +

+


math.sinh (x)

+ + +

+Returns the hyperbolic sine of x. + + + + +

+


math.sqrt (x)

+ + +

+Returns the square root of x. +(You can also use the expression x^0.5 to compute this value.) + + + + +

+


math.tan (x)

+ + +

+Returns the tangent of x (assumed to be in radians). + + + + +

+


math.tanh (x)

+ + +

+Returns the hyperbolic tangent of x. + + + + + + + +

6.7 – Bitwise Operations

+ +

+This library provides bitwise operations. +It provides all its functions inside the table bit32. + + +

+Unless otherwise stated, +all functions accept numeric arguments in the range +(-251,+251); +each argument is normalized to +the remainder of its division by 232 +and truncated to an integer (in some unspecified way), +so that its final value falls in the range [0,232 - 1]. +Similarly, all results are in the range [0,232 - 1]. +Note that bit32.bnot(0) is 0xFFFFFFFF, +which is different from -1. + + +

+


bit32.arshift (x, disp)

+ + +

+Returns the number x shifted disp bits to the right. +The number disp may be any representable integer. +Negative displacements shift to the left. + + +

+This shift operation is what is called arithmetic shift. +Vacant bits on the left are filled +with copies of the higher bit of x; +vacant bits on the right are filled with zeros. +In particular, +displacements with absolute values higher than 31 +result in zero or 0xFFFFFFFF (all original bits are shifted out). + + + + +

+


bit32.band (···)

+ + +

+Returns the bitwise and of its operands. + + + + +

+


bit32.bnot (x)

+ + +

+Returns the bitwise negation of x. +For any integer x, +the following identity holds: + +

+     assert(bit32.bnot(x) == (-1 - x) % 2^32)
+
+ + + +

+


bit32.bor (···)

+ + +

+Returns the bitwise or of its operands. + + + + +

+


bit32.btest (···)

+ + +

+Returns a boolean signaling +whether the bitwise and of its operands is different from zero. + + + + +

+


bit32.bxor (···)

+ + +

+Returns the bitwise exclusive or of its operands. + + + + +

+


bit32.extract (n, field [, width])

+ + +

+Returns the unsigned number formed by the bits +field to field + width - 1 from n. +Bits are numbered from 0 (least significant) to 31 (most significant). +All accessed bits must be in the range [0, 31]. + + +

+The default for width is 1. + + + + +

+


bit32.replace (n, v, field [, width])

+ + +

+Returns a copy of n with +the bits field to field + width - 1 +replaced by the value v. +See bit32.extract for details about field and width. + + + + +

+


bit32.lrotate (x, disp)

+ + +

+Returns the number x rotated disp bits to the left. +The number disp may be any representable integer. + + +

+For any valid displacement, +the following identity holds: + +

+     assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32))
+

+In particular, +negative displacements rotate to the right. + + + + +

+


bit32.lshift (x, disp)

+ + +

+Returns the number x shifted disp bits to the left. +The number disp may be any representable integer. +Negative displacements shift to the right. +In any direction, vacant bits are filled with zeros. +In particular, +displacements with absolute values higher than 31 +result in zero (all bits are shifted out). + + +

+For positive displacements, +the following equality holds: + +

+     assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32)
+
+ + + +

+


bit32.rrotate (x, disp)

+ + +

+Returns the number x rotated disp bits to the right. +The number disp may be any representable integer. + + +

+For any valid displacement, +the following identity holds: + +

+     assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32))
+

+In particular, +negative displacements rotate to the left. + + + + +

+


bit32.rshift (x, disp)

+ + +

+Returns the number x shifted disp bits to the right. +The number disp may be any representable integer. +Negative displacements shift to the left. +In any direction, vacant bits are filled with zeros. +In particular, +displacements with absolute values higher than 31 +result in zero (all bits are shifted out). + + +

+For positive displacements, +the following equality holds: + +

+     assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp))
+
+ +

+This shift operation is what is called logical shift. + + + + + + + +

6.8 – Input and Output Facilities

+ +

+The I/O library provides two different styles for file manipulation. +The first one uses implicit file descriptors; +that is, there are operations to set a default input file and a +default output file, +and all input/output operations are over these default files. +The second style uses explicit file descriptors. + + +

+When using implicit file descriptors, +all operations are supplied by table io. +When using explicit file descriptors, +the operation io.open returns a file descriptor +and then all operations are supplied as methods of the file descriptor. + + +

+The table io also provides +three predefined file descriptors with their usual meanings from C: +io.stdin, io.stdout, and io.stderr. +The I/O library never closes these files. + + +

+Unless otherwise stated, +all I/O functions return nil on failure +(plus an error message as a second result and +a system-dependent error code as a third result) +and some value different from nil on success. +On non-Posix systems, +the computation of the error message and error code +in case of errors +may be not thread safe, +because they rely on the global C variable errno. + + +

+


io.close ([file])

+ + +

+Equivalent to file:close(). +Without a file, closes the default output file. + + + + +

+


io.flush ()

+ + +

+Equivalent to io.output():flush(). + + + + +

+


io.input ([file])

+ + +

+When called with a file name, it opens the named file (in text mode), +and sets its handle as the default input file. +When called with a file handle, +it simply sets this file handle as the default input file. +When called without parameters, +it returns the current default input file. + + +

+In case of errors this function raises the error, +instead of returning an error code. + + + + +

+


io.lines ([filename ···])

+ + +

+Opens the given file name in read mode +and returns an iterator function that +works like file:lines(···) over the opened file. +When the iterator function detects the end of file, +it returns nil (to finish the loop) and automatically closes the file. + + +

+The call io.lines() (with no file name) is equivalent +to io.input():lines(); +that is, it iterates over the lines of the default input file. +In this case it does not close the file when the loop ends. + + +

+In case of errors this function raises the error, +instead of returning an error code. + + + + +

+


io.open (filename [, mode])

+ + +

+This function opens a file, +in the mode specified in the string mode. +It returns a new file handle, +or, in case of errors, nil plus an error message. + + +

+The mode string can be any of the following: + +

    +
  • "r": read mode (the default);
  • +
  • "w": write mode;
  • +
  • "a": append mode;
  • +
  • "r+": update mode, all previous data is preserved;
  • +
  • "w+": update mode, all previous data is erased;
  • +
  • "a+": append update mode, previous data is preserved, + writing is only allowed at the end of file.
  • +

+The mode string can also have a 'b' at the end, +which is needed in some systems to open the file in binary mode. + + + + +

+


io.output ([file])

+ + +

+Similar to io.input, but operates over the default output file. + + + + +

+


io.popen (prog [, mode])

+ + +

+This function is system dependent and is not available +on all platforms. + + +

+Starts program prog in a separated process and returns +a file handle that you can use to read data from this program +(if mode is "r", the default) +or to write data to this program +(if mode is "w"). + + + + +

+


io.read (···)

+ + +

+Equivalent to io.input():read(···). + + + + +

+


io.tmpfile ()

+ + +

+Returns a handle for a temporary file. +This file is opened in update mode +and it is automatically removed when the program ends. + + + + +

+


io.type (obj)

+ + +

+Checks whether obj is a valid file handle. +Returns the string "file" if obj is an open file handle, +"closed file" if obj is a closed file handle, +or nil if obj is not a file handle. + + + + +

+


io.write (···)

+ + +

+Equivalent to io.output():write(···). + + + + +

+


file:close ()

+ + +

+Closes file. +Note that files are automatically closed when +their handles are garbage collected, +but that takes an unpredictable amount of time to happen. + + +

+When closing a file handle created with io.popen, +file:close returns the same values +returned by os.execute. + + + + +

+


file:flush ()

+ + +

+Saves any written data to file. + + + + +

+


file:lines (···)

+ + +

+Returns an iterator function that, +each time it is called, +reads the file according to the given formats. +When no format is given, +uses "*l" as a default. +As an example, the construction + +

+     for c in file:lines(1) do body end
+

+will iterate over all characters of the file, +starting at the current position. +Unlike io.lines, this function does not close the file +when the loop ends. + + +

+In case of errors this function raises the error, +instead of returning an error code. + + + + +

+


file:read (···)

+ + +

+Reads the file file, +according to the given formats, which specify what to read. +For each format, +the function returns a string (or a number) with the characters read, +or nil if it cannot read data with the specified format. +When called without formats, +it uses a default format that reads the next line +(see below). + + +

+The available formats are + +

    + +
  • "*n": +reads a number; +this is the only format that returns a number instead of a string. +
  • + +
  • "*a": +reads the whole file, starting at the current position. +On end of file, it returns the empty string. +
  • + +
  • "*l": +reads the next line skipping the end of line, +returning nil on end of file. +This is the default format. +
  • + +
  • "*L": +reads the next line keeping the end of line (if present), +returning nil on end of file. +
  • + +
  • number: +reads a string with up to this number of bytes, +returning nil on end of file. +If number is zero, +it reads nothing and returns an empty string, +or nil on end of file. +
  • + +
+ + + +

+


file:seek ([whence [, offset]])

+ + +

+Sets and gets the file position, +measured from the beginning of the file, +to the position given by offset plus a base +specified by the string whence, as follows: + +

    +
  • "set": base is position 0 (beginning of the file);
  • +
  • "cur": base is current position;
  • +
  • "end": base is end of file;
  • +

+In case of success, seek returns the final file position, +measured in bytes from the beginning of the file. +If seek fails, it returns nil, +plus a string describing the error. + + +

+The default value for whence is "cur", +and for offset is 0. +Therefore, the call file:seek() returns the current +file position, without changing it; +the call file:seek("set") sets the position to the +beginning of the file (and returns 0); +and the call file:seek("end") sets the position to the +end of the file, and returns its size. + + + + +

+


file:setvbuf (mode [, size])

+ + +

+Sets the buffering mode for an output file. +There are three available modes: + +

    + +
  • "no": +no buffering; the result of any output operation appears immediately. +
  • + +
  • "full": +full buffering; output operation is performed only +when the buffer is full or when +you explicitly flush the file (see io.flush). +
  • + +
  • "line": +line buffering; output is buffered until a newline is output +or there is any input from some special files +(such as a terminal device). +
  • + +

+For the last two cases, size +specifies the size of the buffer, in bytes. +The default is an appropriate size. + + + + +

+


file:write (···)

+ + +

+Writes the value of each of its arguments to file. +The arguments must be strings or numbers. + + +

+In case of success, this function returns file. +Otherwise it returns nil plus a string describing the error. + + + + + + + +

6.9 – Operating System Facilities

+ +

+This library is implemented through table os. + + +

+


os.clock ()

+ + +

+Returns an approximation of the amount in seconds of CPU time +used by the program. + + + + +

+


os.date ([format [, time]])

+ + +

+Returns a string or a table containing date and time, +formatted according to the given string format. + + +

+If the time argument is present, +this is the time to be formatted +(see the os.time function for a description of this value). +Otherwise, date formats the current time. + + +

+If format starts with '!', +then the date is formatted in Coordinated Universal Time. +After this optional character, +if format is the string "*t", +then date returns a table with the following fields: +year (four digits), month (1–12), day (1–31), +hour (0–23), min (0–59), sec (0–61), +wday (weekday, Sunday is 1), +yday (day of the year), +and isdst (daylight saving flag, a boolean). +This last field may be absent +if the information is not available. + + +

+If format is not "*t", +then date returns the date as a string, +formatted according to the same rules as the ANSI C function strftime. + + +

+When called without arguments, +date returns a reasonable date and time representation that depends on +the host system and on the current locale +(that is, os.date() is equivalent to os.date("%c")). + + +

+On non-Posix systems, +this function may be not thread safe +because of its reliance on C function gmtime and C function localtime. + + + + +

+


os.difftime (t2, t1)

+ + +

+Returns the number of seconds from time t1 to time t2. +In POSIX, Windows, and some other systems, +this value is exactly t2-t1. + + + + +

+


os.execute ([command])

+ + +

+This function is equivalent to the ANSI C function system. +It passes command to be executed by an operating system shell. +Its first result is true +if the command terminated successfully, +or nil otherwise. +After this first result +the function returns a string and a number, +as follows: + +

    + +
  • "exit": +the command terminated normally; +the following number is the exit status of the command. +
  • + +
  • "signal": +the command was terminated by a signal; +the following number is the signal that terminated the command. +
  • + +
+ +

+When called without a command, +os.execute returns a boolean that is true if a shell is available. + + + + +

+


os.exit ([code [, close])

+ + +

+Calls the ANSI C function exit to terminate the host program. +If code is true, +the returned status is EXIT_SUCCESS; +if code is false, +the returned status is EXIT_FAILURE; +if code is a number, +the returned status is this number. +The default value for code is true. + + +

+If the optional second argument close is true, +closes the Lua state before exiting. + + + + +

+


os.getenv (varname)

+ + +

+Returns the value of the process environment variable varname, +or nil if the variable is not defined. + + + + +

+


os.remove (filename)

+ + +

+Deletes the file (or empty directory, on POSIX systems) +with the given name. +If this function fails, it returns nil, +plus a string describing the error and the error code. + + + + +

+


os.rename (oldname, newname)

+ + +

+Renames file or directory named oldname to newname. +If this function fails, it returns nil, +plus a string describing the error and the error code. + + + + +

+


os.setlocale (locale [, category])

+ + +

+Sets the current locale of the program. +locale is a system-dependent string specifying a locale; +category is an optional string describing which category to change: +"all", "collate", "ctype", +"monetary", "numeric", or "time"; +the default category is "all". +The function returns the name of the new locale, +or nil if the request cannot be honored. + + +

+If locale is the empty string, +the current locale is set to an implementation-defined native locale. +If locale is the string "C", +the current locale is set to the standard C locale. + + +

+When called with nil as the first argument, +this function only returns the name of the current locale +for the given category. + + +

+This function may be not thread safe +because of its reliance on C function setlocale. + + + + +

+


os.time ([table])

+ + +

+Returns the current time when called without arguments, +or a time representing the date and time specified by the given table. +This table must have fields year, month, and day, +and may have fields +hour (default is 12), +min (default is 0), +sec (default is 0), +and isdst (default is nil). +For a description of these fields, see the os.date function. + + +

+The returned value is a number, whose meaning depends on your system. +In POSIX, Windows, and some other systems, +this number counts the number +of seconds since some given start time (the "epoch"). +In other systems, the meaning is not specified, +and the number returned by time can be used only as an argument to +os.date and os.difftime. + + + + +

+


os.tmpname ()

+ + +

+Returns a string with a file name that can +be used for a temporary file. +The file must be explicitly opened before its use +and explicitly removed when no longer needed. + + +

+On POSIX systems, +this function also creates a file with that name, +to avoid security risks. +(Someone else might create the file with wrong permissions +in the time between getting the name and creating the file.) +You still have to open the file to use it +and to remove it (even if you do not use it). + + +

+When possible, +you may prefer to use io.tmpfile, +which automatically removes the file when the program ends. + + + + + + + +

6.10 – The Debug Library

+ +

+This library provides +the functionality of the debug interface (§4.9) to Lua programs. +You should exert care when using this library. +Several of its functions +violate basic assumptions about Lua code +(e.g., that variables local to a function +cannot be accessed from outside; +that userdata metatables cannot be changed by Lua code; +that Lua programs do not crash) +and therefore can compromise otherwise secure code. +Moreover, some functions in this library may be slow. + + +

+All functions in this library are provided +inside the debug table. +All functions that operate over a thread +have an optional first argument which is the +thread to operate over. +The default is always the current thread. + + +

+


debug.debug ()

+ + +

+Enters an interactive mode with the user, +running each string that the user enters. +Using simple commands and other debug facilities, +the user can inspect global and local variables, +change their values, evaluate expressions, and so on. +A line containing only the word cont finishes this function, +so that the caller continues its execution. + + +

+Note that commands for debug.debug are not lexically nested +within any function and so have no direct access to local variables. + + + + +

+


debug.gethook ([thread])

+ + +

+Returns the current hook settings of the thread, as three values: +the current hook function, the current hook mask, +and the current hook count +(as set by the debug.sethook function). + + + + +

+


debug.getinfo ([thread,] f [, what])

+ + +

+Returns a table with information about a function. +You can give the function directly +or you can give a number as the value of f, +which means the function running at level f of the call stack +of the given thread: +level 0 is the current function (getinfo itself); +level 1 is the function that called getinfo +(except for tail calls, which do not count on the stack); +and so on. +If f is a number larger than the number of active functions, +then getinfo returns nil. + + +

+The returned table can contain all the fields returned by lua_getinfo, +with the string what describing which fields to fill in. +The default for what is to get all information available, +except the table of valid lines. +If present, +the option 'f' +adds a field named func with the function itself. +If present, +the option 'L' +adds a field named activelines with the table of +valid lines. + + +

+For instance, the expression debug.getinfo(1,"n").name returns +a table with a name for the current function, +if a reasonable name can be found, +and the expression debug.getinfo(print) +returns a table with all available information +about the print function. + + + + +

+


debug.getlocal ([thread,] f, local)

+ + +

+This function returns the name and the value of the local variable +with index local of the function at level f of the stack. +This function accesses not only explicit local variables, +but also parameters, temporaries, etc. + + +

+The first parameter or local variable has index 1, and so on, +until the last active variable. +Negative indices refer to vararg parameters; +-1 is the first vararg parameter. +The function returns nil if there is no variable with the given index, +and raises an error when called with a level out of range. +(You can call debug.getinfo to check whether the level is valid.) + + +

+Variable names starting with '(' (open parenthesis) +represent internal variables +(loop control variables, temporaries, varargs, and C function locals). + + +

+The parameter f may also be a function. +In that case, getlocal returns only the name of function parameters. + + + + +

+


debug.getmetatable (value)

+ + +

+Returns the metatable of the given value +or nil if it does not have a metatable. + + + + +

+


debug.getregistry ()

+ + +

+Returns the registry table (see §4.5). + + + + +

+


debug.getupvalue (f, up)

+ + +

+This function returns the name and the value of the upvalue +with index up of the function f. +The function returns nil if there is no upvalue with the given index. + + + + +

+


debug.getuservalue (u)

+ + +

+Returns the Lua value associated to u. +If u is not a userdata, +returns nil. + + + + +

+


debug.sethook ([thread,] hook, mask [, count])

+ + +

+Sets the given function as a hook. +The string mask and the number count describe +when the hook will be called. +The string mask may have the following characters, +with the given meaning: + +

    +
  • 'c': the hook is called every time Lua calls a function;
  • +
  • 'r': the hook is called every time Lua returns from a function;
  • +
  • 'l': the hook is called every time Lua enters a new line of code.
  • +

+With a count different from zero, +the hook is called after every count instructions. + + +

+When called without arguments, +debug.sethook turns off the hook. + + +

+When the hook is called, its first parameter is a string +describing the event that has triggered its call: +"call" (or "tail call"), +"return", +"line", and "count". +For line events, +the hook also gets the new line number as its second parameter. +Inside a hook, +you can call getinfo with level 2 to get more information about +the running function +(level 0 is the getinfo function, +and level 1 is the hook function). + + + + +

+


debug.setlocal ([thread,] level, local, value)

+ + +

+This function assigns the value value to the local variable +with index local of the function at level level of the stack. +The function returns nil if there is no local +variable with the given index, +and raises an error when called with a level out of range. +(You can call getinfo to check whether the level is valid.) +Otherwise, it returns the name of the local variable. + + +

+See debug.getlocal for more information about +variable indices and names. + + + + +

+


debug.setmetatable (value, table)

+ + +

+Sets the metatable for the given value to the given table +(which can be nil). +Returns value. + + + + +

+


debug.setupvalue (f, up, value)

+ + +

+This function assigns the value value to the upvalue +with index up of the function f. +The function returns nil if there is no upvalue +with the given index. +Otherwise, it returns the name of the upvalue. + + + + +

+


debug.setuservalue (udata, value)

+ + +

+Sets the given value as +the Lua value associated to the given udata. +value must be a table or nil; +udata must be a full userdata. + + +

+Returns udata. + + + + +

+


debug.traceback ([thread,] [message [, level]])

+ + +

+If message is present but is neither a string nor nil, +this function returns message without further processing. +Otherwise, +it returns a string with a traceback of the call stack. +An optional message string is appended +at the beginning of the traceback. +An optional level number tells at which level +to start the traceback +(default is 1, the function calling traceback). + + + + +

+


debug.upvalueid (f, n)

+ + +

+Returns an unique identifier (as a light userdata) +for the upvalue numbered n +from the given function. + + +

+These unique identifiers allow a program to check whether different +closures share upvalues. +Lua closures that share an upvalue +(that is, that access a same external local variable) +will return identical ids for those upvalue indices. + + + + +

+


debug.upvaluejoin (f1, n1, f2, n2)

+ + +

+Make the n1-th upvalue of the Lua closure f1 +refer to the n2-th upvalue of the Lua closure f2. + + + + + + + +

7 – Lua Standalone

+ +

+Although Lua has been designed as an extension language, +to be embedded in a host C program, +it is also frequently used as a standalone language. +An interpreter for Lua as a standalone language, +called simply lua, +is provided with the standard distribution. +The standalone interpreter includes +all standard libraries, including the debug library. +Its usage is: + +

+     lua [options] [script [args]]
+

+The options are: + +

    +
  • -e stat: executes string stat;
  • +
  • -l mod: "requires" mod;
  • +
  • -i: enters interactive mode after running script;
  • +
  • -v: prints version information;
  • +
  • -E: ignores environment variables;
  • +
  • --: stops handling options;
  • +
  • -: executes stdin as a file and stops handling options.
  • +

+After handling its options, lua runs the given script, +passing to it the given args as string arguments. +When called without arguments, +lua behaves as lua -v -i +when the standard input (stdin) is a terminal, +and as lua - otherwise. + + +

+When called without option -E, +the interpreter checks for an environment variable LUA_INIT_5_2 +(or LUA_INIT if it is not defined) +before running any argument. +If the variable content has the format @filename, +then lua executes the file. +Otherwise, lua executes the string itself. + + +

+When called with option -E, +besides ignoring LUA_INIT, +Lua also ignores +the values of LUA_PATH and LUA_CPATH, +setting the values of +package.path and package.cpath +with the default paths defined in luaconf.h. + + +

+All options are handled in order, except -i and -E. +For instance, an invocation like + +

+     $ lua -e'a=1' -e 'print(a)' script.lua
+

+will first set a to 1, then print the value of a, +and finally run the file script.lua with no arguments. +(Here $ is the shell prompt. Your prompt may be different.) + + +

+Before starting to run the script, +lua collects all arguments in the command line +in a global table called arg. +The script name is stored at index 0, +the first argument after the script name goes to index 1, +and so on. +Any arguments before the script name +(that is, the interpreter name plus the options) +go to negative indices. +For instance, in the call + +

+     $ lua -la b.lua t1 t2
+

+the interpreter first runs the file a.lua, +then creates a table + +

+     arg = { [-2] = "lua", [-1] = "-la",
+             [0] = "b.lua",
+             [1] = "t1", [2] = "t2" }
+

+and finally runs the file b.lua. +The script is called with arg[1], arg[2], ... +as arguments; +it can also access these arguments with the vararg expression '...'. + + +

+In interactive mode, +if you write an incomplete statement, +the interpreter waits for its completion +by issuing a different prompt. + + +

+In case of unprotected errors in the script, +the interpreter reports the error to the standard error stream. +If the error object is a string, +the interpreter adds a stack traceback to it. +Otherwise, if the error object has a metamethod __tostring, +the interpreter calls this metamethod to produce the final message. +Finally, if the error object is nil, +the interpreter does not report the error. + + +

+When finishing normally, +the interpreter closes its main Lua state +(see lua_close). +The script can avoid this step by +calling os.exit to terminate. + + +

+To allow the use of Lua as a +script interpreter in Unix systems, +the standalone interpreter skips +the first line of a chunk if it starts with #. +Therefore, Lua scripts can be made into executable programs +by using chmod +x and the #! form, +as in + +

+     #!/usr/local/bin/lua
+

+(Of course, +the location of the Lua interpreter may be different in your machine. +If lua is in your PATH, +then + +

+     #!/usr/bin/env lua
+

+is a more portable solution.) + + + +

8 – Incompatibilities with the Previous Version

+ +

+Here we list the incompatibilities that you may find when moving a program +from Lua 5.1 to Lua 5.2. +You can avoid some incompatibilities by compiling Lua with +appropriate options (see file luaconf.h). +However, +all these compatibility options will be removed in the next version of Lua. +Similarly, +all features marked as deprecated in Lua 5.1 +have been removed in Lua 5.2. + + + +

8.1 – Changes in the Language

+
    + +
  • +The concept of environment changed. +Only Lua functions have environments. +To set the environment of a Lua function, +use the variable _ENV or the function load. + + +

    +C functions no longer have environments. +Use an upvalue with a shared table if you need to keep +shared state among several C functions. +(You may use luaL_setfuncs to open a C library +with all functions sharing a common upvalue.) + + +

    +To manipulate the "environment" of a userdata +(which is now called user value), +use the new functions +lua_getuservalue and lua_setuservalue. +

  • + +
  • +Lua identifiers cannot use locale-dependent letters. +
  • + +
  • +Doing a step or a full collection in the garbage collector +does not restart the collector if it has been stopped. +
  • + +
  • +Weak tables with weak keys now perform like ephemeron tables. +
  • + +
  • +The event tail return in debug hooks was removed. +Instead, tail calls generate a special new event, +tail call, so that the debugger can know that +there will not be a corresponding return event. +
  • + +
  • +Equality between function values has changed. +Now, a function definition may not create a new value; +it may reuse some previous value if there is no +observable difference to the new function. +
  • + +
+ + + + +

8.2 – Changes in the Libraries

+
    + +
  • +Function module is deprecated. +It is easy to set up a module with regular Lua code. +Modules are not expected to set global variables. +
  • + +
  • +Functions setfenv and getfenv were removed, +because of the changes in environments. +
  • + +
  • +Function math.log10 is deprecated. +Use math.log with 10 as its second argument, instead. +
  • + +
  • +Function loadstring is deprecated. +Use load instead; it now accepts string arguments +and are exactly equivalent to loadstring. +
  • + +
  • +Function table.maxn is deprecated. +Write it in Lua if you really need it. +
  • + +
  • +Function os.execute now returns true when command +terminates successfully and nil plus error information +otherwise. +
  • + +
  • +Function unpack was moved into the table library +and therefore must be called as table.unpack. +
  • + +
  • +Character class %z in patterns is deprecated, +as now patterns may contain '\0' as a regular character. +
  • + +
  • +The table package.loaders was renamed package.searchers. +
  • + +
  • +Lua does not have bytecode verification anymore. +So, all functions that load code +(load and loadfile) +are potentially insecure when loading untrusted binary data. +(Actually, those functions were already insecure because +of flaws in the verification algorithm.) +When in doubt, +use the mode argument of those functions +to restrict them to loading textual chunks. +
  • + +
  • +The standard paths in the official distribution may +change between versions. +
  • + +
+ + + + +

8.3 – Changes in the API

+
    + +
  • +Pseudoindex LUA_GLOBALSINDEX was removed. +You must get the global environment from the registry +(see §4.5). +
  • + +
  • +Pseudoindex LUA_ENVIRONINDEX +and functions lua_getfenv/lua_setfenv +were removed, +as C functions no longer have environments. +
  • + +
  • +Function luaL_register is deprecated. +Use luaL_setfuncs so that your module does not create globals. +(Modules are not expected to set global variables anymore.) +
  • + +
  • +The osize argument to the allocation function +may not be zero when creating a new block, +that is, when ptr is NULL +(see lua_Alloc). +Use only the test ptr == NULL to check whether +the block is new. +
  • + +
  • +Finalizers (__gc metamethods) for userdata are called in the +reverse order that they were marked for finalization, +not that they were created (see §2.5.1). +(Most userdata are marked immediately after they are created.) +Moreover, +if the metatable does not have a __gc field when set, +the finalizer will not be called, +even if it is set later. +
  • + +
  • +luaL_typerror was removed. +Write your own version if you need it. +
  • + +
  • +Function lua_cpcall is deprecated. +You can simply push the function with lua_pushcfunction +and call it with lua_pcall. +
  • + +
  • +Functions lua_equal and lua_lessthan are deprecated. +Use the new lua_compare with appropriate options instead. +
  • + +
  • +Function lua_objlen was renamed lua_rawlen. +
  • + +
  • +Function lua_load has an extra parameter, mode. +Pass NULL to simulate the old behavior. +
  • + +
  • +Function lua_resume has an extra parameter, from. +Pass NULL or the thread doing the call. +
  • + +
+ + + + +

9 – The Complete Syntax of Lua

+ +

+Here is the complete syntax of Lua in extended BNF. +(It does not describe operator precedences.) + + + + +

+
+	chunk ::= block
+
+	block ::= {stat} [retstat]
+
+	stat ::=  ‘;’ | 
+		 varlist ‘=’ explist | 
+		 functioncall | 
+		 label | 
+		 break | 
+		 goto Name | 
+		 do block end | 
+		 while exp do block end | 
+		 repeat block until exp | 
+		 if exp then block {elseif exp then block} [else block] end | 
+		 for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
+		 for namelist in explist do block end | 
+		 function funcname funcbody | 
+		 local function Name funcbody | 
+		 local namelist [‘=’ explist] 
+
+	retstat ::= return [explist] [‘;’]
+
+	label ::= ‘::’ Name ‘::’
+
+	funcname ::= Name {‘.’ Name} [‘:’ Name]
+
+	varlist ::= var {‘,’ var}
+
+	var ::=  Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name 
+
+	namelist ::= Name {‘,’ Name}
+
+	explist ::= exp {‘,’ exp}
+
+	exp ::=  nil | false | true | Number | String | ‘...’ | functiondef | 
+		 prefixexp | tableconstructor | exp binop exp | unop exp 
+
+	prefixexp ::= var | functioncall | ‘(’ exp ‘)’
+
+	functioncall ::=  prefixexp args | prefixexp ‘:’ Name args 
+
+	args ::=  ‘(’ [explist] ‘)’ | tableconstructor | String 
+
+	functiondef ::= function funcbody
+
+	funcbody ::= ‘(’ [parlist] ‘)’ block end
+
+	parlist ::= namelist [‘,’ ‘...’] | ‘...’
+
+	tableconstructor ::= ‘{’ [fieldlist] ‘}’
+
+	fieldlist ::= field {fieldsep field} [fieldsep]
+
+	field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
+
+	fieldsep ::= ‘,’ | ‘;’
+
+	binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ | 
+		 ‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ | 
+		 and | or
+
+	unop ::= ‘-’ | not | ‘#’
+
+
+ +

+ + + + + + + +


+ +Last update: +Thu Mar 21 12:58:59 BRT 2013 + + + + + diff --git a/src/external/lua-5.2.3/doc/osi-certified-72x60.png b/src/external/lua-5.2.3/doc/osi-certified-72x60.png new file mode 100644 index 000000000..07df5f6ee Binary files /dev/null and b/src/external/lua-5.2.3/doc/osi-certified-72x60.png differ diff --git a/src/external/lua-5.2.3/doc/readme.html b/src/external/lua-5.2.3/doc/readme.html new file mode 100644 index 000000000..8acec874c --- /dev/null +++ b/src/external/lua-5.2.3/doc/readme.html @@ -0,0 +1,413 @@ + + + +Lua 5.2 readme + + + + + + + +
+

+Lua +Welcome to Lua 5.2 +

+ +

+about +· +installation +· +changes +· +license +· +reference manual + +

About Lua

+ +

+Lua is a powerful, fast, lightweight, embeddable scripting language +developed by a +team +at +PUC-Rio, +the Pontifical Catholic University of Rio de Janeiro in Brazil. +Lua is +free software +used in many products and projects around the world. + +

+Lua's +official web site +provides complete information +about Lua, +including +an +executive summary +and +updated +documentation, +especially the +reference manual, +which may differ slightly from the +local copy +distributed in this package. + +

Installing Lua

+ +

+Lua is distributed in +source +form. +You need to build it before using it. +Building Lua should be straightforward +because +Lua is implemented in pure ANSI C and compiles unmodified in all known +platforms that have an ANSI C compiler. +Lua also compiles unmodified as C++. +The instructions given below for building Lua are for Unix-like platforms. +See also +instructions for other systems +and +customization options. + +

+If you don't have the time or the inclination to compile Lua yourself, +get a binary from +LuaBinaries. +Try also +Lua for Windows, +an easy-to-use distribution of Lua that includes many useful libraries. + +

Building Lua

+ +

+In most Unix-like platforms, simply do "make" with a suitable target. +Here are the details. + +

    +
  1. +Open a terminal window and move to +the top-level directory, which is named lua-5.2.3. +The Makefile there controls both the build process and the installation process. +

    +

  2. + Do "make" and see if your platform is listed. + The platforms currently supported are: +

    +

    + aix ansi bsd freebsd generic linux macosx mingw posix solaris +

    +

    + If your platform is listed, just do "make xxx", where xxx + is your platform name. +

    + If your platform is not listed, try the closest one or posix, generic, + ansi, in this order. +

    +

  3. +The compilation takes only a few moments +and produces three files in the src directory: +lua (the interpreter), +luac (the compiler), +and liblua.a (the library). +

    +

  4. + To check that Lua has been built correctly, do "make test" + after building Lua. This will run the interpreter and print its version string. +
+

+If you're running Linux and get compilation errors, +make sure you have installed the readline development package. +If you get link errors after that, +then try "make linux MYLIBS=-ltermcap". + +

Installing Lua

+

+ Once you have built Lua, you may want to install it in an official + place in your system. In this case, do "make install". The official + place and the way to install files are defined in the Makefile. You'll + probably need the right permissions to install files. + +

+ To build and install Lua in one step, do "make xxx install", + where xxx is your platform name. + +

+ To install Lua locally, do "make local". + This will create a directory install with subdirectories + bin, include, lib, man, + and install Lua as listed below. + + To install Lua locally, but in some other directory, do + "make install INSTALL_TOP=xxx", where xxx is your chosen directory. + +

+
+ bin: +
+ lua luac +
+ include: +
+ lua.h luaconf.h lualib.h lauxlib.h lua.hpp +
+ lib: +
+ liblua.a +
+ man/man1: +
+ lua.1 luac.1 +
+ +

+ These are the only directories you need for development. + If you only want to run Lua programs, + you only need the files in bin and man. + The files in include and lib are needed for + embedding Lua in C or C++ programs. + +

Customization

+

+ Three kinds of things can be customized by editing a file: +

    +
  • Where and how to install Lua — edit Makefile. +
  • How to build Lua — edit src/Makefile. +
  • Lua features — edit src/luaconf.h. +
+ +

+ You don't actually need to edit the Makefiles because you may set the + relevant variables in the command line when invoking make. + Nevertheless, it's probably best to edit and save the Makefiles to + record the changes you need. + +

+ On the other hand, if you need to customize some Lua features, you'll need + to edit src/luaconf.h before building and installing Lua. + The edited file will be the one installed, and + it will be used by any Lua clients that you build, to ensure consistency. + Further customization is available to experts by editing the Lua sources. + +

+ We strongly recommend that you enable dynamic loading in src/luaconf.h. + This is done automatically for all platforms listed above that have + this feature and also for Windows. + +

Building Lua on other systems

+ +

+ If you're not using the usual Unix tools, then the instructions for + building Lua depend on the compiler you use. You'll need to create + projects (or whatever your compiler uses) for building the library, + the interpreter, and the compiler, as follows: + +

+
+library: +
+lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c +lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c +ltm.c lundump.c lvm.c lzio.c +lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c +lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c +
+interpreter: +
+ library, lua.c +
+compiler: +
+ library, luac.c +
+ +

+ To use Lua as a library in your own programs you'll need to know how to + create and use libraries with your compiler. Moreover, to dynamically load + C libraries for Lua you'll need to know how to create dynamic libraries + and you'll need to make sure that the Lua API functions are accessible to + those dynamic libraries — but don't link the Lua library + into each dynamic library. For Unix, we recommend that the Lua library + be linked statically into the host program and its symbols exported for + dynamic linking; src/Makefile does this for the Lua interpreter. + For Windows, we recommend that the Lua library be a DLL. + +

+ As mentioned above, you may edit src/luaconf.h to customize + some features before building Lua. + +

Changes since Lua 5.1

+ +

+Here are the main changes introduced in Lua 5.2. +The +reference manual +lists the +incompatibilities that had to be introduced. + +

Main changes

+
    +
  • yieldable pcall and metamethods +
  • new lexical scheme for globals +
  • ephemeron tables +
  • new library for bitwise operations +
  • light C functions +
  • emergency garbage collector +
  • goto statement +
  • finalizers for tables +
+ +Here are the other changes introduced in Lua 5.2: +

Language

+
    +
  • no more fenv for threads or functions +
  • tables honor the __len metamethod +
  • hex and \z escapes in strings +
  • support for hexadecimal floats +
  • order metamethods work for different types +
  • no more verification of opcode consistency +
  • hook event "tail return" replaced by "tail call" +
  • empty statement +
  • break statement may appear in the middle of a block +
+ +

Libraries

+
    +
  • arguments for function called through xpcall +
  • optional 'mode' argument to load and loadfile (to control binary x text) +
  • optional 'env' argument to load and loadfile (environment for loaded chunk) +
  • loadlib may load libraries with global names (RTLD_GLOBAL) +
  • new function package.searchpath +
  • modules receive their paths when loaded +
  • optional base in math.log +
  • optional separator in string.rep +
  • file:write returns file +
  • closing a pipe returns exit status +
  • os.exit may close state +
  • new metamethods __pairs and __ipairs +
  • new option 'isrunning' for collectgarbage and lua_gc +
  • frontier patterns +
  • \0 in patterns +
  • new option *L for io.read +
  • options for io.lines +
  • debug.getlocal can access function varargs +
+ +

C API

+
    +
  • main thread predefined in the registry +
  • new functions +lua_absindex, +lua_arith, +lua_compare, +lua_copy, +lua_len, +lua_rawgetp, +lua_rawsetp, +lua_upvalueid, +lua_upvaluejoin, +lua_version. +
  • new functions +luaL_checkversion, +luaL_setmetatable, +luaL_testudata, +luaL_tolstring. +
  • lua_pushstring and pushlstring return string +
  • nparams and isvararg available in debug API +
  • new lua_Unsigned +
+ +

Implementation

+
    +
  • max constants per function raised to 226 +
  • generational mode for garbage collection (experimental) +
  • NaN trick (experimental) +
  • internal (immutable) version of ctypes +
  • simpler implementation for string buffers +
  • parser uses much less C-stack space (no more auto arrays) +
+ +

Lua standalone interpreter

+
    +
  • new -E option to avoid environment variables +
  • handling of non-string error messages +
+ +

License

+ +[osi certified] + + +

+Lua is free software distributed under the terms of the +MIT license +reproduced below; +it may be used for any purpose, including commercial purposes, +at absolutely no cost without having to ask us. + +The only requirement is that if you do use Lua, +then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation. + +For details, see +this. + +

+Copyright © 1994–2013 Lua.org, PUC-Rio. + +

+Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +

+The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +

+

+ +


+ +Last update: +Sat Nov 9 22:39:16 BRST 2013 + + + + + diff --git a/src/external/lua-5.2.3/src/Makefile b/src/external/lua-5.2.3/src/Makefile new file mode 100644 index 000000000..54b03875d --- /dev/null +++ b/src/external/lua-5.2.3/src/Makefile @@ -0,0 +1,189 @@ +# Makefile for building Lua +# See ../doc/readme.html for installation and customization instructions. + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +PREFIX?=/var/openarmor + +#CC= gcc +CFLAGS= -Wall -DLUA_COMPAT_ALL -DPREFIX=\"$(PREFIX)\" $(SYSCFLAGS) $(MYCFLAGS) +LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) +LIBS= -lm $(SYSLIBS) $(MYLIBS) + +AR= ar rcu +RANLIB= ranlib +RM= rm -f + +SYSCFLAGS= +SYSLDFLAGS= +SYSLIBS= + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= +MYOBJS= + +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= + +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ + lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ + ltm.o lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ + lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o +BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) + +LUA_T= openarmor-lua +LUA_O= lua.o + +LUAC_T= openarmor-luac +LUAC_O= luac.o + +ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +# Targets start here. +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(BASE_O) + $(AR) $@ $(BASE_O) + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c + +echo: + @echo "PLAT= $(PLAT)" + @echo "CC= $(CC)" + @echo "CFLAGS= $(CFLAGS)" + @echo "LDFLAGS= $(SYSLDFLAGS)" + @echo "LIBS= $(LIBS)" + @echo "AR= $(AR)" + @echo "RANLIB= $(RANLIB)" + @echo "RM= $(RM)" + +# Convenience targets for popular platforms +ALL= all + +none: + @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" + @echo " $(PLATS)" + +aix: + $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" + +ansi: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" + +bsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -I/usr/local/include" SYSLIBS="-Wl,-E -lreadline -L/usr/local/lib" + +freebsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -I/usr/local/include" SYSLIBS="-Wl,-E -lreadline -L/usr/local/lib" + +generic: $(ALL) + +linux: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" + +macosx: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc + +mingw: + $(MAKE) "LUA_A=lua52.dll" "LUA_T=openarmor-lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" openarmor-lua.exe + $(MAKE) "LUAC_T=luac.exe" openarmor-luac.exe + +posix: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" + +solaris: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ + lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ + lvm.h +lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + lstring.h ltable.h lvm.h +lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h +lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h +ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ + ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ + lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ + lstring.h ltable.h lundump.h lvm.h +ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ + lstate.h ltm.h lzio.h lmem.h +lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ + lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h +lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ + lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ + ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ + ltable.h +lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ + ltm.h lzio.h lstring.h lgc.h +lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h +ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ + lmem.h lstring.h lgc.h ltable.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h +lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ + lzio.h + diff --git a/src/external/lua-5.2.3/src/Makefile.mingw b/src/external/lua-5.2.3/src/Makefile.mingw new file mode 100644 index 000000000..38176cb2b --- /dev/null +++ b/src/external/lua-5.2.3/src/Makefile.mingw @@ -0,0 +1,187 @@ +# Makefile for building Lua +# See ../doc/readme.html for installation and customization instructions. + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +CC= i686-w64-mingw32-gcc +CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) +LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) +LIBS= -lm $(SYSLIBS) $(MYLIBS) + +AR= i686-w64-mingw32-ar rcu +RANLIB= i686-w64-mingw32-ranlib +RM= rm -f + +SYSCFLAGS= +SYSLDFLAGS= +SYSLIBS= + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= +MYOBJS= + +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= + +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ + lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ + ltm.o lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ + lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o +BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) + +LUA_T= openarmor-lua +LUA_O= lua.o + +LUAC_T= openarmor-luac +LUAC_O= luac.o + +ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +# Targets start here. +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(BASE_O) + $(AR) $@ $(BASE_O) + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c + +echo: + @echo "PLAT= $(PLAT)" + @echo "CC= $(CC)" + @echo "CFLAGS= $(CFLAGS)" + @echo "LDFLAGS= $(SYSLDFLAGS)" + @echo "LIBS= $(LIBS)" + @echo "AR= $(AR)" + @echo "RANLIB= $(RANLIB)" + @echo "RM= $(RM)" + +# Convenience targets for popular platforms +ALL= all + +none: + @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" + @echo " $(PLATS)" + +aix: + $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" + +ansi: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" + +bsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" + +freebsd: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" + +generic: $(ALL) + +linux: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" + +macosx: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc + +mingw: + $(MAKE) -f Makefile.mingw "LUA_A=lua52.dll" "LUA_T=openarmor-lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" openarmor-lua.exe + $(MAKE) -f Makefile.mingw "LUAC_T=openarmor-luac.exe" openarmor-luac.exe + +posix: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" + +solaris: + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ + lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ + lvm.h +lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + lstring.h ltable.h lvm.h +lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h +lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h +ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ + ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ + lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ + lstring.h ltable.h lundump.h lvm.h +ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ + lstate.h ltm.h lzio.h lmem.h +lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ + lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h +lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ + lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ + ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ + ltable.h +lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ + ltm.h lzio.h lstring.h lgc.h +lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h +ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ + lmem.h lstring.h lgc.h ltable.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h +lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ + lzio.h + diff --git a/src/external/lua-5.2.3/src/lapi.c b/src/external/lua-5.2.3/src/lapi.c new file mode 100644 index 000000000..d011431ea --- /dev/null +++ b/src/external/lua-5.2.3/src/lapi.c @@ -0,0 +1,1284 @@ +/* +** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$LuaVersion: " LUA_COPYRIGHT " $" + "$LuaAuthors: " LUA_AUTHORS " $"; + + +/* value at a non-valid index */ +#define NONVALIDVALUE cast(TValue *, luaO_nilobject) + +/* corresponding test */ +#define isvalid(o) ((o) != luaO_nilobject) + +/* test for pseudo index */ +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) + +/* test for valid but not pseudo index */ +#define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) + +#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") + +#define api_checkstackindex(L, i, o) \ + api_check(L, isstackindex(i, o), "index not in the stack") + + +static TValue *index2addr (lua_State *L, int idx) { + CallInfo *ci = L->ci; + if (idx > 0) { + TValue *o = ci->func + idx; + api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); + if (o >= L->top) return NONVALIDVALUE; + else return o; + } + else if (!ispseudo(idx)) { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); + return L->top + idx; + } + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttislcf(ci->func)) /* light C function? */ + return NONVALIDVALUE; /* it has no upvalues */ + else { + CClosure *func = clCvalue(ci->func); + return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; + } + } +} + + +/* +** to be called by 'lua_checkstack' in protected mode, to grow stack +** capturing memory errors +*/ +static void growstack (lua_State *L, void *ud) { + int size = *(int *)ud; + luaD_growstack(L, size); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res; + CallInfo *ci = L->ci; + lua_lock(L); + if (L->stack_last - L->top > size) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else { /* no; need to grow stack */ + int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; + if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ + res = 0; /* no */ + else /* try to grow stack */ + res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK); + } + if (res && ci->top < L->top + size) + ci->top = L->top + size; /* adjust frame top */ + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API const lua_Number *lua_version (lua_State *L) { + static const lua_Number version = LUA_VERSION_NUM; + if (L == NULL) return &version; + else return G(L)->version; +} + + + +/* +** basic stack manipulation +*/ + + +/* +** convert an acceptable stack index into an absolute index +*/ +LUA_API int lua_absindex (lua_State *L, int idx) { + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top - L->ci->func + idx); +} + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - (L->ci->func + 1)); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + StkId func = L->ci->func; + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); + while (L->top < (func + 1) + idx) + setnilvalue(L->top++); + L->top = (func + 1) + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + for (q = L->top; q > p; q--) /* use L->top as a temporary */ + setobjs2s(L, q, q - 1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +static void moveto (lua_State *L, TValue *fr, int idx) { + TValue *to = index2addr(L, idx); + api_checkvalidindex(L, to); + setobj(L, to, fr); + if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ + luaC_barrier(L, clCvalue(L->ci->func), fr); + /* LUA_REGISTRYINDEX does not need gc barrier + (collector revisits it before finishing collection) */ +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + lua_lock(L); + api_checknelems(L, 1); + moveto(L, L->top - 1, idx); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr; + lua_lock(L); + fr = index2addr(L, fromidx); + moveto(L, fr, toidx); + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2addr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (isvalid(o) ? ttypenv(o) : LUA_TNONE); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return ttypename(t); +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2addr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2addr(L, index1); + StkId o2 = index2addr(L, index2); + return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; +} + + +LUA_API void lua_arith (lua_State *L, int op) { + StkId o1; /* 1st operand */ + StkId o2; /* 2nd operand */ + lua_lock(L); + if (op != LUA_OPUNM) /* all other operations expect two operands */ + api_checknelems(L, 2); + else { /* for unary minus, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top, L->top - 1); + L->top++; + } + o1 = L->top - 2; + o2 = L->top - 1; + if (ttisnumber(o1) && ttisnumber(o2)) { + setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); + } + else + luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { + StkId o1, o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + if (isvalid(o1) && isvalid(o2)) { + switch (op) { + case LUA_OPEQ: i = equalobj(L, o1, o2); break; + case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; + default: api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; +} + + +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + if (isnum) *isnum = 1; + return nvalue(o); + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + if (isnum) *isnum = 1; + return res; + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + lua_Unsigned res; + lua_Number num = nvalue(o); + lua_number2unsigned(res, num); + if (isnum) *isnum = 1; + return res; + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2addr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2addr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2addr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_rawlen (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttypenv(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + if (ttislcf(o)) return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else return NULL; /* not a C function */ +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttypenv(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TLCL: return clLvalue(o); + case LUA_TCCL: return clCvalue(o); + case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + luai_checknum(L, L->top, + luaG_runerror(L, "C API - attempt to push a signaling NaN")); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { + lua_Number n; + lua_lock(L); + n = lua_unsigned2number(u); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_newlstr(L, s, len); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); +} + + +LUA_API const char *lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) { + lua_pushnil(L); + return NULL; + } + else { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_new(L, s); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); + } +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + lua_lock(L); + if (n == 0) { + setfvalue(L->top, fn); + } + else { + Closure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + luaC_checkGC(L); + cl = luaF_newCclosure(L, n); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top + n); + setclCvalue(L, L->top, cl); + } + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_getglobal (lua_State *L, const char *var) { + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_gettable(L, gt, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + setsvalue2s(L, L->top, luaS_new(L, k)); + api_incr_top(L); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top, luaH_getint(hvalue(t), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2s(L, L->top, luaH_get(hvalue(t), &k)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + Table *t; + lua_lock(L); + luaC_checkGC(L); + t = luaH_new(L); + sethvalue(L, L->top, t); + api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2addr(L, objindex); + switch (ttypenv(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttypenv(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getuservalue (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (uvalue(o)->env) { + sethvalue(L, L->top, uvalue(o)->env); + } else + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_setglobal (lua_State *L, const char *var) { + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + api_checknelems(L, 1); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_settable(L, gt, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); +} + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + setsvalue2s(L, L->top++, luaS_new(L, k)); + luaV_settable(L, t, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + invalidateTMcache(hvalue(t)); + luaC_barrierback(L, gcvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + luaH_setint(L, hvalue(t), n, L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top - 1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2addr(L, objindex); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1), "table expected"); + mt = hvalue(L->top - 1); + } + switch (ttypenv(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrierback(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) { + luaC_objbarrier(L, rawuvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + default: { + G(L)->mt[ttypenv(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API void lua_setuservalue (lua_State *L, int idx) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (ttisnil(L->top - 1)) + uvalue(o)->env = NULL; + else { + api_check(L, ttistable(L->top - 1), "table expected"); + uvalue(o)->env = hvalue(L->top - 1); + luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + } + L->top--; + lua_unlock(L); +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ + "results from function overflow current stack size") + + +LUA_API int lua_getctx (lua_State *L, int *ctx) { + if (L->ci->callstatus & CIST_YIELDED) { + if (ctx) *ctx = L->ci->u.c.ctx; + return L->ci->u.c.status; + } + else return LUA_OK; +} + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k) { + StkId func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults, 1); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_call(L, func, nresults, 0); /* just do the call */ + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults, 0); +} + + + +LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2addr(L, errfunc); + api_checkstackindex(L, errfunc, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->extra = savestack(L, c.func); + ci->u.c.old_allowhook = L->allowhook; + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + /* mark that function may do error recovery */ + ci->callstatus |= CIST_YPCALL; + luaD_call(L, c.func, nresults, 1); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname, const char *mode) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) { /* no errors? */ + LClosure *f = clLvalue(L->top - 1); /* get newly created function */ + if (f->nupvalues == 1) { /* does it have one upvalue? */ + /* get global table from registry */ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v, gt); + luaC_barrier(L, f->upvals[0], gt); + } + } + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, getproto(o), writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->gcrunning = 0; + break; + } + case LUA_GCRESTART: { + luaE_setdebt(g, 0); + g->gcrunning = 1; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L, 0); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(gettotalbytes(g) >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(gettotalbytes(g) & 0x3ff); + break; + } + case LUA_GCSTEP: { + if (g->gckind == KGC_GEN) { /* generational mode? */ + res = (g->GCestimate == 0); /* true if it will do major collection */ + luaC_forcestep(L); /* do a single step */ + } + else { + lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; + if (g->gcrunning) + debt += g->GCdebt; /* include current debt */ + luaE_setdebt(g, debt); + luaC_forcestep(L); + if (g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + } + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETMAJORINC: { + res = g->gcmajorinc; + g->gcmajorinc = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + case LUA_GCISRUNNING: { + res = g->gcrunning; + break; + } + case LUA_GCGEN: { /* change collector to generational mode */ + luaC_changemode(L, KGC_GEN); + break; + } + case LUA_GCINC: { /* change collector to incremental mode */ + luaC_changemode(L, KGC_NORMAL); + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + /* code unreachable; will unlock when control actually leaves the kernel */ + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API void lua_len (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_objlen(L, L->top, t); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, NULL); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val, + GCObject **owner) { + switch (ttype(fi)) { + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(1 <= n && n <= f->nupvalues)) return NULL; + *val = &f->upvalue[n-1]; + if (owner) *owner = obj2gco(f); + return ""; + } + case LUA_TLCL: { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->upvals[n-1]->v; + if (owner) *owner = obj2gco(f->upvals[n - 1]); + name = p->upvalues[n-1].name; + return (name == NULL) ? "" : getstr(name); + } + default: return NULL; /* not a closure */ + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + lua_lock(L); + name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val = NULL; /* to avoid warnings */ + GCObject *owner = NULL; /* to avoid warnings */ + StkId fi; + lua_lock(L); + fi = index2addr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val, &owner); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, owner, L->top); + } + lua_unlock(L); + return name; +} + + +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { + LClosure *f; + StkId fi = index2addr(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); + if (pf) *pf = f; + return &f->upvals[n - 1]; /* get its upvalue pointer */ +} + + +LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { + StkId fi = index2addr(L, fidx); + switch (ttype(fi)) { + case LUA_TLCL: { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); + return &f->upvalue[n - 1]; + } + default: { + api_check(L, 0, "closure expected"); + return NULL; + } + } +} + + +LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + *up1 = *up2; + luaC_objbarrier(L, f1, *up2); +} + diff --git a/src/external/lua-5.2.3/src/lapi.h b/src/external/lua-5.2.3/src/lapi.h new file mode 100644 index 000000000..c7d34ad84 --- /dev/null +++ b/src/external/lua-5.2.3/src/lapi.h @@ -0,0 +1,24 @@ +/* +** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "llimits.h" +#include "lstate.h" + +#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ + "stack overflow");} + +#define adjustresults(L,nres) \ + { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } + +#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ + "not enough elements in the stack") + + +#endif diff --git a/src/external/lua-5.2.3/src/lauxlib.c b/src/external/lua-5.2.3/src/lauxlib.c new file mode 100644 index 000000000..b00f8c709 --- /dev/null +++ b/src/external/lua-5.2.3/src/lauxlib.c @@ -0,0 +1,959 @@ +/* +** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +/* +** {====================================================== +** Traceback +** ======================================================= +*/ + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + + + +/* +** search for 'objidx' in table at index -1. +** return 1 + string at top if find a good name. +*/ +static int findfield (lua_State *L, int objidx, int level) { + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) { /* try recursively */ + lua_remove(L, -2); /* remove table (but keep name) */ + lua_pushliteral(L, "."); + lua_insert(L, -2); /* place '.' between the two names */ + lua_concat(L, 3); + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ +} + + +static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_pushglobaltable(L); + if (findfield(L, top + 1, 2)) { + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ + return 1; + } + else { + lua_settop(L, top); /* remove function and global table */ + return 0; + } +} + + +static void pushfuncname (lua_State *L, lua_Debug *ar) { + if (*ar->namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, "function " LUA_QS, ar->name); + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what == 'C') { + if (pushglobalfuncname(L, ar)) { + lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else + lua_pushliteral(L, "?"); + } + else + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); +} + + +static int countlevels (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } + /* do a binary search */ + while (li < le) { + int m = (li + le)/2; + if (lua_getstack(L, m, &ar)) li = m + 1; + else le = m; + } + return le - 1; +} + + +LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, + const char *msg, int level) { + lua_Debug ar; + int top = lua_gettop(L); + int numlevels = countlevels(L1); + int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; + if (msg) lua_pushfstring(L, "%s\n", msg); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level == mark) { /* too many levels? */ + lua_pushliteral(L, "\n\t..."); /* add a '...' */ + level = numlevels - LEVELS2; /* and skip to last ones */ + } + else { + lua_getinfo(L1, "Slnt", &ar); + lua_pushfstring(L, "\n\t%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + lua_pushliteral(L, " in "); + pushfuncname(L, &ar); + if (ar.istailcall) + lua_pushliteral(L, "\n\t(...tail calls...)"); + lua_concat(L, lua_gettop(L) - top); + } + } + lua_concat(L, lua_gettop(L) - top); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +static int typeerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + typeerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + + +LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { + int en = errno; /* calls to Lua API may change this value */ + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (fname) + lua_pushfstring(L, "%s: %s", fname, strerror(en)); + else + lua_pushstring(L, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +#if !defined(inspectstat) /* { */ + +#if defined(LUA_USE_POSIX) + +#include + +/* +** use appropriate macros to interpret 'pclose' return status +*/ +#define inspectstat(stat,what) \ + if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ + else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } + +#else + +#define inspectstat(stat,what) /* no op */ + +#endif + +#endif /* } */ + + +LUALIB_API int luaL_execresult (lua_State *L, int stat) { + const char *what = "exit"; /* type of termination */ + if (stat == -1) /* error? */ + return luaL_fileresult(L, 0, NULL); + else { + inspectstat(stat, what); /* interpret result */ + if (*what == 'e' && stat == 0) /* successful termination? */ + lua_pushboolean(L, 1); + else + lua_pushnil(L); + lua_pushstring(L, what); + lua_pushinteger(L, stat); + return 3; /* return true/nil,what,code */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Userdata's metatable manipulation +** ======================================================= +*/ + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); /* try to get metatable */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); +} + + +LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = luaL_testudata(L, ud, tname); + if (p == NULL) typeerror(L, ud, tname); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Argument check functions +** ======================================================= +*/ + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { + /* keep some extra space to run error routines, if needed */ + const int extra = LUA_MINSTACK; + if (!lua_checkstack(L, space + extra)) { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); + } +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + int isnum; + lua_Number d = lua_tonumberx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + int isnum; + lua_Integer d = lua_tointegerx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { + int isnum; + lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, + lua_Unsigned def) { + return luaL_opt(L, luaL_checkunsigned, narg, def); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +/* +** check whether buffer is using a userdata on the stack as a temporary +** buffer +*/ +#define buffonstack(B) ((B)->b != (B)->initb) + + +/* +** returns a pointer to a free area with at least 'sz' bytes +*/ +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { + lua_State *L = B->L; + if (B->size - B->n < sz) { /* not enough space? */ + char *newbuff; + size_t newsize = B->size * 2; /* double buffer size */ + if (newsize - B->n < sz) /* not big enough? */ + newsize = B->n + sz; + if (newsize < B->n || newsize - B->n < sz) + luaL_error(L, "buffer too large"); + /* create larger buffer */ + newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); + /* move content to new buffer */ + memcpy(newbuff, B->b, B->n * sizeof(char)); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ + B->b = newbuff; + B->size = newsize; + } + return &B->b[B->n]; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + char *b = luaL_prepbuffsize(B, l); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + lua_State *L = B->L; + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ +} + + +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { + luaL_addsize(B, sz); + luaL_pushresult(B); +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t l; + const char *s = lua_tolstring(L, -1, &l); + if (buffonstack(B)) + lua_insert(L, -2); /* put value below buffer */ + luaL_addlstring(B, s, l); + lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->b = B->initb; + B->n = 0; + B->size = LUAL_BUFFERSIZE; +} + + +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { + luaL_buffinit(L, B); + return luaL_prepbuffsize(B, sz); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Reference system +** ======================================================= +*/ + +/* index of free-list header */ +#define freelist 0 + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int n; /* number of pre-read characters */ + FILE *f; /* file being read */ + char buff[LUAL_BUFFERSIZE]; /* area for reading file */ +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; /* not used */ + if (lf->n > 0) { /* are there pre-read characters to be read? */ + *size = lf->n; /* return them (chars already in buffer) */ + lf->n = 0; /* no more pre-read characters */ + } + else { /* read a block from file */ + /* 'fread' can return > 0 *and* set the EOF flag. If next call to + 'getF' called 'fread', it might still wait for user input. + The next check avoids this problem. */ + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ + } + return lf->buff; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +static int skipBOM (LoadF *lf) { + const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ + int c; + lf->n = 0; + do { + c = getc(lf->f); + if (c == EOF || c != *(const unsigned char *)p++) return c; + lf->buff[lf->n++] = c; /* to be read by the parser */ + } while (*p != '\0'); + lf->n = 0; /* prefix matched; discard it */ + return getc(lf->f); /* return next character */ +} + + +/* +** reads the first character of file 'f' and skips an optional BOM mark +** in its beginning plus its first line if it starts with '#'. Returns +** true if it skipped the first line. In any case, '*cp' has the +** first "valid" character of the file (after the optional BOM and +** a first-line comment). +*/ +static int skipcomment (LoadF *lf, int *cp) { + int c = *cp = skipBOM(lf); + if (c == '#') { /* first line is a comment (Unix exec. file)? */ + do { /* skip first line */ + c = getc(lf->f); + } while (c != EOF && c != '\n') ; + *cp = getc(lf->f); /* skip end-of-line, if present */ + return 1; /* there was a comment */ + } + else return 0; /* no comment */ +} + + +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, + const char *mode) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + if (skipcomment(&lf, &c)) /* read initial portion */ + lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(&lf, &c); /* re-read initial portion */ + } + if (c != EOF) + lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ + status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); +} + + +LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + +/* }====================================================== */ + + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = lua_absindex(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API int luaL_len (lua_State *L, int idx) { + int l; + int isnum; + lua_len(L, idx); + l = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) + luaL_error(L, "object length is not a number"); + lua_pop(L, 1); /* remove object */ + return l; +} + + +LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ + switch (lua_type(L, idx)) { + case LUA_TNUMBER: + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), + lua_topointer(L, idx)); + break; + } + } + return lua_tolstring(L, -1, len); +} + + +/* +** {====================================================== +** Compatibility with 5.1 module functions +** ======================================================= +*/ +#if defined(LUA_COMPAT_MODULE) + +static const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + if (idx) lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + +/* +** Count number of elements in a luaL_Reg list. +*/ +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l && l->name; l++) size++; + return size; +} + + +/* +** Find or create a module table with a given name. The function +** first looks at the _LOADED table and, if that fails, try a +** global variable with that name. In any case, leaves on the stack +** the module table. +*/ +LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, + int sizehint) { + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ + lua_getfield(L, -1, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + lua_pushglobaltable(L); + if (luaL_findtable(L, 0, modname, sizehint) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ +} + + +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + luaL_checkversion(L); + if (libname) { + luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ + } + if (l) + luaL_setfuncs(L, l, nup); + else + lua_pop(L, nup); /* remove upvalues */ +} + +#endif +/* }====================================================== */ + +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkversion(L); + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ +LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { + lua_getfield(L, idx, fname); + if (lua_istable(L, -1)) return 1; /* table already there */ + else { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } +} + + +/* +** stripped-down 'require'. Calls 'openf' to open a module, +** registers the result in 'package.loaded' table and, if 'glb' +** is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* open module */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); /* make copy of module (call result) */ + lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ + lua_pop(L, 1); /* remove _LOADED table */ + if (glb) { + lua_pushvalue(L, -1); /* copy of 'mod' */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } +} + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; (void)osize; /* not used */ + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; /* return to Lua to abort */ +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + + +LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { + const lua_Number *v = lua_version(L); + if (v != lua_version(NULL)) + luaL_error(L, "multiple Lua VMs detected"); + else if (*v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + ver, *v); + /* check conversions number -> integer types */ + lua_pushnumber(L, -(lua_Number)0x1234); + if (lua_tointeger(L, -1) != -0x1234 || + lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) + luaL_error(L, "bad conversion number->int;" + " must recompile Lua with proper settings"); + lua_pop(L, 1); +} + diff --git a/src/external/lua-5.2.3/src/lauxlib.h b/src/external/lua-5.2.3/src/lauxlib.h new file mode 100644 index 000000000..0fb023b8e --- /dev/null +++ b/src/external/lua-5.2.3/src/lauxlib.h @@ -0,0 +1,212 @@ +/* +** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); +#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) + +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); +LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); +LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, + lua_Unsigned def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); +LUALIB_API int (luaL_execresult) (lua_State *L, int stat); + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + +LUALIB_API int (luaL_len) (lua_State *L, int idx); + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); + +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); + +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +typedef struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + char initb[LUAL_BUFFERSIZE]; /* initial buffer */ +} luaL_Buffer; + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + + +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ + +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ + +#define LUA_FILEHANDLE "FILE*" + + +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + + + +/* compatibility with old module system */ +#if defined(LUA_COMPAT_MODULE) + +LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, + int sizehint); +LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); + +#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) + +#endif + + +#endif + + diff --git a/src/external/lua-5.2.3/src/lbaselib.c b/src/external/lua-5.2.3/src/lbaselib.c new file mode 100644 index 000000000..5255b3cd9 --- /dev/null +++ b/src/external/lua-5.2.3/src/lbaselib.c @@ -0,0 +1,458 @@ +/* +** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + size_t l; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tolstring(L, -1, &l); /* get result */ + if (s == NULL) + return luaL_error(L, + LUA_QL("tostring") " must return a string to " LUA_QL("print")); + if (i>1) luai_writestring("\t", 1); + luai_writestring(s, l); + lua_pop(L, 1); /* pop result */ + } + luai_writeline(); + return 0; +} + + +#define SPACECHARS " \f\n\r\t\v" + +static int luaB_tonumber (lua_State *L) { + if (lua_isnoneornil(L, 2)) { /* standard conversion */ + int isnum; + lua_Number n = lua_tonumberx(L, 1, &isnum); + if (isnum) { + lua_pushnumber(L, n); + return 1; + } /* else not a number; must be something */ + luaL_checkany(L, 1); + } + else { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *e = s + l; /* end point for 's' */ + int base = luaL_checkint(L, 2); + int neg = 0; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') { s++; neg = 1; } /* handle signal */ + else if (*s == '+') s++; + if (isalnum((unsigned char)*s)) { + lua_Number n = 0; + do { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : toupper((unsigned char)*s) - 'A' + 10; + if (digit >= base) break; /* invalid numeral; force a fail */ + n = n * (lua_Number)base + (lua_Number)digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + if (s == e) { /* no invalid trailing characters? */ + lua_pushnumber(L, (neg) ? -n : n); + return 1; + } /* else not a number */ + } /* else not a number */ + } + lua_pushnil(L); /* not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + return luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawlen (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string expected"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", + "setmajorinc", "isrunning", "generational", "incremental", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, o, ex); + switch (o) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + lua_pushinteger(L, b); + return 2; + } + case LUA_GCSTEP: case LUA_GCISRUNNING: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushinteger(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int pairsmeta (lua_State *L, const char *method, int iszero, + lua_CFunction iter) { + if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ + luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ + lua_pushcfunction(L, iter); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + if (iszero) lua_pushinteger(L, 0); /* and initial value */ + else lua_pushnil(L); + } + else { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_call(L, 1, 3); /* get 3 values from metamethod */ + } + return 3; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + return pairsmeta(L, "__pairs", 0, luaB_next); +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 1 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + return pairsmeta(L, "__ipairs", 1, ipairsaux); +} + + +static int load_aux (lua_State *L, int status, int envidx) { + if (status == LUA_OK) { + if (envidx != 0) { /* 'env' parameter? */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ + } + return 1; + } + else { /* error (message is on top of the stack) */ + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + const char *mode = luaL_optstring(L, 2, NULL); + int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ + int status = luaL_loadfilex(L, fname, mode); + return load_aux(L, status, env); +} + + +/* +** {====================================================== +** Generic Read function +** ======================================================= +*/ + + +/* +** reserved slot, above all arguments, to hold a copy of the returned +** string to avoid it being collected while parsed. 'load' has four +** optional arguments (chunk, source name, mode, and environment). +*/ +#define RESERVEDSLOT 5 + + +/* +** Reader for generic `load' function: `lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)(ud); /* not used */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* pop result */ + *size = 0; + return NULL; + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "reader function must return a string"); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); +} + + +static int luaB_load (lua_State *L) { + int status; + size_t l; + const char *s = lua_tolstring(L, 1, &l); + const char *mode = luaL_optstring(L, 3, "bt"); + int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ + if (s != NULL) { /* loading a string? */ + const char *chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, l, chunkname, mode); + } + else { /* loading from a reader function */ + const char *chunkname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); + } + return load_aux(L, status, env); +} + +/* }====================================================== */ + + +static int dofilecont (lua_State *L) { + return lua_gettop(L) - 1; +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + lua_settop(L, 1); + if (luaL_loadfile(L, fname) != LUA_OK) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); + return dofilecont(L); +} + + +static int luaB_assert (lua_State *L) { + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + + +static int finishpcall (lua_State *L, int status) { + if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */ + lua_settop(L, 0); /* create space for return values */ + lua_pushboolean(L, 0); + lua_pushstring(L, "stack overflow"); + return 2; /* return false, msg */ + } + lua_pushboolean(L, status); /* first result (status) */ + lua_replace(L, 1); /* put first result in first slot */ + return lua_gettop(L); +} + + +static int pcallcont (lua_State *L) { + int status = lua_getctx(L, NULL); + return finishpcall(L, (status == LUA_YIELD)); +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + lua_pushnil(L); + lua_insert(L, 1); /* create space for status result */ + status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); + return finishpcall(L, (status == LUA_OK)); +} + + +static int luaB_xpcall (lua_State *L) { + int status; + int n = lua_gettop(L); + luaL_argcheck(L, n >= 2, 2, "value expected"); + lua_pushvalue(L, 1); /* exchange function... */ + lua_copy(L, 2, 1); /* ...and error handler */ + lua_replace(L, 2); + status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); + return finishpcall(L, (status == LUA_OK)); +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, +#if defined(LUA_COMPAT_LOADSTRING) + {"loadstring", luaB_load}, +#endif + {"next", luaB_next}, + {"pairs", luaB_pairs}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"xpcall", luaB_xpcall}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_base (lua_State *L) { + /* set global _G */ + lua_pushglobaltable(L); + lua_pushglobaltable(L); + lua_setfield(L, -2, "_G"); + /* open lib into global table */ + luaL_setfuncs(L, base_funcs, 0); + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ + return 1; +} + diff --git a/src/external/lua-5.2.3/src/lbitlib.c b/src/external/lua-5.2.3/src/lbitlib.c new file mode 100644 index 000000000..31c7b66f1 --- /dev/null +++ b/src/external/lua-5.2.3/src/lbitlib.c @@ -0,0 +1,212 @@ +/* +** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $ +** Standard library for bitwise operations +** See Copyright Notice in lua.h +*/ + +#define lbitlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* number of bits to consider in a number */ +#if !defined(LUA_NBITS) +#define LUA_NBITS 32 +#endif + + +#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) + +/* macro to trim extra bits */ +#define trim(x) ((x) & ALLONES) + + +/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ +#define mask(n) (~((ALLONES << 1) << ((n) - 1))) + + +typedef lua_Unsigned b_uint; + + + +static b_uint andaux (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = ~(b_uint)0; + for (i = 1; i <= n; i++) + r &= luaL_checkunsigned(L, i); + return trim(r); +} + + +static int b_and (lua_State *L) { + b_uint r = andaux(L); + lua_pushunsigned(L, r); + return 1; +} + + +static int b_test (lua_State *L) { + b_uint r = andaux(L); + lua_pushboolean(L, r != 0); + return 1; +} + + +static int b_or (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r |= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_xor (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r ^= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_not (lua_State *L) { + b_uint r = ~luaL_checkunsigned(L, 1); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_shift (lua_State *L, b_uint r, int i) { + if (i < 0) { /* shift right? */ + i = -i; + r = trim(r); + if (i >= LUA_NBITS) r = 0; + else r >>= i; + } + else { /* shift left */ + if (i >= LUA_NBITS) r = 0; + else r <<= i; + r = trim(r); + } + lua_pushunsigned(L, r); + return 1; +} + + +static int b_lshift (lua_State *L) { + return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); +} + + +static int b_rshift (lua_State *L) { + return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); +} + + +static int b_arshift (lua_State *L) { + b_uint r = luaL_checkunsigned(L, 1); + int i = luaL_checkint(L, 2); + if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) + return b_shift(L, r, -i); + else { /* arithmetic shift for 'negative' number */ + if (i >= LUA_NBITS) r = ALLONES; + else + r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ + lua_pushunsigned(L, r); + return 1; + } +} + + +static int b_rot (lua_State *L, int i) { + b_uint r = luaL_checkunsigned(L, 1); + i &= (LUA_NBITS - 1); /* i = i % NBITS */ + r = trim(r); + if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ + r = (r << i) | (r >> (LUA_NBITS - i)); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_lrot (lua_State *L) { + return b_rot(L, luaL_checkint(L, 2)); +} + + +static int b_rrot (lua_State *L) { + return b_rot(L, -luaL_checkint(L, 2)); +} + + +/* +** get field and width arguments for field-manipulation functions, +** checking whether they are valid. +** ('luaL_error' called without 'return' to avoid later warnings about +** 'width' being used uninitialized.) +*/ +static int fieldargs (lua_State *L, int farg, int *width) { + int f = luaL_checkint(L, farg); + int w = luaL_optint(L, farg + 1, 1); + luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); + luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + if (f + w > LUA_NBITS) + luaL_error(L, "trying to access non-existent bits"); + *width = w; + return f; +} + + +static int b_extract (lua_State *L) { + int w; + b_uint r = luaL_checkunsigned(L, 1); + int f = fieldargs(L, 2, &w); + r = (r >> f) & mask(w); + lua_pushunsigned(L, r); + return 1; +} + + +static int b_replace (lua_State *L) { + int w; + b_uint r = luaL_checkunsigned(L, 1); + b_uint v = luaL_checkunsigned(L, 2); + int f = fieldargs(L, 3, &w); + int m = mask(w); + v &= m; /* erase bits outside given width */ + r = (r & ~(m << f)) | (v << f); + lua_pushunsigned(L, r); + return 1; +} + + +static const luaL_Reg bitlib[] = { + {"arshift", b_arshift}, + {"band", b_and}, + {"bnot", b_not}, + {"bor", b_or}, + {"bxor", b_xor}, + {"btest", b_test}, + {"extract", b_extract}, + {"lrotate", b_lrot}, + {"lshift", b_lshift}, + {"replace", b_replace}, + {"rrotate", b_rrot}, + {"rshift", b_rshift}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_bit32 (lua_State *L) { + luaL_newlib(L, bitlib); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/lcode.c b/src/external/lua-5.2.3/src/lcode.c new file mode 100644 index 000000000..820b95c0e --- /dev/null +++ b/src/external/lua-5.2.3/src/lcode.c @@ -0,0 +1,881 @@ +/* +** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + int l = from + n - 1; /* last register to set nil */ + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; + } + } /* else go through */ + } + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { + level++; /* argument is +1 to reserve 0 as non-op */ + while (list != NO_JUMP) { + int next = getjump(fs, list); + lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && + (GETARG_A(fs->f->code[list]) == 0 || + GETARG_A(fs->f->code[list]) >= level)); + SETARG_A(fs->f->code[list], level); + list = next; + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +static int luaK_code (FuncState *fs, Instruction i) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "opcodes"); + f->lineinfo[fs->pc] = fs->ls->lastline; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); + return luaK_code(fs, CREATE_ABC(o, a, b, c)); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); +} + + +static int codeextraarg (FuncState *fs, int a) { + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +} + + +int luaK_codek (FuncState *fs, int reg, int k) { + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.info); +} + + +static int addk (FuncState *fs, TValue *key, TValue *v) { + lua_State *L = fs->ls->L; + TValue *idx = luaH_set(L, fs->h, key); + Proto *f = fs->f; + int k, oldsize; + if (ttisnumber(idx)) { + lua_Number n = nvalue(idx); + lua_number2int(k, n); + if (luaV_rawequalobj(&f->k[k], v)) + return k; + /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); + go through and create a new entry for this value */ + } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setnvalue(idx, cast_num(k)); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->ls->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + int n; + lua_State *L = fs->ls->L; + TValue o; + setnvalue(&o, r); + if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ + /* use raw representation as key to avoid numeric problems */ + setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); + n = addk(fs, L->top - 1, &o); + L->top--; + } + else + n = addk(fs, &o, &o); /* regular case */ + return n; +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->ls->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ + freereg(fs, e->u.ind.idx); + if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ + freereg(fs, e->u.ind.t); + op = OP_GETTABLE; + } + e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codek(fs, reg, e->u.info); + break; + } + case VKNUM: { + luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ + if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put value on it */ + return e->u.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.info; +} + + +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ + e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.info); + } + else break; + } + case VKNUM: { + e->u.info = luaK_numberK(fs, e->u.nval); + e->k = VK; + /* go through */ + } + case VK: { + if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ + return RKASK(e->u.info); + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); + break; + } + case VINDEXED: { + OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int ereg; + luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ + freeexp(fs, e); + e->u.info = fs->freereg; /* base register for op_self */ + e->k = VNONRELOC; + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); + freeexp(fs, key); +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + invertjump(fs, e); + pc = e->u.info; + break; + } + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VJMP: { + pc = e->u.info; + break; + } + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + lua_assert(!hasjumps(t)); + t->u.ind.t = t->u.info; + t->u.ind.idx = luaK_exp2RK(fs, k); + t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL + : check_exp(vkisinreg(t->k), VLOCAL); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) + return 0; /* do not attempt to divide by 0 */ + r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + luaK_fixline(fs, line); + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (isnumeral(e)) /* minus constant? */ + e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ + else { + luaK_exp2anyreg(fs, e); + codearith(fs, OP_UNM, e, &e2, line); + } + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2, line); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.info); + e1->k = VRELOCABLE; e1->u.info = e2->u.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2, line); + } + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); + break; + } + case OPR_EQ: case OPR_LT: case OPR_LE: { + codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); + break; + } + case OPR_NE: case OPR_GT: case OPR_GE: { + codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else if (c <= MAXARG_Ax) { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + codeextraarg(fs, c); + } + else + luaX_syntaxerror(fs->ls, "constructor too long"); + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/src/external/lua-5.2.3/src/lcode.h b/src/external/lua-5.2.3/src/lcode.h new file mode 100644 index 000000000..6a1424cf5 --- /dev/null +++ b/src/external/lua-5.2.3/src/lcode.h @@ -0,0 +1,83 @@ +/* +** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums (ORDER OP) +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/src/external/lua-5.2.3/src/lcorolib.c b/src/external/lua-5.2.3/src/lcorolib.c new file mode 100644 index 000000000..ce4f6ad42 --- /dev/null +++ b/src/external/lua-5.2.3/src/lcorolib.c @@ -0,0 +1,155 @@ +/* +** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $ +** Coroutine Library +** See Copyright Notice in lua.h +*/ + + +#include + + +#define lcorolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status; + if (!lua_checkstack(co, narg)) { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { + lua_pushliteral(L, "cannot resume dead coroutine"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg); + if (status == LUA_OK || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + if (L == co) lua_pushliteral(L, "running"); + else { + switch (lua_status(co)) { + case LUA_YIELD: + lua_pushliteral(L, "suspended"); + break; + case LUA_OK: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + lua_pushliteral(L, "normal"); /* it is running */ + else if (lua_gettop(co) == 0) + lua_pushliteral(L, "dead"); + else + lua_pushliteral(L, "suspended"); /* initial state */ + break; + } + default: /* some error occurred */ + lua_pushliteral(L, "dead"); + break; + } + } + return 1; +} + + +static int luaB_corunning (lua_State *L) { + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_coroutine (lua_State *L) { + luaL_newlib(L, co_funcs); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/lctype.c b/src/external/lua-5.2.3/src/lctype.c new file mode 100644 index 000000000..93f8cadc3 --- /dev/null +++ b/src/external/lua-5.2.3/src/lctype.c @@ -0,0 +1,52 @@ +/* +** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#define lctype_c +#define LUA_CORE + +#include "lctype.h" + +#if !LUA_USE_CTYPE /* { */ + +#include + +LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { + 0x00, /* EOZ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ + 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#endif /* } */ diff --git a/src/external/lua-5.2.3/src/lctype.h b/src/external/lua-5.2.3/src/lctype.h new file mode 100644 index 000000000..b09b21a33 --- /dev/null +++ b/src/external/lua-5.2.3/src/lctype.h @@ -0,0 +1,95 @@ +/* +** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + +/* +** this 'ltolower' only works for alphabetic characters +*/ +#define ltolower(c) ((c) | ('A' ^ 'a')) + + +/* two more entries for 0 and -1 (EOZ) */ +LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/src/external/lua-5.2.3/src/ldblib.c b/src/external/lua-5.2.3/src/ldblib.c new file mode 100644 index 000000000..84fe3c7d8 --- /dev/null +++ b/src/external/lua-5.2.3/src/ldblib.c @@ -0,0 +1,398 @@ +/* +** $Id: ldblib.c,v 1.132.1.1 2013/04/12 18:48:47 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define HOOKKEY "_HKEY" + + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; /* return 1st argument */ +} + + +static int db_getuservalue (lua_State *L) { + if (lua_type(L, 1) != LUA_TUSERDATA) + lua_pushnil(L); + else + lua_getuservalue(L, 1); + return 1; +} + + +static int db_setuservalue (lua_State *L) { + if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) + luaL_argerror(L, 1, "full userdata expected, got light userdata"); + luaL_checktype(L, 1, LUA_TUSERDATA); + if (!lua_isnoneornil(L, 2)) + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + lua_setuservalue(L, 1); + return 1; +} + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsb (lua_State *L, const char *i, int v) { + lua_pushboolean(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnStu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) { + settabsi(L, "nups", ar.nups); + settabsi(L, "nparams", ar.nparams); + settabsb(L, "isvararg", ar.isvararg); + } + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 't')) + settabsb(L, "istailcall", ar.istailcall); + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + int nvar = luaL_checkint(L, arg+2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) { /* function argument? */ + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ + return 1; + } + else { /* stack-level argument */ + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, nvar); + if (name) { + lua_xmove(L1, L, 1); /* push local value */ + lua_pushstring(L, name); /* push name */ + lua_pushvalue(L, -2); /* re-order */ + return 2; + } + else { + lua_pushnil(L); /* no name (nor value) */ + return 1; + } + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + +static int checkupval (lua_State *L, int argf, int argnup) { + lua_Debug ar; + int nup = luaL_checkint(L, argnup); + luaL_checktype(L, argf, LUA_TFUNCTION); + lua_pushvalue(L, argf); + lua_getinfo(L, ">u", &ar); + luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index"); + return nup; +} + + +static int db_upvalueid (lua_State *L) { + int n = checkupval(L, 1, 2); + lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); + return 1; +} + + +static int db_upvaluejoin (lua_State *L) { + int n1 = checkupval(L, 1, 2); + int n2 = checkupval(L, 3, 4); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); + lua_upvaluejoin(L, 1, n1, 3, n2); + return 0; +} + + +#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY) + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail call"}; + gethooktable(L); + lua_pushthread(L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + if (gethooktable(L) == 0) { /* creating hook table? */ + lua_pushstring(L, "k"); + lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ + } + lua_pushthread(L1); lua_xmove(L1, L, 1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushthread(L1); lua_xmove(L1, L, 1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + luai_writestringerror("%s", "lua_debug> "); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) + luai_writestringerror("%s\n", lua_tostring(L, -1)); + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +static int db_traceback (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + const char *msg = lua_tostring(L, arg + 1); + if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ + else { + int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0); + luaL_traceback(L, L1, msg, level); + } + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getuservalue", db_getuservalue}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"upvaluejoin", db_upvaluejoin}, + {"upvalueid", db_upvalueid}, + {"setuservalue", db_setuservalue}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_traceback}, + {NULL, NULL} +}; + + +LUAMOD_API int luaopen_debug (lua_State *L) { + luaL_newlib(L, dblib); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/ldebug.c b/src/external/lua-5.2.3/src/ldebug.c new file mode 100644 index 000000000..20d663eff --- /dev/null +++ b/src/external/lua-5.2.3/src/ldebug.c @@ -0,0 +1,593 @@ +/* +** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (CallInfo *ci) { + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); +} + + +static int currentline (CallInfo *ci) { + return getfuncline(ci_func(ci)->p, currentpc(ci)); +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + if (isLua(L->ci)) + L->oldpc = L->ci->u.l.savedpc; + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ + lua_lock(L); + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) + level--; + if (level == 0 && ci != &L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = ci; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static const char *upvalname (Proto *p, int uv) { + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) return "?"; + else return getstr(s); +} + + +static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + int nparams = clLvalue(ci->func)->p->numparams; + if (n >= ci->u.l.base - ci->func - nparams) + return NULL; /* no such vararg */ + else { + *pos = ci->func + nparams + n; + return "(*vararg)"; /* generic name for any vararg */ + } +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos) { + const char *name = NULL; + StkId base; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, -n, pos); + else { + base = ci->u.l.base; + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + } + else + base = ci->func + 1; + if (name == NULL) { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top : ci->next->func; + if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + name = "(*temporary)"; /* generic name for any valid slot */ + else + return NULL; /* no name */ + } + *pos = base + (n - 1); + return name; +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + lua_lock(L); + if (ar == NULL) { /* information about non-active function? */ + if (!isLfunction(L->top - 1)) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); + } + else { /* active function; get information through 'ar' */ + StkId pos = 0; /* to avoid warnings */ + name = findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobj2s(L, L->top, pos); + api_incr_top(L); + } + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + StkId pos = 0; /* to avoid warnings */ + const char *name = findlocal(L, ar->i_ci, n, &pos); + lua_lock(L); + if (name) + setobjs2s(L, pos, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (noLuaClosure(cl)) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + Proto *p = cl->l.p; + ar->source = p->source ? getstr(p->source) : "=?"; + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (noLuaClosure(f)) { + setnilvalue(L->top); + api_incr_top(L); + } + else { + int i; + TValue v; + int *lineinfo = f->l.p->lineinfo; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue(L, L->top, t); /* push it on stack */ + api_incr_top(L); + setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ + for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ + luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ + } +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; + break; + } + case 'u': { + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (noLuaClosure(f)) { + ar->isvararg = 1; + ar->nparams = 0; + } + else { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; + break; + } + case 'n': { + /* calling function is a known Lua function? */ + if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) + ar->namewhat = getfuncname(L, ci->previous, &ar->name); + else + ar->namewhat = NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *cl; + CallInfo *ci; + StkId func; + lua_lock(L); + if (*what == '>') { + ci = NULL; + func = L->top - 1; + api_check(L, ttisfunction(func), "function expected"); + what++; /* skip the '>' */ + L->top--; /* pop function */ + } + else { + ci = ar->i_ci; + func = ci->func; + lua_assert(ttisfunction(ci->func)); + } + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); + if (strchr(what, 'f')) { + setobjs2s(L, L->top, func); + api_incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, cl); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution +** ======================================================= +*/ + +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name); + + +/* +** find a "name" for the RK value 'c' +*/ +static void kname (Proto *p, int pc, int c, const char **name) { + if (ISK(c)) { /* is 'c' a constant? */ + TValue *kvalue = &p->k[INDEXK(c)]; + if (ttisstring(kvalue)) { /* literal constant? */ + *name = svalue(kvalue); /* it is its own name */ + return; + } + /* else no reasonable name found */ + } + else { /* 'c' is a register */ + const char *what = getobjname(p, pc, c, name); /* search for 'c' */ + if (what && *what == 'c') { /* found a constant name? */ + return; /* 'name' already filled */ + } + /* else no reasonable name found */ + } + *name = "?"; /* no reasonable name found */ +} + + +static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else return pc; /* current position sets that register */ +} + + +/* +** try to find last instruction before 'lastpc' that modified register 'reg' +*/ +static int findsetreg (Proto *p, int lastpc, int reg) { + int pc; + int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ + for (pc = 0; pc < lastpc; pc++) { + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + switch (op) { + case OP_LOADNIL: { + int b = GETARG_B(i); + if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_TFORCALL: { + if (reg >= a + 2) /* affect all regs above its base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (reg >= a) /* affect all registers above base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_JMP: { + int b = GETARG_sBx(i); + int dest = pc + 1 + b; + /* jump is forward and do not skip `lastpc'? */ + if (pc < dest && dest <= lastpc) { + if (dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + } + break; + } + case OP_TEST: { + if (reg == a) /* jumped code can change 'a' */ + setreg = filterpc(pc, jmptarget); + break; + } + default: + if (testAMode(op) && reg == a) /* any instruction that set A */ + setreg = filterpc(pc, jmptarget); + break; + } + } + return setreg; +} + + +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name) { + int pc; + *name = luaF_getlocalname(p, reg + 1, lastpc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + pc = findsetreg(p, lastpc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_MOVE: { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return getobjname(p, pc, b, name); /* get name for 'b' */ + break; + } + case OP_GETTABUP: + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + int t = GETARG_B(i); /* table index */ + const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ + ? luaF_getlocalname(p, t + 1, pc) + : upvalname(p, t); + kname(p, pc, k, name); + return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; + } + case OP_GETUPVAL: { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: + case OP_LOADKX: { + int b = (op == OP_LOADK) ? GETARG_Bx(i) + : GETARG_Ax(p->code[pc + 1]); + if (ttisstring(&p->k[b])) { + *name = svalue(&p->k[b]); + return "constant"; + } + break; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + kname(p, pc, k, name); + return "method"; + } + default: break; /* go through to return NULL */ + } + } + return NULL; /* could not find reasonable name */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + TMS tm; + Proto *p = ci_func(ci)->p; /* calling function */ + int pc = currentpc(ci); /* calling instruction index */ + Instruction i = p->code[pc]; /* calling instruction */ + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: /* get function name */ + return getobjname(p, pc, GETARG_A(i), name); + case OP_TFORCALL: { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* all other instructions can call only through metamethods */ + case OP_SELF: + case OP_GETTABUP: + case OP_GETTABLE: tm = TM_INDEX; break; + case OP_SETTABUP: + case OP_SETTABLE: tm = TM_NEWINDEX; break; + case OP_EQ: tm = TM_EQ; break; + case OP_ADD: tm = TM_ADD; break; + case OP_SUB: tm = TM_SUB; break; + case OP_MUL: tm = TM_MUL; break; + case OP_DIV: tm = TM_DIV; break; + case OP_MOD: tm = TM_MOD; break; + case OP_POW: tm = TM_POW; break; + case OP_UNM: tm = TM_UNM; break; + case OP_LEN: tm = TM_LEN; break; + case OP_LT: tm = TM_LT; break; + case OP_LE: tm = TM_LE; break; + case OP_CONCAT: tm = TM_CONCAT; break; + default: + return NULL; /* else no useful name can be found */ + } + *name = getstr(G(L)->tmname[tm]); + return "metamethod"; +} + +/* }====================================================== */ + + + +/* +** only ANSI way to check whether a pointer points to an array +** (used only for error messages, so efficiency is not a big concern) +*/ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->u.l.base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +static const char *getupvalname (CallInfo *ci, const TValue *o, + const char **name) { + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) { + if (c->upvals[i]->v == o) { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; +} + + +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + CallInfo *ci = L->ci; + const char *name = NULL; + const char *t = objtypename(o); + const char *kind = NULL; + if (isLua(ci)) { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind && isinstack(ci, o)) /* no? try a register */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), + cast_int(o - ci->u.l.base), &name); + } + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = objtypename(p1); + const char *t2 = objtypename(p2); + if (t1 == t2) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(ci); + TString *src = ci_func(ci)->p->source; + if (src) + luaO_chunkid(buff, getstr(src), LUA_IDSIZE); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +l_noret luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + L->top++; + luaD_call(L, L->top - 2, 1, 0); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/src/external/lua-5.2.3/src/ldebug.h b/src/external/lua-5.2.3/src/ldebug.h new file mode 100644 index 000000000..6445c763e --- /dev/null +++ b/src/external/lua-5.2.3/src/ldebug.h @@ -0,0 +1,34 @@ +/* +** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue((ci)->func)) + + +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); + +#endif diff --git a/src/external/lua-5.2.3/src/ldo.c b/src/external/lua-5.2.3/src/ldo.c new file mode 100644 index 000000000..e9dd5fa95 --- /dev/null +++ b/src/external/lua-5.2.3/src/ldo.c @@ -0,0 +1,681 @@ +/* +** $Id: ldo.c,v 2.108.1.3 2013/11/08 18:22:50 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + +/* +** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By +** default, Lua handles errors with exceptions when compiling as +** C++ code, with _longjmp/_setjmp when asked to use them, and with +** longjmp/setjmp otherwise. +*/ +#if !defined(LUAI_THROW) + +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) \ + try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + +#endif + + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + default: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +l_noret luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ + } + else { /* thread has no error handler */ + L->status = cast_byte(errcode); /* mark it as dead */ + if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ + luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ + } + else { /* no handler at all; abort */ + if (G(L)->panic) { /* panic function? */ + lua_unlock(L); + G(L)->panic(L); /* call it (last chance to jump out) */ + } + abort(); + } + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + unsigned short oldnCcalls = L->nCcalls; + struct lua_longjmp lj; + lj.status = LUA_OK; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + ci->top = (ci->top - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + if (isLua(ci)) + ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; + } +} + + +/* some space for error handling */ +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int lim = L->stacksize; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); + for (; lim < newsize; lim++) + setnilvalue(L->stack + lim); /* erase new segment */ + L->stacksize = newsize; + L->stack_last = L->stack + newsize - EXTRA_STACK; + correctstack(L, oldstack); +} + + +void luaD_growstack (lua_State *L, int n) { + int size = L->stacksize; + if (size > LUAI_MAXSTACK) /* error after extra size? */ + luaD_throw(L, LUA_ERRERR); + else { + int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; + int newsize = 2 * size; + if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; + if (newsize < needed) newsize = needed; + if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ + luaD_reallocstack(L, ERRORSTACKSIZE); + luaG_runerror(L, "stack overflow"); + } + else + luaD_reallocstack(L, newsize); + } +} + + +static int stackinuse (lua_State *L) { + CallInfo *ci; + StkId lim = L->top; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + lua_assert(ci->top <= L->stack_last); + if (lim < ci->top) lim = ci->top; + } + return cast_int(lim - L->stack) + 1; /* part of stack in use */ +} + + +void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); + int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; + if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; + if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ + goodsize >= L->stacksize) /* would grow instead of shrink? */ + condmovestack(L); /* don't change stack (change only for debugging) */ + else + luaD_reallocstack(L, goodsize); /* shrink it */ +} + + +void luaD_hook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + CallInfo *ci = L->ci; + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= CIST_HOOKED; + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + ci->callstatus &= ~CIST_HOOKED; + } +} + + +static void callhook (lua_State *L, CallInfo *ci) { + int hook = LUA_HOOKCALL; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + if (isLua(ci->previous) && + GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { + ci->callstatus |= CIST_TAIL; + hook = LUA_HOOKTAILCALL; + } + luaD_hook(L, hook, -1); + ci->u.l.savedpc--; /* correct 'pc' */ +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + StkId base, fixed; + lua_assert(actual >= nfixargs); + /* move fixed parameters to final position */ + luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed + i); + setnilvalue(fixed + i); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) + + +/* +** returns true if function has been executed (C function) +*/ +int luaD_precall (lua_State *L, StkId func, int nresults) { + lua_CFunction f; + CallInfo *ci; + int n; /* number of arguments (Lua) or returns (C) */ + ptrdiff_t funcr = savestack(L, func); + switch (ttype(func)) { + case LUA_TLCF: /* light C function */ + f = fvalue(func); + goto Cfunc; + case LUA_TCCL: { /* C closure */ + f = clCvalue(func)->f; + Cfunc: + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = restorestack(L, funcr); + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, L->top - n); + return 1; + } + case LUA_TLCL: { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + n = cast_int(L->top - func) - 1; /* number of real arguments */ + luaD_checkstack(L, p->maxstacksize); + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + if (!p->is_vararg) { + func = restorestack(L, funcr); + base = func + 1; + } + else { + base = adjust_varargs(L, p, n); + func = restorestack(L, funcr); /* previous call can change stack */ + } + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + ci->top = base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + L->top = ci->top; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* retry with 'function' tag method */ + return luaD_precall(L, func, nresults); /* now it must be a function */ + } + } +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci = L->ci; + if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { + if (L->hookmask & LUA_MASKRET) { + ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ + luaD_hook(L, LUA_HOOKRET, -1); + firstResult = restorestack(L, fr); + } + L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ + } + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->ci = ci = ci->previous; /* back to caller */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (!allowyield) L->nny++; + if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ + luaV_execute(L); /* call it */ + if (!allowyield) L->nny--; + L->nCcalls--; +} + + +static void finishCcall (lua_State *L) { + CallInfo *ci = L->ci; + int n; + lua_assert(ci->u.c.k != NULL); /* must have a continuation */ + lua_assert(L->nny == 0); + if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ + ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ + L->errfunc = ci->u.c.old_errfunc; + } + /* finish 'lua_callk'/'lua_pcall' */ + adjustresults(L, ci->nresults); + /* call continuation function */ + if (!(ci->callstatus & CIST_STAT)) /* no call status? */ + ci->u.c.status = LUA_YIELD; /* 'default' status */ + lua_assert(ci->u.c.status != LUA_OK); + ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); + lua_lock(L); + api_checknelems(L, n); + /* finish 'luaD_precall' */ + luaD_poscall(L, L->top - n); +} + + +static void unroll (lua_State *L, void *ud) { + UNUSED(ud); + for (;;) { + if (L->ci == &L->base_ci) /* stack is empty? */ + return; /* coroutine finished normally */ + if (!isLua(L->ci)) /* C function? */ + finishCcall(L); + else { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L); /* execute down to higher C 'boundary' */ + } + } +} + + +/* +** check whether thread has a suspended protected call +*/ +static CallInfo *findpcall (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ +} + + +static int recover (lua_State *L, int status) { + StkId oldtop; + CallInfo *ci = findpcall(L); + if (ci == NULL) return 0; /* no recovery point */ + /* "finish" luaD_pcall */ + oldtop = restorestack(L, ci->extra); + luaF_close(L, oldtop); + seterrorobj(L, status, oldtop); + L->ci = ci; + L->allowhook = ci->u.c.old_allowhook; + L->nny = 0; /* should be zero to be yieldable */ + luaD_shrinkstack(L); + L->errfunc = ci->u.c.old_errfunc; + ci->callstatus |= CIST_STAT; /* call has error status */ + ci->u.c.status = status; /* (here it is) */ + return 1; /* continue running the coroutine */ +} + + +/* +** signal an error in the call to 'resume', not in the execution of the +** coroutine itself. (Such errors should not be handled by any coroutine +** error handler and should not kill the coroutine.) +*/ +static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { + L->top = firstArg; /* remove args from the stack */ + setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + luaD_throw(L, -1); /* jump back to 'lua_resume' */ +} + + +/* +** do the work for 'lua_resume' in protected mode +*/ +static void resume (lua_State *L, void *ud) { + int nCcalls = L->nCcalls; + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (nCcalls >= LUAI_MAXCCALLS) + resume_error(L, "C stack overflow", firstArg); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (ci != &L->base_ci) /* not in base level? */ + resume_error(L, "cannot resume non-suspended coroutine", firstArg); + /* coroutine is in base level; start running it */ + if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ + luaV_execute(L); /* call it */ + } + else if (L->status != LUA_YIELD) + resume_error(L, "cannot resume dead coroutine", firstArg); + else { /* resuming from previous yield */ + L->status = LUA_OK; + ci->func = restorestack(L, ci->extra); + if (isLua(ci)) /* yielded inside a hook? */ + luaV_execute(L); /* just continue running Lua code */ + else { /* 'common' yield */ + if (ci->u.c.k != NULL) { /* does it have a continuation? */ + int n; + ci->u.c.status = LUA_YIELD; /* 'default' status */ + ci->callstatus |= CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + firstArg = L->top - n; /* yield results come from continuation */ + } + luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ + } + unroll(L, NULL); + } + lua_assert(nCcalls == L->nCcalls); +} + + +LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { + int status; + int oldnny = L->nny; /* save 'nny' */ + lua_lock(L); + luai_userstateresume(L, nargs); + L->nCcalls = (from) ? from->nCcalls + 1 : 1; + L->nny = 0; /* allow yields */ + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status == -1) /* error calling 'lua_resume'? */ + status = LUA_ERRRUN; + else { /* yield or regular error */ + while (status != LUA_OK && status != LUA_YIELD) { /* error? */ + if (recover(L, status)) /* recover point? */ + status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ + else { /* unrecoverable error */ + L->status = cast_byte(status); /* mark thread as `dead' */ + seterrorobj(L, status, L->top); + L->ci->top = L->top; + break; + } + } + lua_assert(status == L->status); + } + L->nny = oldnny; /* restore 'nny' */ + L->nCcalls--; + lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); + lua_unlock(L); + return status; +} + + +LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { + CallInfo *ci = L->ci; + luai_userstateyield(L, nresults); + lua_lock(L); + api_checknelems(L, nresults); + if (L->nny > 0) { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } + L->status = LUA_YIELD; + ci->extra = savestack(L, ci->func); /* save current 'func' */ + if (isLua(ci)) { /* inside a hook? */ + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + ci->func = L->top - nresults - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ + lua_unlock(L); + return 0; /* return to 'luaD_hook' */ +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + unsigned short old_nny = L->nny; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != LUA_OK) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close possible pending closures */ + seterrorobj(L, status, oldtop); + L->ci = old_ci; + L->allowhook = old_allowhooks; + L->nny = old_nny; + luaD_shrinkstack(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; + const char *name; +}; + + +static void checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } +} + + +static void f_parser (lua_State *L, void *ud) { + int i; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, &p->buff, p->name); + } + else { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); + for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ + UpVal *up = luaF_newupval(L); + cl->l.upvals[i] = up; + luaC_objbarrier(L, cl, up); + } +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode) { + struct SParser p; + int status; + L->nny++; /* cannot yield during parsing */ + p.z = z; p.name = name; p.mode = mode; + p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; p.dyd.label.size = 0; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + L->nny--; + return status; +} + + diff --git a/src/external/lua-5.2.3/src/ldo.h b/src/external/lua-5.2.3/src/ldo.h new file mode 100644 index 000000000..d3d3082c9 --- /dev/null +++ b/src/external/lua-5.2.3/src/ldo.h @@ -0,0 +1,46 @@ +/* +** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ + luaD_growstack(L, n); else condmovestack(L); + + +#define incr_top(L) {L->top++; luaD_checkstack(L,0);} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, + int allowyield); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); + +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +#endif + diff --git a/src/external/lua-5.2.3/src/ldump.c b/src/external/lua-5.2.3/src/ldump.c new file mode 100644 index 000000000..61fa2cd89 --- /dev/null +++ b/src/external/lua-5.2.3/src/ldump.c @@ -0,0 +1,173 @@ +/* +** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size*sizeof(char),D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttypenv(o),D); + switch (ttypenv(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: lua_assert(0); + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],D); +} + +static void DumpUpvalues(const Proto* f, DumpState* D) +{ + int i,n=f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i].instack,D); + DumpChar(f->upvalues[i].idx,D); + } +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + DumpString((D->strip) ? NULL : f->source,D); + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i].name,D); +} + +static void DumpFunction(const Proto* f, DumpState* D) +{ + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpUpvalues(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + lu_byte h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,&D); + return D.status; +} diff --git a/src/external/lua-5.2.3/src/lfs.c b/src/external/lua-5.2.3/src/lfs.c new file mode 100644 index 000000000..ace995098 --- /dev/null +++ b/src/external/lua-5.2.3/src/lfs.c @@ -0,0 +1,888 @@ +/* +** LuaFileSystem +** Copyright Kepler Project 2003 (http://www.keplerproject.org/luafilesystem) +** +** File system manipulation library. +** This library offers these functions: +** lfs.attributes (filepath [, attributename]) +** lfs.chdir (path) +** lfs.currentdir () +** lfs.dir (path) +** lfs.lock (fh, mode) +** lfs.lock_dir (path) +** lfs.mkdir (path) +** lfs.rmdir (path) +** lfs.setmode (filepath, mode) +** lfs.symlinkattributes (filepath [, attributename]) -- thanks to Sam Roberts +** lfs.touch (filepath [, atime [, mtime]]) +** lfs.unlock (fh) +** +** $Id: lfs.c,v 1.61 2009/07/04 02:10:16 mascarenhas Exp $ +*/ + +#ifndef _WIN32 +#ifndef _AIX +#define _FILE_OFFSET_BITS 64 /* Linux, Solaris and HP-UX */ +#else +#define _LARGE_FILES 1 /* AIX */ +#endif +#endif + +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#include +#include +#ifdef __BORLANDC__ + #include +#else + #include +#endif +#include +#else +#include +#include +#include +#include +#include +#endif + +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + +#include "lfs.h" + +#define LFS_VERSION "1.6.2" +#define LFS_LIBNAME "lfs" + +#if LUA_VERSION_NUM < 502 +# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) +#endif + +/* Define 'strerror' for systems that do not implement it */ +#ifdef NO_STRERROR +#define strerror(_) "System unable to describe the error" +#endif + +/* Define 'getcwd' for systems that do not implement it */ +#ifdef NO_GETCWD +#define getcwd(p,s) NULL +#define getcwd_error "Function 'getcwd' not provided by system" +#else +#define getcwd_error strerror(errno) + #ifdef _WIN32 + /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */ + #define LFS_MAXPATHLEN MAX_PATH + #else + /* For MAXPATHLEN: */ + #include + #define LFS_MAXPATHLEN MAXPATHLEN + #endif +#endif + +#define DIR_METATABLE "directory metatable" +typedef struct dir_data { + int closed; +#ifdef _WIN32 + long hFile; + char pattern[MAX_PATH+1]; +#else + DIR *dir; +#endif +} dir_data; + +#define LOCK_METATABLE "lock metatable" + +#ifdef _WIN32 + #ifdef __BORLANDC__ + #define lfs_setmode(L,file,m) ((void)L, setmode(_fileno(file), m)) + #define STAT_STRUCT struct stati64 + #else + #define lfs_setmode(L,file,m) ((void)L, _setmode(_fileno(file), m)) + #define STAT_STRUCT struct _stati64 + #endif +#define STAT_FUNC _stati64 +#define LSTAT_FUNC STAT_FUNC +#else +#define _O_TEXT 0 +#define _O_BINARY 0 +#define lfs_setmode(L,file,m) ((void)L, (void)file, (void)m, 0) +#define STAT_STRUCT struct stat +#define STAT_FUNC stat +#define LSTAT_FUNC lstat +#endif + +/* +** Utility functions +*/ +static int pusherror(lua_State *L, const char *info) +{ + lua_pushnil(L); + if (info==NULL) + lua_pushstring(L, strerror(errno)); + else + lua_pushfstring(L, "%s: %s", info, strerror(errno)); + lua_pushinteger(L, errno); + return 3; +} + +static int pushresult(lua_State *L, int i, const char *info) +{ + if (i==-1) + return pusherror(L, info); + lua_pushinteger(L, i); + return 1; +} + + +/* +** This function changes the working (current) directory +*/ +static int change_dir (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + if (chdir(path)) { + lua_pushnil (L); + lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n", + path, chdir_error); + return 2; + } else { + lua_pushboolean (L, 1); + return 1; + } +} + +/* +** This function returns the current directory +** If unable to get the current directory, it returns nil +** and a string describing the error +*/ +static int get_dir (lua_State *L) { + char *path; + /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */ + char buf[LFS_MAXPATHLEN]; + if ((path = getcwd(buf, LFS_MAXPATHLEN)) == NULL) { + lua_pushnil(L); + lua_pushstring(L, getcwd_error); + return 2; + } + else { + lua_pushstring(L, path); + return 1; + } +} + +/* +** Check if the given element on the stack is a file and returns it. +*/ +static FILE *check_file (lua_State *L, int idx, const char *funcname) { + FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*"); + if (fh == NULL) { + luaL_error (L, "%s: not a file", funcname); + return 0; + } else if (*fh == NULL) { + luaL_error (L, "%s: closed file", funcname); + return 0; + } else + return *fh; +} + + +/* +** +*/ +static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) { + int code; +#ifdef _WIN32 + /* lkmode valid values are: + LK_LOCK Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error. + LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error. + LK_NBRLCK Same as _LK_NBLCK. + LK_RLCK Same as _LK_LOCK. + LK_UNLCK Unlocks the specified bytes, which must have been previously locked. + + Regions should be locked only briefly and should be unlocked before closing a file or exiting the program. + + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp + */ + int lkmode; + switch (*mode) { + case 'r': lkmode = LK_NBLCK; break; + case 'w': lkmode = LK_NBLCK; break; + case 'u': lkmode = LK_UNLCK; break; + default : return luaL_error (L, "%s: invalid mode", funcname); + } + if (!len) { + fseek (fh, 0L, SEEK_END); + len = ftell (fh); + } + fseek (fh, start, SEEK_SET); +#ifdef __BORLANDC__ + code = locking (fileno(fh), lkmode, len); +#else + code = _locking (fileno(fh), lkmode, len); +#endif +#else + struct flock f; + switch (*mode) { + case 'w': f.l_type = F_WRLCK; break; + case 'r': f.l_type = F_RDLCK; break; + case 'u': f.l_type = F_UNLCK; break; + default : return luaL_error (L, "%s: invalid mode", funcname); + } + f.l_whence = SEEK_SET; + f.l_start = (off_t)start; + f.l_len = (off_t)len; + code = fcntl (fileno(fh), F_SETLK, &f); +#endif + return (code != -1); +} + +#ifdef _WIN32 +typedef struct lfs_Lock { + HANDLE fd; +} lfs_Lock; +static int lfs_lock_dir(lua_State *L) { + size_t pathl; HANDLE fd; + lfs_Lock *lock; + char *ln; + const char *lockfile = "/lockfile.lfs"; + const char *path = luaL_checklstring(L, 1, &pathl); + ln = (char*)malloc(pathl + strlen(lockfile) + 1); + if(!ln) { + lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; + } + strcpy(ln, path); strcat(ln, lockfile); + if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) { + int en = GetLastError(); + free(ln); lua_pushnil(L); + if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION) + lua_pushstring(L, "File exists"); + else + lua_pushstring(L, strerror(en)); + return 2; + } + free(ln); + lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); + lock->fd = fd; + luaL_getmetatable (L, LOCK_METATABLE); + lua_setmetatable (L, -2); + return 1; +} +static int lfs_unlock_dir(lua_State *L) { + lfs_Lock *lock = luaL_checkudata(L, 1, LOCK_METATABLE); + CloseHandle(lock->fd); + return 0; +} +#else +typedef struct lfs_Lock { + char *ln; +} lfs_Lock; +static int lfs_lock_dir(lua_State *L) { + lfs_Lock *lock; + size_t pathl; + char *ln; + const char *lockfile = "/lockfile.lfs"; + const char *path = luaL_checklstring(L, 1, &pathl); + lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); + ln = (char*)malloc(pathl + strlen(lockfile) + 1); + if(!ln) { + lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; + } + strcpy(ln, path); strcat(ln, lockfile); + if(symlink("lock", ln) == -1) { + free(ln); lua_pushnil(L); + lua_pushstring(L, strerror(errno)); return 2; + } + lock->ln = ln; + luaL_getmetatable (L, LOCK_METATABLE); + lua_setmetatable (L, -2); + return 1; +} +static int lfs_unlock_dir(lua_State *L) { + lfs_Lock *lock = luaL_checkudata(L, 1, LOCK_METATABLE); + if(lock->ln) { + unlink(lock->ln); + free(lock->ln); + lock->ln = NULL; + } + return 0; +} +#endif + +static int lfs_g_setmode (lua_State *L, FILE *f, int arg) { + static const int mode[] = {_O_BINARY, _O_TEXT}; + static const char *const modenames[] = {"binary", "text", NULL}; + int op = luaL_checkoption(L, arg, NULL, modenames); + int res = lfs_setmode(L, f, mode[op]); + if (res != -1) { + int i; + lua_pushboolean(L, 1); + for (i = 0; modenames[i] != NULL; i++) { + if (mode[i] == res) { + lua_pushstring(L, modenames[i]); + goto exit; + } + } + lua_pushnil(L); + exit: + return 2; + } else { + int en = errno; + lua_pushnil(L); + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + +static int lfs_f_setmode(lua_State *L) { + return lfs_g_setmode(L, check_file(L, 1, "setmode"), 2); +} + +/* +** Locks a file. +** @param #1 File handle. +** @param #2 String with lock mode ('w'rite, 'r'ead). +** @param #3 Number with start position (optional). +** @param #4 Number with length (optional). +*/ +static int file_lock (lua_State *L) { + FILE *fh = check_file (L, 1, "lock"); + const char *mode = luaL_checkstring (L, 2); + const long start = luaL_optlong (L, 3, 0); + long len = luaL_optlong (L, 4, 0); + if (_file_lock (L, fh, mode, start, len, "lock")) { + lua_pushboolean (L, 1); + return 1; + } else { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } +} + + +/* +** Unlocks a file. +** @param #1 File handle. +** @param #2 Number with start position (optional). +** @param #3 Number with length (optional). +*/ +static int file_unlock (lua_State *L) { + FILE *fh = check_file (L, 1, "unlock"); + const long start = luaL_optlong (L, 2, 0); + long len = luaL_optlong (L, 3, 0); + if (_file_lock (L, fh, "u", start, len, "unlock")) { + lua_pushboolean (L, 1); + return 1; + } else { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } +} + + +/* +** Creates a link. +** @param #1 Object to link to. +** @param #2 Name of link. +** @param #3 True if link is symbolic (optional). +*/ +static int make_link(lua_State *L) +{ +#ifndef _WIN32 + const char *oldpath = luaL_checkstring(L, 1); + const char *newpath = luaL_checkstring(L, 2); + return pushresult(L, + (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL); +#else + pusherror(L, "make_link is not supported on Windows"); +#endif +} + + +/* +** Creates a directory. +** @param #1 Directory path. +*/ +static int make_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + int fail; +#ifdef _WIN32 + fail = _mkdir (path); +#else + fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); +#endif + if (fail) { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } + lua_pushboolean (L, 1); + return 1; +} + +/* +** Removes a directory. +** @param #1 Directory path. +*/ +static int remove_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + int fail; + + fail = rmdir (path); + + if (fail) { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } + lua_pushboolean (L, 1); + return 1; +} + +/* +** Directory iterator +*/ +static int dir_iter (lua_State *L) { +#ifdef _WIN32 + struct _finddata_t c_file; +#else + struct dirent *entry; +#endif + dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE); + luaL_argcheck (L, d->closed == 0, 1, "closed directory"); +#ifdef _WIN32 + if (d->hFile == 0L) { /* first entry */ + if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { + lua_pushnil (L); + lua_pushstring (L, strerror (errno)); + d->closed = 1; + return 2; + } else { + lua_pushstring (L, c_file.name); + return 1; + } + } else { /* next entry */ + if (_findnext (d->hFile, &c_file) == -1L) { + /* no more entries => close directory */ + _findclose (d->hFile); + d->closed = 1; + return 0; + } else { + lua_pushstring (L, c_file.name); + return 1; + } + } +#else + if ((entry = readdir (d->dir)) != NULL) { + lua_pushstring (L, entry->d_name); + return 1; + } else { + /* no more entries => close directory */ + closedir (d->dir); + d->closed = 1; + return 0; + } +#endif +} + + +/* +** Closes directory iterators +*/ +static int dir_close (lua_State *L) { + dir_data *d = (dir_data *)lua_touserdata (L, 1); +#ifdef _WIN32 + if (!d->closed && d->hFile) { + _findclose (d->hFile); + } +#else + if (!d->closed && d->dir) { + closedir (d->dir); + } +#endif + d->closed = 1; + return 0; +} + + +/* +** Factory of directory iterators +*/ +static int dir_iter_factory (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + dir_data *d; + lua_pushcfunction (L, dir_iter); + d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); + d->closed = 0; +#ifdef _WIN32 + d->hFile = 0L; + if (strlen(path) > MAX_PATH-2) + luaL_error (L, "path too long: %s", path); + else + sprintf (d->pattern, "%s/*", path); +#else + d->dir = opendir (path); + if (d->dir == NULL) + luaL_error (L, "cannot open %s: %s", path, strerror (errno)); +#endif + return 2; +} + + +/* +** Creates directory metatable. +*/ +static int dir_create_meta (lua_State *L) { + luaL_newmetatable (L, DIR_METATABLE); + + /* Method table */ + lua_newtable(L); + lua_pushcfunction (L, dir_iter); + lua_setfield(L, -2, "next"); + lua_pushcfunction (L, dir_close); + lua_setfield(L, -2, "close"); + + /* Metamethods */ + lua_setfield(L, -2, "__index"); + lua_pushcfunction (L, dir_close); + lua_setfield (L, -2, "__gc"); + return 1; +} + +/* +** Creates lock metatable. +*/ +static int lock_create_meta (lua_State *L) { + luaL_newmetatable (L, LOCK_METATABLE); + + /* Method table */ + lua_newtable(L); + lua_pushcfunction(L, lfs_unlock_dir); + lua_setfield(L, -2, "free"); + + /* Metamethods */ + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, lfs_unlock_dir); + lua_setfield(L, -2, "__gc"); + return 1; +} + + +#ifdef _WIN32 + #ifndef S_ISDIR + #define S_ISDIR(mode) (mode&_S_IFDIR) + #endif + #ifndef S_ISREG + #define S_ISREG(mode) (mode&_S_IFREG) + #endif + #ifndef S_ISLNK + #define S_ISLNK(mode) (0) + #endif + #ifndef S_ISSOCK + #define S_ISSOCK(mode) (0) + #endif + #ifndef S_ISFIFO + #define S_ISFIFO(mode) (0) + #endif + #ifndef S_ISCHR + #define S_ISCHR(mode) (mode&_S_IFCHR) + #endif + #ifndef S_ISBLK + #define S_ISBLK(mode) (0) + #endif +#endif +/* +** Convert the inode protection mode to a string. +*/ +#ifdef _WIN32 +static const char *mode2string (unsigned short mode) { +#else +static const char *mode2string (mode_t mode) { +#endif + if ( S_ISREG(mode) ) + return "file"; + else if ( S_ISDIR(mode) ) + return "directory"; + else if ( S_ISLNK(mode) ) + return "link"; + else if ( S_ISSOCK(mode) ) + return "socket"; + else if ( S_ISFIFO(mode) ) + return "named pipe"; + else if ( S_ISCHR(mode) ) + return "char device"; + else if ( S_ISBLK(mode) ) + return "block device"; + else + return "other"; +} + + +/* +** Set access time and modification values for file +*/ +static int file_utime (lua_State *L) { + const char *file = luaL_checkstring (L, 1); + struct utimbuf utb, *buf; + + if (lua_gettop (L) == 1) /* set to current date/time */ + buf = NULL; + else { + utb.actime = (time_t)luaL_optnumber (L, 2, 0); + utb.modtime = (time_t)luaL_optnumber (L, 3, utb.actime); + buf = &utb; + } + if (utime (file, buf)) { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror (errno)); + return 2; + } + lua_pushboolean (L, 1); + return 1; +} + + +/* inode protection mode */ +static void push_st_mode (lua_State *L, STAT_STRUCT *info) { + lua_pushstring (L, mode2string (info->st_mode)); +} +/* device inode resides on */ +static void push_st_dev (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_dev); +} +/* inode's number */ +static void push_st_ino (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_ino); +} +/* number of hard links to the file */ +static void push_st_nlink (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_nlink); +} +/* user-id of owner */ +static void push_st_uid (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_uid); +} +/* group-id of owner */ +static void push_st_gid (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_gid); +} +/* device type, for special file inode */ +static void push_st_rdev (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_rdev); +} +/* time of last access */ +static void push_st_atime (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, info->st_atime); +} +/* time of last data modification */ +static void push_st_mtime (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, info->st_mtime); +} +/* time of last file status change */ +static void push_st_ctime (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, info->st_ctime); +} +/* file size, in bytes */ +static void push_st_size (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_size); +} +#ifndef _WIN32 +/* blocks allocated for file */ +static void push_st_blocks (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_blocks); +} +/* optimal file system I/O blocksize */ +static void push_st_blksize (lua_State *L, STAT_STRUCT *info) { + lua_pushnumber (L, (lua_Number)info->st_blksize); +} +#endif +static void push_invalid (lua_State *L, STAT_STRUCT *info) { + luaL_error(L, "invalid attribute name"); +#ifndef _WIN32 + info->st_blksize = 0; /* never reached */ +#endif +} + + /* +** Convert the inode protection mode to a permission list. +*/ + +#ifdef _WIN32 +static const char *perm2string (unsigned short mode) { + static char perms[10] = "---------\0"; + int i; + for (i=0;i<9;i++) perms[i]='-'; + if (mode & _S_IREAD) + { perms[0] = 'r'; perms[3] = 'r'; perms[6] = 'r'; } + if (mode & _S_IWRITE) + { perms[1] = 'w'; perms[4] = 'w'; perms[7] = 'w'; } + if (mode & _S_IEXEC) + { perms[2] = 'x'; perms[5] = 'x'; perms[8] = 'x'; } + return perms; +} +#else +static const char *perm2string (mode_t mode) { + static char perms[10] = "---------\0"; + int i; + for (i=0;i<9;i++) perms[i]='-'; + if (mode & S_IRUSR) perms[0] = 'r'; + if (mode & S_IWUSR) perms[1] = 'w'; + if (mode & S_IXUSR) perms[2] = 'x'; + if (mode & S_IRGRP) perms[3] = 'r'; + if (mode & S_IWGRP) perms[4] = 'w'; + if (mode & S_IXGRP) perms[5] = 'x'; + if (mode & S_IROTH) perms[6] = 'r'; + if (mode & S_IWOTH) perms[7] = 'w'; + if (mode & S_IXOTH) perms[8] = 'x'; + return perms; +} +#endif + +/* permssions string */ +static void push_st_perm (lua_State *L, STAT_STRUCT *info) { + lua_pushstring (L, perm2string (info->st_mode)); +} + +typedef void (*_push_function) (lua_State *L, STAT_STRUCT *info); + +struct _stat_members { + const char *name; + _push_function push; +}; + +struct _stat_members members[] = { + { "mode", push_st_mode }, + { "dev", push_st_dev }, + { "ino", push_st_ino }, + { "nlink", push_st_nlink }, + { "uid", push_st_uid }, + { "gid", push_st_gid }, + { "rdev", push_st_rdev }, + { "access", push_st_atime }, + { "modification", push_st_mtime }, + { "change", push_st_ctime }, + { "size", push_st_size }, + { "permissions", push_st_perm }, +#ifndef _WIN32 + { "blocks", push_st_blocks }, + { "blksize", push_st_blksize }, +#endif + { NULL, push_invalid } +}; + +/* +** Get file or symbolic link information +*/ +static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) { + int i; + STAT_STRUCT info; + const char *file = luaL_checkstring (L, 1); + + if (st(file, &info)) { + lua_pushnil (L); + lua_pushfstring (L, "cannot obtain information from file `%s'", file); + return 2; + } + if (lua_isstring (L, 2)) { + int v; + const char *member = lua_tostring (L, 2); + if (strcmp (member, "mode") == 0) v = 0; +#ifndef _WIN32 + else if (strcmp (member, "blocks") == 0) v = 11; + else if (strcmp (member, "blksize") == 0) v = 12; +#endif + else /* look for member */ + for (v = 1; members[v].name; v++) + if (*members[v].name == *member) + break; + /* push member value and return */ + members[v].push (L, &info); + return 1; + } else if (!lua_istable (L, 2)) + /* creates a table if none is given */ + lua_newtable (L); + /* stores all members in table on top of the stack */ + for (i = 0; members[i].name; i++) { + lua_pushstring (L, members[i].name); + members[i].push (L, &info); + lua_rawset (L, -3); + } + return 1; +} + + +/* +** Get file information using stat. +*/ +static int file_info (lua_State *L) { + return _file_info_ (L, STAT_FUNC); +} + + +/* +** Get symbolic link information using lstat. +*/ +static int link_info (lua_State *L) { + return _file_info_ (L, LSTAT_FUNC); +} + + +/* +** Assumes the table is on top of the stack. +*/ +static void set_info (lua_State *L) { + lua_pushliteral (L, "_COPYRIGHT"); + lua_pushliteral (L, "Copyright (C) 2003-2012 Kepler Project"); + lua_settable (L, -3); + lua_pushliteral (L, "_DESCRIPTION"); + lua_pushliteral (L, "LuaFileSystem is a Lua library developed to complement the set of functions related to file systems offered by the standard Lua distribution"); + lua_settable (L, -3); + lua_pushliteral (L, "_VERSION"); + lua_pushliteral (L, "LuaFileSystem "LFS_VERSION); + lua_settable (L, -3); +} + + +static const struct luaL_Reg fslib[] = { + {"attributes", file_info}, + {"chdir", change_dir}, + {"currentdir", get_dir}, + {"dir", dir_iter_factory}, + {"link", make_link}, + {"lock", file_lock}, + {"mkdir", make_dir}, + {"rmdir", remove_dir}, + {"symlinkattributes", link_info}, + {"setmode", lfs_f_setmode}, + {"touch", file_utime}, + {"unlock", file_unlock}, + {"lock_dir", lfs_lock_dir}, + {NULL, NULL}, +}; + +int luaopen_lfs (lua_State *L) { + dir_create_meta (L); + lock_create_meta (L); + luaL_newlib (L, fslib); + lua_pushvalue(L, -1); + lua_setglobal(L, LFS_LIBNAME); + set_info (L); + return 1; +} diff --git a/src/external/lua-5.2.3/src/lfs.def b/src/external/lua-5.2.3/src/lfs.def new file mode 100644 index 000000000..2b69094b0 --- /dev/null +++ b/src/external/lua-5.2.3/src/lfs.def @@ -0,0 +1,5 @@ +LIBRARY lfs.dll +DESCRIPTION "LuaFileSystem" +VERSION 1.5.0 +EXPORTS +luaopen_lfs diff --git a/src/external/lua-5.2.3/src/lfs.h b/src/external/lua-5.2.3/src/lfs.h new file mode 100644 index 000000000..4b52780bb --- /dev/null +++ b/src/external/lua-5.2.3/src/lfs.h @@ -0,0 +1,17 @@ +/* +** LuaFileSystem +** Copyright Kepler Project 2003 (http://www.keplerproject.org/luafilesystem) +** +** $Id: lfs.h,v 1.5 2008/02/19 20:08:23 mascarenhas Exp $ +*/ + +/* Define 'chdir' for systems that do not implement it */ +#ifdef NO_CHDIR +#define chdir(p) (-1) +#define chdir_error "Function 'chdir' not provided by system" +#else +#define chdir_error strerror(errno) +#endif + + +int luaopen_lfs (lua_State *L); diff --git a/src/external/lua-5.2.3/src/lfunc.c b/src/external/lua-5.2.3/src/lfunc.c new file mode 100644 index 000000000..e90e1520c --- /dev/null +++ b/src/external/lua-5.2.3/src/lfunc.c @@ -0,0 +1,161 @@ +/* +** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int n) { + Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; + c->c.nupvalues = cast_byte(n); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int n) { + Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; + c->l.p = NULL; + c->l.nupvalues = cast_byte(n); + while (n--) c->l.upvals[n] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { + GCObject *o = obj2gco(p); + lua_assert(p->v != &p->u.value); + lua_assert(!isold(o) || isold(obj2gco(L))); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, o)) /* is it dead? */ + changewhite(o); /* resurrect it */ + return p; + } + pp = &p->next; + } + /* not found: create a new one */ + uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; + uv->v = level; /* current value lives in the stack */ + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); /* remove upvalue from 'uvhead' list */ + setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ + uv->v = &uv->u.value; /* now current value lives here */ + gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ + g->allgc = o; + luaC_checkupvalcolor(g, uv); + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->cache = NULL; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); + luaM_free(L, f); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/src/external/lua-5.2.3/src/lfunc.h b/src/external/lua-5.2.3/src/lfunc.h new file mode 100644 index 000000000..ca0d3a3e0 --- /dev/null +++ b/src/external/lua-5.2.3/src/lfunc.h @@ -0,0 +1,33 @@ +/* +** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/src/external/lua-5.2.3/src/lgc.c b/src/external/lua-5.2.3/src/lgc.c new file mode 100644 index 000000000..52460dcdd --- /dev/null +++ b/src/external/lua-5.2.3/src/lgc.c @@ -0,0 +1,1220 @@ +/* +** $Id: lgc.c,v 2.140.1.2 2013/04/26 18:22:05 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +/* +** cost of sweeping one element (the size of a small object divided +** by some adjust for the sweep speed) +*/ +#define GCSWEEPCOST ((sizeof(TString) + 4) / 4) + +/* maximum number of elements to sweep in each single step */ +#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) + +/* maximum number of finalizers to call in each GC step */ +#define GCFINALIZENUM 4 + + +/* +** macro to adjust 'stepmul': 'stepmul' is actually used like +** 'stepmul / STEPMULADJ' (value chosen by tests) +*/ +#define STEPMULADJ 200 + + +/* +** macro to adjust 'pause': 'pause' is actually used like +** 'pause / PAUSEADJ' (value chosen by tests) +*/ +#define PAUSEADJ 100 + + +/* +** 'makewhite' erases all color bits plus the old bit and then +** sets only the current white bit +*/ +#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) +#define makewhite(g,x) \ + (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) + +#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) +#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) + + +#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) + +#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) + + +#define checkconsistency(obj) \ + lua_longassert(!iscollectable(obj) || righttt(obj)) + + +#define markvalue(g,o) { checkconsistency(o); \ + if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + +static void reallymarkobject (global_State *g, GCObject *o); + + +/* +** {====================================================== +** Generic functions +** ======================================================= +*/ + + +/* +** one after last element in a hash array +*/ +#define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) + + +/* +** link table 'h' into list pointed by 'p' +*/ +#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) + + +/* +** if key is not marked, mark its entry as dead (therefore removing it +** from the table) +*/ +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (valiswhite(gkey(n))) + setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */ +} + + +/* +** tells whether a key or value can be cleared from a weak +** table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for objects +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (global_State *g, const TValue *o) { + if (!iscollectable(o)) return 0; + else if (ttisstring(o)) { + markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + else return iswhite(gcvalue(o)); +} + + +/* +** barrier that moves collector forward, that is, mark the white object +** being pointed by a black object. +*/ +void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSpause); + lua_assert(gch(o)->tt != LUA_TTABLE); + if (keepinvariantout(g)) /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + else { /* sweep phase */ + lua_assert(issweepphase(g)); + makewhite(g, o); /* mark main obj. as white to avoid other barriers */ + } +} + + +/* +** barrier that moves collector backward, that is, mark the black object +** pointing to a white object as gray again. (Current implementation +** only works for tables; access to 'gclist' is not uniform across +** different types.) +*/ +void luaC_barrierback_ (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); + black2gray(o); /* make object gray (again) */ + gco2t(o)->gclist = g->grayagain; + g->grayagain = o; +} + + +/* +** barrier for prototypes. When creating first closure (cache is +** NULL), use a forward barrier; this may be the only closure of the +** prototype (if it is a "regular" function, with a single instance) +** and the prototype may be big, so it is better to avoid traversing +** it again. Otherwise, use a backward barrier, to avoid marking all +** possible instances. +*/ +LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) { + global_State *g = G(L); + lua_assert(isblack(obj2gco(p))); + if (p->cache == NULL) { /* first time? */ + luaC_objbarrier(L, p, c); + } + else { /* use a backward barrier */ + black2gray(obj2gco(p)); /* make prototype gray (again) */ + p->gclist = g->grayagain; + g->grayagain = obj2gco(p); + } +} + + +/* +** check color (and invariants) for an upvalue that was closed, +** i.e., moved into the 'allgc' list +*/ +void luaC_checkupvalcolor (global_State *g, UpVal *uv) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o)); /* open upvalues are never black */ + if (isgray(o)) { + if (keepinvariant(g)) { + resetoldbit(o); /* see MOVE OLD rule */ + gray2black(o); /* it is being visited now */ + markvalue(g, uv->v); + } + else { + lua_assert(issweepphase(g)); + makewhite(g, o); + } + } +} + + +/* +** create a new collectable object (with given type and size) and link +** it to '*list'. 'offset' tells how many bytes to allocate before the +** object itself (used only by states). +*/ +GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, + int offset) { + global_State *g = G(L); + char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); + GCObject *o = obj2gco(raw + offset); + if (list == NULL) + list = &g->allgc; /* standard list for collectable objects */ + gch(o)->marked = luaC_white(g); + gch(o)->tt = tt; + gch(o)->next = *list; + *list = o; + return o; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Mark functions +** ======================================================= +*/ + + +/* +** mark an object. Userdata, strings, and closed upvalues are visited +** and turned black here. Other objects are marked gray and added +** to appropriate list to be visited (and turned black) later. (Open +** upvalues are already linked in 'headuv' list.) +*/ +static void reallymarkobject (global_State *g, GCObject *o) { + lu_mem size; + white2gray(o); + switch (gch(o)->tt) { + case LUA_TSHRSTR: + case LUA_TLNGSTR: { + size = sizestring(gco2ts(o)); + break; /* nothing else to mark; make it black */ + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + markobject(g, mt); + markobject(g, gco2u(o)->env); + size = sizeudata(gco2u(o)); + break; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v != &uv->u.value) /* open? */ + return; /* open upvalues remain gray */ + size = sizeof(UpVal); + break; + } + case LUA_TLCL: { + gco2lcl(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TCCL: { + gco2ccl(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TTABLE: { + linktable(gco2t(o), &g->gray); + return; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + return; + } + default: lua_assert(0); return; + } + gray2black(o); + g->GCmemtrav += size; +} + + +/* +** mark metamethods for basic types +*/ +static void markmt (global_State *g) { + int i; + for (i=0; i < LUA_NUMTAGS; i++) + markobject(g, g->mt[i]); +} + + +/* +** mark all objects in list of being-finalized +*/ +static void markbeingfnz (global_State *g) { + GCObject *o; + for (o = g->tobefnz; o != NULL; o = gch(o)->next) { + makewhite(g, o); + reallymarkobject(g, o); + } +} + + +/* +** mark all values stored in marked open upvalues. (See comment in +** 'lstate.h'.) +*/ +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +/* +** mark root set and reset all gray lists, to start a new +** incremental (or full) collection +*/ +static void restartcollection (global_State *g) { + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Traverse functions +** ======================================================= +*/ + +static void traverseweakvalue (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (do not + traverse it just to check) */ + int hasclears = (h->sizearray > 0); + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (hasclears) + linktable(h, &g->weak); /* has to be cleared later */ + else /* no white values */ + linktable(h, &g->grayagain); /* no need to clean */ +} + + +static int traverseephemeron (global_State *g, Table *h) { + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int prop = 0; /* true if table has entry "white-key -> white-value" */ + Node *n, *limit = gnodelast(h); + int i; + /* traverse array part (numeric keys are 'strong') */ + for (i = 0; i < h->sizearray; i++) { + if (valiswhite(&h->array[i])) { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part */ + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + prop = 1; /* must propagate again */ + } + else if (valiswhite(gval(n))) { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + if (prop) + linktable(h, &g->ephemeron); /* have to propagate again */ + else if (hasclears) /* does table have white keys? */ + linktable(h, &g->allweak); /* may have to clean white keys */ + else /* no white keys */ + linktable(h, &g->grayagain); /* no need to clean */ + return marked; +} + + +static void traversestrongtable (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + markvalue(g, gval(n)); /* mark value */ + } + } +} + + +static lu_mem traversetable (global_State *g, Table *h) { + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + markobject(g, h->metatable); + if (mode && ttisstring(mode) && /* is there a weak mode? */ + ((weakkey = strchr(svalue(mode), 'k')), + (weakvalue = strchr(svalue(mode), 'v')), + (weakkey || weakvalue))) { /* is really weak? */ + black2gray(obj2gco(h)); /* keep table gray */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h); + else /* all weak */ + linktable(h, &g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * cast(size_t, sizenode(h)); +} + + +static int traverseproto (global_State *g, Proto *f) { + int i; + if (f->cache && iswhite(obj2gco(f->cache))) + f->cache = NULL; /* allow cache to be collected */ + markobject(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobject(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobject(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobject(g, f->locvars[i].varname); + return sizeof(Proto) + sizeof(Instruction) * f->sizecode + + sizeof(Proto *) * f->sizep + + sizeof(TValue) * f->sizek + + sizeof(int) * f->sizelineinfo + + sizeof(LocVar) * f->sizelocvars + + sizeof(Upvaldesc) * f->sizeupvalues; +} + + +static lu_mem traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return sizeCclosure(cl->nupvalues); +} + +static lu_mem traverseLclosure (global_State *g, LClosure *cl) { + int i; + markobject(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->upvals[i]); + return sizeLclosure(cl->nupvalues); +} + + +static lu_mem traversestack (global_State *g, lua_State *th) { + int n = 0; + StkId o = th->stack; + if (o == NULL) + return 1; /* stack not completely built yet */ + for (; o < th->top; o++) /* mark live elements in the stack */ + markvalue(g, o); + if (g->gcstate == GCSatomic) { /* final traversal? */ + StkId lim = th->stack + th->stacksize; /* real end of stack */ + for (; o < lim; o++) /* clear not-marked stack slice */ + setnilvalue(o); + } + else { /* count call infos to compute size */ + CallInfo *ci; + for (ci = &th->base_ci; ci != th->ci; ci = ci->next) + n++; + } + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * n; +} + + +/* +** traverse one gray object, turning it to black (except for threads, +** which are always gray). +*/ +static void propagatemark (global_State *g) { + lu_mem size; + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (gch(o)->tt) { + case LUA_TTABLE: { + Table *h = gco2t(o); + g->gray = h->gclist; /* remove from 'gray' list */ + size = traversetable(g, h); + break; + } + case LUA_TLCL: { + LClosure *cl = gco2lcl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseLclosure(g, cl); + break; + } + case LUA_TCCL: { + CClosure *cl = gco2ccl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseCclosure(g, cl); + break; + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; /* remove from 'gray' list */ + th->gclist = g->grayagain; + g->grayagain = o; /* insert into 'grayagain' list */ + black2gray(o); + size = traversestack(g, th); + break; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; /* remove from 'gray' list */ + size = traverseproto(g, p); + break; + } + default: lua_assert(0); return; + } + g->GCmemtrav += size; +} + + +static void propagateall (global_State *g) { + while (g->gray) propagatemark(g); +} + + +static void propagatelist (global_State *g, GCObject *l) { + lua_assert(g->gray == NULL); /* no grays left */ + g->gray = l; + propagateall(g); /* traverse all elements from 'l' */ +} + +/* +** retraverse all gray lists. Because tables may be reinserted in other +** lists when traversed, traverse the original lists to avoid traversing +** twice the same table (which is not wrong, but inefficient) +*/ +static void retraversegrays (global_State *g) { + GCObject *weak = g->weak; /* save original lists */ + GCObject *grayagain = g->grayagain; + GCObject *ephemeron = g->ephemeron; + g->weak = g->grayagain = g->ephemeron = NULL; + propagateall(g); /* traverse main gray list */ + propagatelist(g, grayagain); + propagatelist(g, weak); + propagatelist(g, ephemeron); +} + + +static void convergeephemerons (global_State *g) { + int changed; + do { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables will return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) { + next = gco2t(w)->gclist; + if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + } while (changed); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Sweep Functions +** ======================================================= +*/ + + +/* +** clear entries with unmarked keys from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearkeys (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +/* +** clear entries with unmarked values from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearvalues (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) { + TValue *o = &h->array[i]; + if (iscleared(g, o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (gch(o)->tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TLCL: { + luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); + break; + } + case LUA_TCCL: { + luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); + break; + } + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2t(o)); break; + case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; + case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; + case LUA_TSHRSTR: + G(L)->strt.nuse--; + /* go through */ + case LUA_TLNGSTR: { + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + default: lua_assert(0); + } +} + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); + + +/* +** sweep the (open) upvalues of a thread and resize its stack and +** list of call-info structures. +*/ +static void sweepthread (lua_State *L, lua_State *L1) { + if (L1->stack == NULL) return; /* stack not completely built yet */ + sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ + luaE_freeCI(L1); /* free extra CallInfo slots */ + /* should not change the stack during an emergency gc cycle */ + if (G(L)->gckind != KGC_EMERGENCY) + luaD_shrinkstack(L1); +} + + +/* +** sweep at most 'count' elements from a list of GCObjects erasing dead +** objects, where a dead (not alive) object is one marked with the "old" +** (non current) white and not fixed. +** In non-generational mode, change all non-dead objects back to white, +** preparing for next collection cycle. +** In generational mode, keep black objects black, and also mark them as +** old; stop when hitting an old object, as all objects after that +** one will be old too. +** When object is a thread, sweep its list of open upvalues too. +*/ +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + global_State *g = G(L); + int ow = otherwhite(g); + int toclear, toset; /* bits to clear and to set in all live objects */ + int tostop; /* stop sweep when this is true */ + if (isgenerational(g)) { /* generational mode? */ + toclear = ~0; /* clear nothing */ + toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ + tostop = bitmask(OLDBIT); /* do not sweep old generation */ + } + else { /* normal mode */ + toclear = maskcolors; /* clear all color bits + old bit */ + toset = luaC_white(g); /* make object white */ + tostop = 0; /* do not stop */ + } + while (*p != NULL && count-- > 0) { + GCObject *curr = *p; + int marked = gch(curr)->marked; + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ + *p = gch(curr)->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { + if (testbits(marked, tostop)) + return NULL; /* stop sweeping this list */ + if (gch(curr)->tt == LUA_TTHREAD) + sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ + /* update marks */ + gch(curr)->marked = cast_byte((marked & toclear) | toset); + p = &gch(curr)->next; /* go to next element */ + } + } + return (*p == NULL) ? NULL : p; +} + + +/* +** sweep a list until a live object (or end of list) +*/ +static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { + GCObject ** old = p; + int i = 0; + do { + i++; + p = sweeplist(L, p, 1); + } while (p == old); + if (n) *n += i; + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Finalization +** ======================================================= +*/ + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ + int hs = g->strt.size / 2; /* half the size of the string table */ + if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ + luaS_resize(L, hs); /* halve its size */ + luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ + } +} + + +static GCObject *udata2finalize (global_State *g) { + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(isfinalized(o)); + g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ + gch(o)->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ + lua_assert(!isold(o)); /* see MOVE OLD rule */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + return o; +} + + +static void dothecall (lua_State *L, void *ud) { + UNUSED(ud); + luaD_call(L, L->top - 2, 0, 0); +} + + +static void GCTM (lua_State *L, int propagateerrors) { + global_State *g = G(L); + const TValue *tm; + TValue v; + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int running = g->gcrunning; + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + g->gcrunning = 0; /* avoid GC steps */ + setobj2s(L, L->top, tm); /* push finalizer... */ + setobj2s(L, L->top + 1, &v); /* ... and its argument */ + L->top += 2; /* and (next line) call the finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->allowhook = oldah; /* restore hooks */ + g->gcrunning = running; /* restore state */ + if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ + if (status == LUA_ERRRUN) { /* is there an error object? */ + const char *msg = (ttisstring(L->top - 1)) + ? svalue(L->top - 1) + : "no message"; + luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); + status = LUA_ERRGCMM; /* error in __gc metamethod */ + } + luaD_throw(L, status); /* re-throw error */ + } + } +} + + +/* +** move all unreachable objects (or 'all' objects) that need +** finalization from list 'finobj' to list 'tobefnz' (to be finalized) +*/ +static void separatetobefnz (lua_State *L, int all) { + global_State *g = G(L); + GCObject **p = &g->finobj; + GCObject *curr; + GCObject **lastnext = &g->tobefnz; + /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ + while (*lastnext != NULL) + lastnext = &gch(*lastnext)->next; + while ((curr = *p) != NULL) { /* traverse all finalizable objects */ + lua_assert(!isfinalized(curr)); + lua_assert(testbit(gch(curr)->marked, SEPARATED)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &gch(curr)->next; /* don't bother with it */ + else { + l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ + *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ + gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &gch(curr)->next; + } + } +} + + +/* +** if object 'o' has a finalizer, remove it from 'allgc' list (must +** search the list to find it) and link it in 'finobj' list. +*/ +void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { + global_State *g = G(L); + if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ + isfinalized(o) || /* ... or is finalized... */ + gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ + return; /* nothing to be done */ + else { /* move 'o' to 'finobj' list */ + GCObject **p; + GCheader *ho = gch(o); + if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ + lua_assert(issweepphase(g)); + g->sweepgc = sweeptolive(L, g->sweepgc, NULL); + } + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } + *p = ho->next; /* remove 'o' from root list */ + ho->next = g->finobj; /* link it in list 'finobj' */ + g->finobj = o; + l_setbit(ho->marked, SEPARATED); /* mark it as such */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + else + resetoldbit(o); /* see MOVE OLD rule */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** GC control +** ======================================================= +*/ + + +/* +** set a reasonable "time" to wait before starting a new GC cycle; +** cycle will start when memory use hits threshold +*/ +static void setpause (global_State *g, l_mem estimate) { + l_mem debt, threshold; + estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ + threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * g->gcpause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = -cast(l_mem, threshold - gettotalbytes(g)); + luaE_setdebt(g, debt); +} + + +#define sweepphases \ + (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) + + +/* +** enter first sweep phase (strings) and prepare pointers for other +** sweep phases. The calls to 'sweeptolive' make pointers point to an +** object inside the list (instead of to the header), so that the real +** sweep do not need to skip objects created between "now" and the start +** of the real sweep. +** Returns how many objects it swept. +*/ +static int entersweep (lua_State *L) { + global_State *g = G(L); + int n = 0; + g->gcstate = GCSsweepstring; + lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); + /* prepare to sweep strings, finalizable objects, and regular objects */ + g->sweepstrgc = 0; + g->sweepfin = sweeptolive(L, &g->finobj, &n); + g->sweepgc = sweeptolive(L, &g->allgc, &n); + return n; +} + + +/* +** change GC mode +*/ +void luaC_changemode (lua_State *L, int mode) { + global_State *g = G(L); + if (mode == g->gckind) return; /* nothing to change */ + if (mode == KGC_GEN) { /* change to generational mode */ + /* make sure gray lists are consistent */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + g->GCestimate = gettotalbytes(g); + g->gckind = KGC_GEN; + } + else { /* change to incremental mode */ + /* sweep all objects to turn them back to white + (as white has not changed, nothing extra will be collected) */ + g->gckind = KGC_NORMAL; + entersweep(L); + luaC_runtilstate(L, ~sweepphases); + } +} + + +/* +** call all pending finalizers +*/ +static void callallpendingfinalizers (lua_State *L, int propagateerrors) { + global_State *g = G(L); + while (g->tobefnz) { + resetoldbit(g->tobefnz); + GCTM(L, propagateerrors); + } +} + + +void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); + int i; + separatetobefnz(L, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L, 0); + g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ + g->gckind = KGC_NORMAL; + sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ + sweepwholelist(L, &g->allgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); + lua_assert(g->strt.nuse == 0); +} + + +static l_mem atomic (lua_State *L) { + global_State *g = G(L); + l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ + GCObject *origweak, *origall; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark basic metatables */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + propagateall(g); /* propagate changes */ + work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ + /* traverse objects caught by write barrier and by 'remarkupvals' */ + retraversegrays(g); + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* clear values from weak tables, before checking finalizers */ + clearvalues(g, g->weak, NULL); + clearvalues(g, g->allweak, NULL); + origweak = g->weak; origall = g->allweak; + work += g->GCmemtrav; /* stop counting (objects being finalized) */ + separatetobefnz(L, 0); /* separate objects to be finalized */ + markbeingfnz(g); /* mark objects that will be finalized */ + propagateall(g); /* remark, to propagate `preserveness' */ + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ + clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ + /* clear values from resurrected weak tables */ + clearvalues(g, g->weak, origweak); + clearvalues(g, g->allweak, origall); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + work += g->GCmemtrav; /* complete counting */ + return work; /* estimate of memory marked by 'atomic' */ +} + + +static lu_mem singlestep (lua_State *L) { + global_State *g = G(L); + switch (g->gcstate) { + case GCSpause: { + /* start to count memory traversed */ + g->GCmemtrav = g->strt.size * sizeof(GCObject*); + lua_assert(!isgenerational(g)); + restartcollection(g); + g->gcstate = GCSpropagate; + return g->GCmemtrav; + } + case GCSpropagate: { + if (g->gray) { + lu_mem oldtrav = g->GCmemtrav; + propagatemark(g); + return g->GCmemtrav - oldtrav; /* memory traversed in this step */ + } + else { /* no more `gray' objects */ + lu_mem work; + int sw; + g->gcstate = GCSatomic; /* finish mark phase */ + g->GCestimate = g->GCmemtrav; /* save what was counted */; + work = atomic(L); /* add what was traversed by 'atomic' */ + g->GCestimate += work; /* estimate of total memory traversed */ + sw = entersweep(L); + return work + sw * GCSWEEPCOST; + } + } + case GCSsweepstring: { + int i; + for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) + sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); + g->sweepstrgc += i; + if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ + g->gcstate = GCSsweepudata; + return i * GCSWEEPCOST; + } + case GCSsweepudata: { + if (g->sweepfin) { + g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); + return GCSWEEPMAX*GCSWEEPCOST; + } + else { + g->gcstate = GCSsweep; + return 0; + } + } + case GCSsweep: { + if (g->sweepgc) { + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + return GCSWEEPMAX*GCSWEEPCOST; + } + else { + /* sweep main thread */ + GCObject *mt = obj2gco(g->mainthread); + sweeplist(L, &mt, 1); + checkSizes(L); + g->gcstate = GCSpause; /* finish collection */ + return GCSWEEPCOST; + } + } + default: lua_assert(0); return 0; + } +} + + +/* +** advances the garbage collector until it reaches a state allowed +** by 'statemask' +*/ +void luaC_runtilstate (lua_State *L, int statesmask) { + global_State *g = G(L); + while (!testbit(statesmask, g->gcstate)) + singlestep(L); +} + + +static void generationalcollection (lua_State *L) { + global_State *g = G(L); + lua_assert(g->gcstate == GCSpropagate); + if (g->GCestimate == 0) { /* signal for another major collection? */ + luaC_fullgc(L, 0); /* perform a full regular collection */ + g->GCestimate = gettotalbytes(g); /* update control */ + } + else { + lu_mem estimate = g->GCestimate; + luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ + g->gcstate = GCSpropagate; /* skip restart */ + if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) + g->GCestimate = 0; /* signal for a major collection */ + else + g->GCestimate = estimate; /* keep estimate from last major coll. */ + + } + setpause(g, gettotalbytes(g)); + lua_assert(g->gcstate == GCSpropagate); +} + + +static void incstep (lua_State *L) { + global_State *g = G(L); + l_mem debt = g->GCdebt; + int stepmul = g->gcstepmul; + if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */ + /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ + debt = (debt / STEPMULADJ) + 1; + debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; + do { /* always perform at least one single step */ + lu_mem work = singlestep(L); /* do some work */ + debt -= work; + } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g, g->GCestimate); /* pause until next cycle */ + else { + debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ + luaE_setdebt(g, debt); + } +} + + +/* +** performs a basic GC step +*/ +void luaC_forcestep (lua_State *L) { + global_State *g = G(L); + int i; + if (isgenerational(g)) generationalcollection(L); + else incstep(L); + /* run a few finalizers (or all of them at the end of a collect cycle) */ + for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) + GCTM(L, 1); /* call one finalizer */ +} + + +/* +** performs a basic GC step only if collector is running +*/ +void luaC_step (lua_State *L) { + global_State *g = G(L); + if (g->gcrunning) luaC_forcestep(L); + else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ +} + + + +/* +** performs a full GC cycle; if "isemergency", does not call +** finalizers (which could change stack positions) +*/ +void luaC_fullgc (lua_State *L, int isemergency) { + global_State *g = G(L); + int origkind = g->gckind; + lua_assert(origkind != KGC_EMERGENCY); + if (isemergency) /* do not run finalizers during emergency GC */ + g->gckind = KGC_EMERGENCY; + else { + g->gckind = KGC_NORMAL; + callallpendingfinalizers(L, 1); + } + if (keepinvariant(g)) { /* may there be some black objects? */ + /* must sweep all objects to turn them back to white + (as white has not changed, nothing will be collected) */ + entersweep(L); + } + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ + luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ + if (origkind == KGC_GEN) { /* generational mode? */ + /* generational mode must be kept in propagate phase */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + } + g->gckind = origkind; + setpause(g, gettotalbytes(g)); + if (!isemergency) /* do not run finalizers during emergency GC */ + callallpendingfinalizers(L, 1); +} + +/* }====================================================== */ + + diff --git a/src/external/lua-5.2.3/src/lgc.h b/src/external/lua-5.2.3/src/lgc.h new file mode 100644 index 000000000..84bb1cdf9 --- /dev/null +++ b/src/external/lua-5.2.3/src/lgc.h @@ -0,0 +1,157 @@ +/* +** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which +** means the object is not marked; gray, which means the +** object is marked, but its references may be not marked; and +** black, which means that the object and all its references are marked. +** The main invariant of the garbage collector, while marking objects, +** is that a black object can never point to a white one. Moreover, +** any gray object must be in a "gray list" (gray, grayagain, weak, +** allweak, ephemeron) so that it can be visited again before finishing +** the collection cycle. These lists have no meaning when the invariant +** is not being enforced (e.g., sweep phase). +*/ + + + +/* how much to allocate before next GC step */ +#if !defined(GCSTEPSIZE) +/* ~100 small strings */ +#define GCSTEPSIZE (cast_int(100 * sizeof(TString))) +#endif + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpropagate 0 +#define GCSatomic 1 +#define GCSsweepstring 2 +#define GCSsweepudata 3 +#define GCSsweep 4 +#define GCSpause 5 + + +#define issweepphase(g) \ + (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) + +#define isgenerational(g) ((g)->gckind == KGC_GEN) + +/* +** macros to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a non-generational collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. During a generational collection, the +** invariant must be kept all times. +*/ + +#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) + + +/* +** Outside the collector, the state in generational mode is kept in +** 'propagate', so 'keepinvariant' is always true. +*/ +#define keepinvariantout(g) \ + check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ + g->gcstate <= GCSatomic) + + +/* +** some useful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) + + +/* Layout for bit use in `marked' field: */ +#define WHITE0BIT 0 /* object is white (type 0) */ +#define WHITE1BIT 1 /* object is white (type 1) */ +#define BLACKBIT 2 /* object is black */ +#define FINALIZEDBIT 3 /* object has been separated for finalization */ +#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ +#define FIXEDBIT 5 /* object is fixed (should not be collected) */ +#define OLDBIT 6 /* object is old (only in generational mode) */ +/* bit 7 is currently used by tests (luaL_checkmemory) */ + +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) testbits((x)->gch.marked, WHITEBITS) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) + +#define isold(x) testbit((x)->gch.marked, OLDBIT) + +/* MOVE OLD rule: whenever an object is moved to the beginning of + a GC list, its old bit must be cleared */ +#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_condGC(L,c) \ + {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} +#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrier_(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierback_(L,p); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarrierback(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } + +#define luaC_barrierproto(L,p,c) \ + { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } + +LUAI_FUNC void luaC_freeallobjects (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_forcestep (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, + GCObject **list, int offset); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); +LUAI_FUNC void luaC_changemode (lua_State *L, int mode); + +#endif diff --git a/src/external/lua-5.2.3/src/linit.c b/src/external/lua-5.2.3/src/linit.c new file mode 100644 index 000000000..c1a383047 --- /dev/null +++ b/src/external/lua-5.2.3/src/linit.c @@ -0,0 +1,67 @@ +/* +** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $ +** Initialization of libraries for lua.c and other clients +** See Copyright Notice in lua.h +*/ + + +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {"_G", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_BITLIBNAME, luaopen_bit32}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +/* +** these libs are preloaded and must be required before used +*/ +static const luaL_Reg preloadedlibs[] = { + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib; + /* call open functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } + /* add open functions from 'preloadedlibs' into 'package.preload' table */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + for (lib = preloadedlibs; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); + } + lua_pop(L, 1); /* remove _PRELOAD table */ +} + diff --git a/src/external/lua-5.2.3/src/liolib.c b/src/external/lua-5.2.3/src/liolib.c new file mode 100644 index 000000000..2a4ec4aa3 --- /dev/null +++ b/src/external/lua-5.2.3/src/liolib.c @@ -0,0 +1,666 @@ +/* +** $Id: liolib.c,v 2.112.1.1 2013/04/12 18:48:47 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +/* +** This definition must come before the inclusion of 'stdio.h'; it +** should not affect non-POSIX systems +*/ +#if !defined(_FILE_OFFSET_BITS) +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + + +#include +#include +#include +#include + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#if !defined(lua_checkmode) + +/* +** Check whether 'mode' matches '[rwa]%+?b?'. +** Change this macro to accept other modes for 'fopen' besides +** the standard ones. +*/ +#define lua_checkmode(mode) \ + (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ + (*mode != '+' || ++mode) && /* skip if char is '+' */ \ + (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ + (*mode == '\0')) + +#endif + +/* +** {====================================================== +** lua_popen spawns a new process connected to the current +** one through the file streams. +** ======================================================= +*/ + +#if !defined(lua_popen) /* { */ + +#if defined(LUA_USE_POPEN) /* { */ + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, pclose(file)) + +#elif defined(LUA_WIN) /* }{ */ + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, _pclose(file)) + + +#else /* }{ */ + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), -1) + + +#endif /* } */ + +#endif /* } */ + +/* }====================================================== */ + + +/* +** {====================================================== +** lua_fseek: configuration for longer offsets +** ======================================================= +*/ + +#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */ + +#if defined(LUA_USE_POSIX) /* { */ + +#define l_fseek(f,o,w) fseeko(f,o,w) +#define l_ftell(f) ftello(f) +#define l_seeknum off_t + +#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \ + && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ +/* Windows (but not DDK) and Visual C++ 2005 or higher */ + +#define l_fseek(f,o,w) _fseeki64(f,o,w) +#define l_ftell(f) _ftelli64(f) +#define l_seeknum __int64 + +#endif /* } */ + +#endif /* } */ + + +#if !defined(l_fseek) /* default definitions */ +#define l_fseek(f,o,w) fseek(f,o,w) +#define l_ftell(f) ftell(f) +#define l_seeknum long +#endif + +/* }====================================================== */ + + +#define IO_PREFIX "_IO_" +#define IO_INPUT (IO_PREFIX "input") +#define IO_OUTPUT (IO_PREFIX "output") + + +typedef luaL_Stream LStream; + + +#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + +#define isclosed(p) ((p)->closef == NULL) + + +static int io_type (lua_State *L) { + LStream *p; + luaL_checkany(L, 1); + p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); + if (p == NULL) + lua_pushnil(L); /* not a file */ + else if (isclosed(p)) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static int f_tostring (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", p->f); + return 1; +} + + +static FILE *tofile (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + luaL_error(L, "attempt to use a closed file"); + lua_assert(p->f); + return p->f; +} + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static LStream *newprefile (lua_State *L) { + LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); + p->closef = NULL; /* mark file handle as 'closed' */ + luaL_setmetatable(L, LUA_FILEHANDLE); + return p; +} + + +static int aux_close (lua_State *L) { + LStream *p = tolstream(L); + lua_CFunction cf = p->closef; + p->closef = NULL; /* mark stream as closed */ + return (*cf)(L); /* close it */ +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) /* no argument? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); +} + + +static int f_gc (lua_State *L) { + LStream *p = tolstream(L); + if (!isclosed(p) && p->f != NULL) + aux_close(L); /* ignore closed and incompletely open files */ + return 0; +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + LStream *p = tolstream(L); + int res = fclose(p->f); + return luaL_fileresult(L, (res == 0), NULL); +} + + +static LStream *newfile (lua_State *L) { + LStream *p = newprefile(L); + p->f = NULL; + p->closef = &io_fclose; + return p; +} + + +static void opencheck (lua_State *L, const char *fname, const char *mode) { + LStream *p = newfile(L); + p->f = fopen(fname, mode); + if (p->f == NULL) + luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newfile(L); + const char *md = mode; /* to traverse/check mode */ + luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); + p->f = fopen(filename, mode); + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + LStream *p = tolstream(L); + return luaL_execresult(L, lua_pclose(L, p->f)); +} + + +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newprefile(L); + p->f = lua_popen(L, filename, mode); + p->closef = &io_pclose; + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + LStream *p = newfile(L); + p->f = tmpfile(); + return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, const char *findex) { + LStream *p; + lua_getfield(L, LUA_REGISTRYINDEX, findex); + p = (LStream *)lua_touserdata(L, -1); + if (isclosed(p)) + luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX)); + return p->f; +} + + +static int g_iofile (lua_State *L, const char *f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) + opencheck(L, filename, mode); + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_setfield(L, LUA_REGISTRYINDEX, f); + } + /* return current value */ + lua_getfield(L, LUA_REGISTRYINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int toclose) { + int i; + int n = lua_gettop(L) - 1; /* number of arguments to read */ + /* ensure that arguments will fit here and into 'io_readline' stack */ + luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); + lua_pushvalue(L, 1); /* file handle */ + lua_pushinteger(L, n); /* number of arguments to read */ + lua_pushboolean(L, toclose); /* close/not close file when finished */ + for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ + lua_pushcclosure(L, io_readline, 3 + n); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + int toclose; + if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ + if (lua_isnil(L, 1)) { /* no file name? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ + lua_replace(L, 1); /* put it at index 1 */ + tofile(L); /* check that it's a valid file handle */ + toclose = 0; /* do not close it after iteration */ + } + else { /* open a new file */ + const char *filename = luaL_checkstring(L, 1); + opencheck(L, filename, "r"); + lua_replace(L, 1); /* put file at index 1 */ + toclose = 1; /* close it after iteration */ + } + aux_lines(L, toclose); + return 1; +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else { + lua_pushnil(L); /* "result" to be removed */ + return 0; /* read fails */ + } +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f, int chop) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_rawlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +#define MAX_SIZE_T (~(size_t)0) + +static void read_all (lua_State *L, FILE *f) { + size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + char *p = luaL_prepbuffsize(&b, rlen); + size_t nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + if (nr < rlen) break; /* eof? */ + else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ + rlen *= 2; /* double buffer size at each iteration */ + } + luaL_pushresult(&b); /* close buffer */ +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t nr; /* number of chars actually read */ + char *p; + luaL_Buffer b; + luaL_buffinit(L, &b); + p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ + nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ + luaL_addsize(&b, nr); + luaL_pushresult(&b); /* close buffer */ + return (nr > 0); /* true iff read something */ +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f, 1); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f, 1); + break; + case 'L': /* line with end-of-line */ + success = read_line(L, f, 0); + break; + case 'a': /* file */ + read_all(L, f); /* read entire file */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return luaL_fileresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); + int i; + int n = (int)lua_tointeger(L, lua_upvalueindex(2)); + if (isclosed(p)) /* file is already closed? */ + return luaL_error(L, "file is already closed"); + lua_settop(L , 1); + for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ + lua_pushvalue(L, lua_upvalueindex(3 + i)); + n = g_read(L, p->f, 2); /* 'n' is number of results */ + lua_assert(n > 0); /* should return at least a nil */ + if (!lua_isnil(L, -n)) /* read at least one value? */ + return n; /* return them */ + else { /* first result is nil: EOF or error */ + if (n > 1) { /* is there error information? */ + /* 2nd result is error message */ + return luaL_error(L, "%s", lua_tostring(L, -n + 1)); + } + if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - arg; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + if (status) return 1; /* file handle already on stack top */ + else return luaL_fileresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + FILE *f = tofile(L); + lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + return g_write(L, f, 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + lua_Number p3 = luaL_optnumber(L, 3, 0); + l_seeknum offset = (l_seeknum)p3; + luaL_argcheck(L, (lua_Number)offset == p3, 3, + "not an integer in proper range"); + op = l_fseek(f, offset, mode[op]); + if (op) + return luaL_fileresult(L, 0, NULL); /* error */ + else { + lua_pushnumber(L, (lua_Number)l_ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return luaL_fileresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); +} + + +/* +** functions for 'io' library +*/ +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +/* +** methods for file handles +*/ +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", f_gc}, + {"__tostring", f_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ + lua_pop(L, 1); /* pop new metatable */ +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + LStream *p = tolstream(L); + p->closef = &io_noclose; /* keep file opened */ + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +static void createstdfile (lua_State *L, FILE *f, const char *k, + const char *fname) { + LStream *p = newprefile(L); + p->f = f; + p->closef = &io_noclose; + if (k != NULL) { + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ + } + lua_setfield(L, -2, fname); /* add file to module */ +} + + +LUAMOD_API int luaopen_io (lua_State *L) { + luaL_newlib(L, iolib); /* new module */ + createmeta(L); + /* create (and set) default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, NULL, "stderr"); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/llex.c b/src/external/lua-5.2.3/src/llex.c new file mode 100644 index 000000000..c4b820e83 --- /dev/null +++ b/src/external/lua-5.2.3/src/llex.c @@ -0,0 +1,530 @@ +/* +** $Id: llex.c,v 2.63.1.2 2013/08/30 15:49:41 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "lctype.h" +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +static const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", "::", "", + "", "", "" +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static l_noret lexerror (LexState *ls, const char *msg, int token); + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { + size_t newsize; + if (luaZ_sizebuffer(b) >= MAX_SIZET/2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[luaZ_bufflen(b)++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.extra = cast_byte(i+1); /* reserved word */ + } +} + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { /* single-byte symbols? */ + lua_assert(token == cast(unsigned char, token)); + return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : + luaO_pushfstring(ls->L, "char(%d)", token); + } + else { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, LUA_QS, s); + else /* names, strings, and numerals */ + return s; + } +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); + default: + return luaX_token2str(ls, token); + } +} + + +static l_noret lexerror (LexState *ls, const char *msg, int token) { + char buff[LUA_IDSIZE]; + luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +l_noret luaX_syntaxerror (LexState *ls, const char *msg) { + lexerror(ls, msg, ls->t.token); +} + + +/* +** creates a new string and anchors it in function's table so that +** it will not be collected until the end of the function's compilation +** (by that time it should be anchored in function's prototype) +*/ +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TValue *o; /* entry for `str' */ + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ + o = luaH_set(L, ls->fs->h, L->top - 1); + if (ttisnil(o)) { /* not in use yet? (see 'addK') */ + /* boolean value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setbvalue(o, 1); /* t[string] = true */ + luaC_checkGC(L); + } + else { /* string already present */ + ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ + } + L->top--; /* remove string from stack */ + return ts; +} + + +/* +** increment line number and skips newline sequence (any of +** \n, \r, \n\r, or \r\n) +*/ +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) { + ls->decpoint = '.'; + ls->L = L; + ls->current = firstchar; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + ls->envn = luaS_new(L, LUA_ENV); /* create env name */ + luaS_fix(ls->envn); /* never collect this name */ + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (ls->current == '\0' || !strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +/* +** change all characters 'from' in buffer to 'to' +*/ +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +#if !defined(getlocaledecpoint) +#define getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) + +/* +** in case of format error, try to change decimal point separator to +** the one defined in the current locale and check again +*/ +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + char old = ls->decpoint; + ls->decpoint = getlocaledecpoint(); + buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ + if (!buff2d(ls->buff, &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +/* +** this function is quite liberal in what it accepts, as 'luaO_str2d' +** will reject ill-formed numerals. +*/ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ + expo = "Pp"; + for (;;) { + if (check_next(ls, expo)) /* exponent part? */ + check_next(ls, "+-"); /* optional exponent sign */ + if (lisxdigit(ls->current) || ls->current == '.') + save_and_next(ls); + else break; + } + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +/* +** skip a sequence '[=*[' or ']=*]' and return its number of '='s or +** -1 if sequence is malformed +*/ +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ + goto endloop; + } + break; + } + case '\n': case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void escerror (LexState *ls, int *c, int n, const char *msg) { + int i; + luaZ_resetbuffer(ls->buff); /* prepare error message */ + save(ls, '\\'); + for (i = 0; i < n && c[i] != EOZ; i++) + save(ls, c[i]); + lexerror(ls, msg, TK_STRING); +} + + +static int readhexaesc (LexState *ls) { + int c[3], i; /* keep input for error message */ + int r = 0; /* result accumulator */ + c[0] = 'x'; /* for error message */ + for (i = 1; i < 3; i++) { /* read two hexadecimal digits */ + c[i] = next(ls); + if (!lisxdigit(c[i])) + escerror(ls, c, i + 1, "hexadecimal digit expected"); + r = (r << 4) + luaO_hexavalue(c[i]); + } + return r; +} + + +static int readdecesc (LexState *ls) { + int c[3], i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ + c[i] = ls->current; + r = 10*r + c[i] - '0'; + next(ls); + } + if (r > UCHAR_MAX) + escerror(ls, c, i, "decimal escape too large"); + return r; +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); /* keep delimiter (for error messages) */ + while (ls->current != del) { + switch (ls->current) { + case EOZ: + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + case '\r': + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': { /* escape sequences */ + int c; /* final character to be saved */ + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; goto read_save; + case 'b': c = '\b'; goto read_save; + case 'f': c = '\f'; goto read_save; + case 'n': c = '\n'; goto read_save; + case 'r': c = '\r'; goto read_save; + case 't': c = '\t'; goto read_save; + case 'v': c = '\v'; goto read_save; + case 'x': c = readhexaesc(ls); goto read_save; + case '\n': case '\r': + inclinenumber(ls); c = '\n'; goto only_save; + case '\\': case '\"': case '\'': + c = ls->current; goto read_save; + case EOZ: goto no_save; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) { + if (currIsNewline(ls)) inclinenumber(ls); + else next(ls); + } + goto no_save; + } + default: { + if (!lisdigit(ls->current)) + escerror(ls, &ls->current, 1, "invalid escape sequence"); + /* digital escape \ddd */ + c = readdecesc(ls); + goto only_save; + } + } + read_save: next(ls); /* read next character */ + only_save: save(ls, c); /* save 'c' */ + no_save: break; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': case '\r': { /* line breaks */ + inclinenumber(ls); + break; + } + case ' ': case '\f': case '\t': case '\v': { /* spaces */ + next(ls); + break; + } + case '-': { /* '-' or '--' (comment) */ + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { /* long comment? */ + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); /* skip until end of line (or end of file) */ + break; + } + case '[': { /* long string or simply '[' */ + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case ':': { + next(ls); + if (ls->current != ':') return ':'; + else { next(ls); return TK_DBCOLON; } + } + case '"': case '\'': { /* short literal strings */ + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { /* '.', '..', '...', or number */ + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ + } + else if (!lisdigit(ls->current)) return '.'; + /* else go through */ + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + case EOZ: { + return TK_EOS; + } + default: { + if (lislalpha(ls->current)) { /* identifier or reserved word? */ + TString *ts; + do { + save_and_next(ls); + } while (lislalnum(ls->current)); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->tsv.extra - 1 + FIRST_RESERVED; + else { + return TK_NAME; + } + } + else { /* single-char tokens (+ - / ...) */ + int c = ls->current; + next(ls); + return c; + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +int luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; +} + diff --git a/src/external/lua-5.2.3/src/llex.h b/src/external/lua-5.2.3/src/llex.h new file mode 100644 index 000000000..a4acdd302 --- /dev/null +++ b/src/external/lua-5.2.3/src/llex.h @@ -0,0 +1,78 @@ +/* +** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, + TK_NUMBER, TK_NAME, TK_STRING +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +/* state of the lexer plus state of the parser when shared by all + functions */ +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/src/external/lua-5.2.3/src/llimits.h b/src/external/lua-5.2.3/src/llimits.h new file mode 100644 index 000000000..152dd0551 --- /dev/null +++ b/src/external/lua-5.2.3/src/llimits.h @@ -0,0 +1,309 @@ +/* +** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +typedef unsigned LUA_INT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + +#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +#if !defined(LUAI_USER_ALIGNMENT_T) +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } +#endif + +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#if defined(lua_assert) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) { if (!(c)) lua_assert(0); } +#else +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) + +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,e) assert(e) +#else +#define luai_apicheck(L,e) lua_assert(e) +#endif + +#endif + +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) + + +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#define cast(t, exp) ((t)(exp)) + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) + + +/* +** non-return type +*/ +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + + + +/* +** maximum depth for nested C calls and syntactical nested non-terminals +** in a program. (Value must fit in an unsigned short int.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in an unsigned char.) +*/ +#define MAXUPVAL UCHAR_MAX + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#if !defined(MINSTRTABSIZE) +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#if !defined(LUA_MINBUFFER) +#define LUA_MINBUFFER 32 +#endif + + +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#if !defined(luai_threadyield) +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** these macros allow user-specific actions on threads when you defined +** LUAI_EXTRASPACE and need to do something extra when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + +/* +** lua_number2int is a macro to convert lua_Number to int. +** lua_number2integer is a macro to convert lua_Number to lua_Integer. +** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. +** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. +** luai_hashnum is a macro to hash a lua_Number value into an integer. +** The hash must be deterministic and give reasonable values for +** both small and large values (outside the range of integers). +*/ + +#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ +/* trick with Microsoft assembler for X86 */ + +#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} +#define lua_number2integer(i,n) lua_number2int(i, n) +#define lua_number2unsigned(i,n) \ + {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} + + +#elif defined(LUA_IEEE754TRICK) /* }{ */ +/* the next trick should work on any machine using IEEE754 with + a 32-bit int type */ + +union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; + +#if !defined(LUA_IEEEENDIAN) /* { */ +#define LUAI_EXTRAIEEE \ + static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; +#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) +#else +#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN +#define LUAI_EXTRAIEEE /* empty */ +#endif /* } */ + +#define lua_number2int32(i,n,t) \ + { LUAI_EXTRAIEEE \ + volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ + (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } + +#define luai_hashnum(i,n) \ + { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ + (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ + +#define lua_number2int(i,n) lua_number2int32(i, n, int) +#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) + +/* the trick can be expanded to lua_Integer when it is a 32-bit value */ +#if defined(LUA_IEEELL) +#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) +#endif + +#endif /* } */ + + +/* the following definitions always work, but may be slow */ + +#if !defined(lua_number2int) +#define lua_number2int(i,n) ((i)=(int)(n)) +#endif + +#if !defined(lua_number2integer) +#define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) +#endif + +#if !defined(lua_number2unsigned) /* { */ +/* the following definition assures proper modulo behavior */ +#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) +#include +#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) +#define lua_number2unsigned(i,n) \ + ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) +#else +#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) +#endif +#endif /* } */ + + +#if !defined(lua_unsigned2number) +/* on several machines, coercion from unsigned to double is slow, + so it may be worth to avoid */ +#define lua_unsigned2number(u) \ + (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) +#endif + + + +#if defined(ltable_c) && !defined(luai_hashnum) + +#include +#include + +#define luai_hashnum(i,n) { int e; \ + n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ + lua_number2int(i, n); i += e; } + +#endif + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L) condmovestack(L) +#else +#define condchangemem(L) \ + ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) +#endif + +#endif diff --git a/src/external/lua-5.2.3/src/lmathlib.c b/src/external/lua-5.2.3/src/lmathlib.c new file mode 100644 index 000000000..fe9fc5423 --- /dev/null +++ b/src/external/lua-5.2.3/src/lmathlib.c @@ -0,0 +1,279 @@ +/* +** $Id: lmathlib.c,v 1.83.1.1 2013/04/12 18:48:47 roberto Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lmathlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI ((lua_Number)(3.1415926535897932384626433832795)) +#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0)) + + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod (lua_State *L) { + lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf (lua_State *L) { + lua_Number ip; + lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number y = luaL_checknumber(L, 2); + lua_pushnumber(L, l_mathop(pow)(x, y)); + return 1; +} + +static int math_log (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + lua_Number res; + if (lua_isnoneornil(L, 2)) + res = l_mathop(log)(x); + else { + lua_Number base = luaL_checknumber(L, 2); + if (base == (lua_Number)10.0) res = l_mathop(log10)(x); + else res = l_mathop(log)(x)/l_mathop(log)(base); + } + lua_pushnumber(L, res); + return 1; +} + +#if defined(LUA_COMPAT_LOG10) +static int math_log10 (lua_State *L) { + lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); + return 1; +} +#endif + +static int math_exp (lua_State *L) { + lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + int ep = luaL_checkint(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + lua_Number u = luaL_checknumber(L, 1); + luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); + lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */ + break; + } + case 2: { /* lower and upper limits */ + lua_Number l = luaL_checknumber(L, 1); + lua_Number u = luaL_checknumber(L, 2); + luaL_argcheck(L, l <= u, 2, "interval is empty"); + lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkunsigned(L, 1)); + (void)rand(); /* discard first value to avoid undesirable correlations */ + return 0; +} + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, +#if defined(LUA_COMPAT_LOG10) + {"log10", math_log10}, +#endif + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUAMOD_API int luaopen_math (lua_State *L) { + luaL_newlib(L, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/lmem.c b/src/external/lua-5.2.3/src/lmem.c new file mode 100644 index 000000000..ee343e3e0 --- /dev/null +++ b/src/external/lua-5.2.3/src/lmem.c @@ -0,0 +1,99 @@ +/* +** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no +** matter 'x'). +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL); +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *what) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, "too many %s (limit is %d)", what, limit); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +l_noret luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; + global_State *g = G(L); + size_t realosize = (block) ? osize : 0; + lua_assert((realosize == 0) == (block == NULL)); +#if defined(HARDMEMTESTS) + if (nsize > realosize && g->gcrunning) + luaC_fullgc(L, 1); /* force a GC whenever possible */ +#endif + newblock = (*g->frealloc)(g->ud, block, osize, nsize); + if (newblock == NULL && nsize > 0) { + api_check(L, nsize > realosize, + "realloc cannot fail when shrinking a block"); + if (g->gcrunning) { + luaC_fullgc(L, 1); /* try to free some memory... */ + newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ + } + if (newblock == NULL) + luaD_throw(L, LUA_ERRMEM); + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - realosize; + return newblock; +} + diff --git a/src/external/lua-5.2.3/src/lmem.h b/src/external/lua-5.2.3/src/lmem.h new file mode 100644 index 000000000..bd4f4e072 --- /dev/null +++ b/src/external/lua-5.2.3/src/lmem.h @@ -0,0 +1,57 @@ +/* +** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +/* +** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is +** always constant. +** The macro is somewhat complex to avoid warnings: +** +1 avoids warnings of "comparison has constant result"; +** cast to 'void' avoids warnings of "value unused". +*/ +#define luaM_reallocv(L,b,on,n,e) \ + (cast(void, \ + (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e))) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) + +#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + +LUAI_FUNC l_noret luaM_toobig (lua_State *L); + +/* not to be called directly */ +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *what); + +#endif + diff --git a/src/external/lua-5.2.3/src/loadlib.c b/src/external/lua-5.2.3/src/loadlib.c new file mode 100644 index 000000000..bedbea3e9 --- /dev/null +++ b/src/external/lua-5.2.3/src/loadlib.c @@ -0,0 +1,725 @@ +/* +** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Windows, and a stub for other +** systems. +*/ + + +/* +** if needed, includes windows header before everything else +*/ +#if defined(_WIN32) +#include +#endif + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** LUA_PATH and LUA_CPATH are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH) +#define LUA_PATH "LUA_PATH" +#endif + +#if !defined(LUA_CPATH) +#define LUA_CPATH "LUA_CPATH" +#endif + +#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + +#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX +#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +** LUA_IGMARK is a mark to ignore all before it when building the +** luaopen_ function name. +*/ +#if !defined (LUA_PATH_SEP) +#define LUA_PATH_SEP ";" +#endif +#if !defined (LUA_PATH_MARK) +#define LUA_PATH_MARK "?" +#endif +#if !defined (LUA_EXEC_DIR) +#define LUA_EXEC_DIR "!" +#endif +#if !defined (LUA_IGMARK) +#define LUA_IGMARK "-" +#endif + + +/* +** LUA_CSUBSEP is the character that replaces dots in submodule names +** when searching for a C loader. +** LUA_LSUBSEP is the character that replaces dots in submodule names +** when searching for a Lua loader. +*/ +#if !defined(LUA_CSUBSEP) +#define LUA_CSUBSEP LUA_DIRSEP +#endif + +#if !defined(LUA_LSUBSEP) +#define LUA_LSUBSEP LUA_DIRSEP +#endif + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +/* table (in the registry) that keeps handles for all loaded C libraries */ +#define CLIBS "_CLIBS" + +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +#define setprogdir(L) ((void)0) + + +/* +** system-dependent functions +*/ +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path, int seeglb); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); + + + +#if defined(LUA_USE_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path, int seeglb) { + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#undef setprogdir + +/* +** optional flags for LoadLibraryEx +*/ +#if !defined(LUA_LLE_FLAGS) +#define LUA_LLE_FLAGS 0 +#endif + + +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HMODULE)lib); +} + + +static void *ll_load (lua_State *L, const char *path, int seeglb) { + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)(lib); /* not used */ +} + + +static void *ll_load (lua_State *L, const char *path, int seeglb) { + (void)(path); (void)(seeglb); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)(lib); (void)(sym); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + +static void *ll_checkclib (lua_State *L, const char *path) { + void *plib; + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + return plib; +} + + +static void ll_addtoclib (lua_State *L, const char *path, void *plib) { + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ +} + + +/* +** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib +** handles in list CLIBS +*/ +static int gctm (lua_State *L) { + int n = luaL_len(L, 1); + for (; n >= 1; n--) { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + ll_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void *reg = ll_checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) { /* must load library? */ + reg = ll_load(L, path, *sym == '*'); + if (reg == NULL) return ERRLIB; /* unable to load library */ + ll_addtoclib(L, path, reg); + } + if (*sym == '*') { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } + else { + lua_CFunction f = ll_sym(L, reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATH_SEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATH_SEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *searchpath (lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) { + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + if (*sep != '\0') /* non-empty separator? */ + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename = luaL_gsub(L, lua_tostring(L, -1), + LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + luaL_addvalue(&msg); /* concatenate error msg. entry */ + } + luaL_pushresult(&msg); /* create error message */ + return NULL; /* not found */ +} + + +static int ll_searchpath (lua_State *L) { + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) return 1; + else { /* error message is on top of the stack */ + lua_pushnil(L); + lua_insert(L, -2); + return 2; /* return nil + error message */ + } +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname, + const char *dirsep) { + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + return searchpath(L, name, path, ".", dirsep); +} + + +static int checkload (lua_State *L, int stat, const char *filename) { + if (stat) { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module " LUA_QS + " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int searcher_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); +} + + +static int loadfunc (lua_State *L, const char *filename, const char *modname) { + const char *funcname; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) { + int stat; + funcname = lua_pushlstring(L, modname, mark - modname); + funcname = lua_pushfstring(L, LUA_POF"%s", funcname); + stat = ll_loadfunc(L, filename, funcname); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + funcname = lua_pushfstring(L, LUA_POF"%s", modname); + return ll_loadfunc(L, filename, funcname); +} + + +static int searcher_C (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); +} + + +static int searcher_Croot (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* root not found */ + if ((stat = loadfunc(L, filename, name)) != 0) { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else { /* open function not found */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; + } + } + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; +} + + +static int searcher_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static void findloader (lua_State *L, const char *name) { + int i; + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ + if (!lua_istable(L, 3)) + luaL_error(L, LUA_QL("package.searchers") " must be a table"); + /* iterate over available searchers to find a loader */ + for (i = 1; ; i++) { + lua_rawgeti(L, 3, i); /* get a searcher */ + if (lua_isnil(L, -1)) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else + lua_pop(L, 2); /* remove both returns */ + } +} + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); /* _LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_pushstring(L, name); /* pass name as argument to module loader */ + lua_insert(L, -2); /* name is 1st argument (before search data) */ + lua_call(L, 2, 1); /* run loader to load module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_isnil(L, -1)) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ +#if defined(LUA_COMPAT_MODULE) + +/* +** changes the environment variable of calling function +*/ +static void set_env (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); /* copy new environment table to top */ + lua_setupvalue(L, -2, 1); + lua_pop(L, 1); /* remove function */ +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int lastarg = lua_gettop(L); /* last parameter */ + luaL_pushmodule(L, modname, 1); /* get/create module table */ + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + set_env(L); + dooptions(L, lastarg); + return 1; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushglobaltable(L); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + +#endif +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +static void setpath (lua_State *L, const char *fieldname, const char *envname1, + const char *envname2, const char *def) { + const char *path = getenv(envname1); + if (path == NULL) /* no environment variable? */ + path = getenv(envname2); /* try alternative name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, + LUA_PATH_SEP AUXMARK LUA_PATH_SEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, +#if defined(LUA_COMPAT_MODULE) + {"seeall", ll_seeall}, +#endif + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { +#if defined(LUA_COMPAT_MODULE) + {"module", ll_module}, +#endif + {"require", ll_require}, + {NULL, NULL} +}; + + +static void createsearcherstable (lua_State *L) { + static const lua_CFunction searchers[] = + {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; + int i; + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); + /* fill it with pre-defined searchers */ + for (i=0; searchers[i] != NULL; i++) { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i+1); + } +} + + +LUAMOD_API int luaopen_package (lua_State *L) { + /* create table CLIBS to keep track of loaded C libraries */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); + lua_createtable(L, 0, 1); /* metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); + /* create `package' table */ + luaL_newlib(L, pk_funcs); + createsearcherstable(L); +#if defined(LUA_COMPAT_LOADERS) + lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ + lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ +#endif + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ + /* set field 'path' */ + setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); + /* set field 'cpath' */ + setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" + LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_setfield(L, -2, "preload"); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ + return 1; /* return 'package' table */ +} + diff --git a/src/external/lua-5.2.3/src/lobject.c b/src/external/lua-5.2.3/src/lobject.c new file mode 100644 index 000000000..882d994d4 --- /dev/null +++ b/src/external/lua-5.2.3/src/lobject.c @@ -0,0 +1,287 @@ +/* +** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "lctype.h" +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* exponent */ + if (x < 8) return x; + while (x >= 0x10) { + x = (x+1) >> 1; + e++; + } + return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 0x1f; + if (e == 0) return x; + else return ((x & 7) + 8) << (e - 1); +} + + +int luaO_ceillog2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = 0; + x--; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; +} + + +lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { + switch (op) { + case LUA_OPADD: return luai_numadd(NULL, v1, v2); + case LUA_OPSUB: return luai_numsub(NULL, v1, v2); + case LUA_OPMUL: return luai_nummul(NULL, v1, v2); + case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); + case LUA_OPMOD: return luai_nummod(NULL, v1, v2); + case LUA_OPPOW: return luai_numpow(NULL, v1, v2); + case LUA_OPUNM: return luai_numunm(NULL, v1); + default: lua_assert(0); return 0; + } +} + + +int luaO_hexavalue (int c) { + if (lisdigit(c)) return c - '0'; + else return ltolower(c) - 'a' + 10; +} + + +#if !defined(lua_strx2number) + +#include + + +static int isneg (const char **s) { + if (**s == '-') { (*s)++; return 1; } + else if (**s == '+') (*s)++; + return 0; +} + + +static lua_Number readhexa (const char **s, lua_Number r, int *count) { + for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */ + r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s))); + (*count)++; + } + return r; +} + + +/* +** convert an hexadecimal numeric string to a number, following +** C99 specification for 'strtod' +*/ +static lua_Number lua_strx2number (const char *s, char **endptr) { + lua_Number r = 0.0; + int e = 0, i = 0; + int neg = 0; /* 1 if number is negative */ + *endptr = cast(char *, s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check signal */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return 0.0; /* invalid format (no '0x') */ + s += 2; /* skip '0x' */ + r = readhexa(&s, r, &i); /* read integer part */ + if (*s == '.') { + s++; /* skip dot */ + r = readhexa(&s, r, &e); /* read fractional part */ + } + if (i == 0 && e == 0) + return 0.0; /* invalid format (no digit) */ + e *= -4; /* each fractional digit divides value by 2^-4 */ + *endptr = cast(char *, s); /* valid up to here */ + if (*s == 'p' || *s == 'P') { /* exponent part? */ + int exp1 = 0; + int neg1; + s++; /* skip 'p' */ + neg1 = isneg(&s); /* signal */ + if (!lisdigit(cast_uchar(*s))) + goto ret; /* must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + } + *endptr = cast(char *, s); /* valid up to here */ + ret: + if (neg) r = -r; + return l_mathop(ldexp)(r, e); +} + +#endif + + +int luaO_str2d (const char *s, size_t len, lua_Number *result) { + char *endptr; + if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ + return 0; + else if (strpbrk(s, "xX")) /* hexa? */ + *result = lua_strx2number(s, &endptr); + else + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* nothing recognized */ + while (lisspace(cast_uchar(*endptr))) endptr++; + return (endptr == s + len); /* OK if no trailing characters */ +} + + + +static void pushstr (lua_State *L, const char *str, size_t l) { + setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 0; + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + luaD_checkstack(L, 2); /* fmt + item */ + pushstr(L, fmt, e - fmt); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s, strlen(s)); + break; + } + case 'c': { + char buff; + buff = cast(char, va_arg(argp, int)); + pushstr(L, &buff, 1); + break; + } + case 'd': { + setnvalue(L->top++, cast_num(va_arg(argp, int))); + break; + } + case 'f': { + setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + int l = sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff, l); + break; + } + case '%': { + pushstr(L, "%", 1); + break; + } + default: { + luaG_runerror(L, + "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), + *(e + 1)); + } + } + n += 2; + fmt = e+2; + } + luaD_checkstack(L, 1); + pushstr(L, fmt, strlen(fmt)); + if (n > 0) luaV_concat(L, n + 1); + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" + +#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + size_t l = strlen(source); + if (*source == '=') { /* 'literal' source */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } + } + else if (*source == '@') { /* file name */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); + } + } + else { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (l < bufflen && nl == NULL) { /* small one-line source? */ + addstr(out, source, l); /* keep it */ + } + else { + if (nl != NULL) l = nl - source; /* stop at first newline */ + if (l > bufflen) l = bufflen; + addstr(out, source, l); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); + } +} + diff --git a/src/external/lua-5.2.3/src/lobject.h b/src/external/lua-5.2.3/src/lobject.h new file mode 100644 index 000000000..3a630b944 --- /dev/null +++ b/src/external/lua-5.2.3/src/lobject.h @@ -0,0 +1,607 @@ +/* +** $Id: lobject.h,v 2.71.1.1 2013/04/12 18:48:47 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO LUA_NUMTAGS +#define LUA_TUPVAL (LUA_NUMTAGS+1) +#define LUA_TDEADKEY (LUA_NUMTAGS+2) + +/* +** number of all possible tags (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTAGS (LUA_TUPVAL+2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* value) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + +#define VARBITS (3 << 4) + + +/* +** LUA_TFUNCTION variants: +** 0 - Lua function +** 1 - light C function +** 2 - regular C function (closure) +*/ + +/* Variant tags for functions */ +#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ +#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ +#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ + + +/* Variant tags for strings */ +#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ +#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + +/* +** Union of all Lua values +*/ +typedef union Value Value; + + +#define numfield lua_Number n; /* numbers */ + + + +/* +** Tagged Values. This is the basic representation of values in Lua, +** an actual value plus a tag with its type. +*/ + +#define TValuefields Value value_; int tt_ + +typedef struct lua_TValue TValue; + + +/* macro defining a nil value */ +#define NILCONSTANT {NULL}, LUA_TNIL + + +#define val_(o) ((o)->value_) +#define num_(o) (val_(o).n) + + +/* raw type tag of a TValue */ +#define rttype(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(x) ((x) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define ttype(o) (rttype(o) & 0x3F) + +/* type tag of a TValue with no variants (bits 0-3) */ +#define ttypenv(o) (novariant(rttype(o))) + + +/* Macros to test type */ +#define checktag(o,t) (rttype(o) == (t)) +#define checktype(o,t) (ttypenv(o) == (t)) +#define ttisnumber(o) checktag((o), LUA_TNUMBER) +#define ttisnil(o) checktag((o), LUA_TNIL) +#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) +#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) +#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) +#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) +#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) +#define ttislcf(o) checktag((o), LUA_TLCF) +#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) +#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) +#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) + +#define ttisequal(o1,o2) (rttype(o1) == rttype(o2)) + +/* Macros to access values */ +#define nvalue(o) check_exp(ttisnumber(o), num_(o)) +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) +#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) +#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) +#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) +#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) +/* a dead value may get the 'gc' field, but cannot access its contents */ +#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + + +#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) + + +/* Macros for internal tests */ +#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) + +#define checkliveness(g,obj) \ + lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && !isdead(g,gcvalue(obj)))) + + +/* Macros to set values */ +#define settt_(o,t) ((o)->tt_=(t)) + +#define setnvalue(obj,x) \ + { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } + +#define setnilvalue(obj) settt_(obj, LUA_TNIL) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } + +#define setpvalue(obj,x) \ + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } + +#define setbvalue(obj,x) \ + { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } + +#define setgcovalue(L,obj,x) \ + { TValue *io=(obj); GCObject *i_g=(x); \ + val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); } + +#define setsvalue(L,obj,x) \ + { TValue *io=(obj); \ + TString *x_ = (x); \ + val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \ + checkliveness(G(L),io); } + +#define setuvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ + checkliveness(G(L),io); } + +#define setthvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ + checkliveness(G(L),io); } + +#define setclLvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \ + checkliveness(G(L),io); } + +#define setclCvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ + checkliveness(G(L),io); } + +#define sethvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ + checkliveness(G(L),io); } + +#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) + + + +#define setobj(L,obj1,obj2) \ + { const TValue *io2=(obj2); TValue *io1=(obj1); \ + io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ + checkliveness(G(L),io1); } + + +/* +** different types of assignments, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + + +/* check whether a number is valid (useful only for NaN trick) */ +#define luai_checknum(L,o,c) { /* empty */ } + + +/* +** {====================================================== +** NaN Trick +** ======================================================= +*/ +#if defined(LUA_NANTRICK) + +/* +** numbers are represented in the 'd_' field. All other values have the +** value (NNMARK | tag) in 'tt__'. A number with such pattern would be +** a "signaled NaN", which is never generated by regular operations by +** the CPU (nor by 'strtod') +*/ + +/* allows for external implementation for part of the trick */ +#if !defined(NNMARK) /* { */ + + +#if !defined(LUA_IEEEENDIAN) +#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN' +#endif + + +#define NNMARK 0x7FF7A500 +#define NNMASK 0x7FFFFF00 + +#undef TValuefields +#undef NILCONSTANT + +#if (LUA_IEEEENDIAN == 0) /* { */ + +/* little endian */ +#define TValuefields \ + union { struct { Value v__; int tt__; } i; double d__; } u +#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} +/* field-access macros */ +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) + +#else /* }{ */ + +/* big endian */ +#define TValuefields \ + union { struct { int tt__; Value v__; } i; double d__; } u +#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}} +/* field-access macros */ +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) + +#endif /* } */ + +#endif /* } */ + + +/* correspondence with standard representation */ +#undef val_ +#define val_(o) v_(o) +#undef num_ +#define num_(o) d_(o) + + +#undef numfield +#define numfield /* no such field; numbers are the entire struct */ + +/* basic check to distinguish numbers from non-numbers */ +#undef ttisnumber +#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK) + +#define tag2tt(t) (NNMARK | (t)) + +#undef rttype +#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff) + +#undef settt_ +#define settt_(o,t) (tt_(o) = tag2tt(t)) + +#undef setnvalue +#define setnvalue(obj,x) \ + { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } + +#undef setobj +#define setobj(L,obj1,obj2) \ + { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ + o1_->u = o2_->u; \ + checkliveness(G(L),o1_); } + + +/* +** these redefinitions are not mandatory, but these forms are more efficient +*/ + +#undef checktag +#undef checktype +#define checktag(o,t) (tt_(o) == tag2tt(t)) +#define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS)) + +#undef ttisequal +#define ttisequal(o1,o2) \ + (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) + + +#undef luai_checknum +#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } + +#endif +/* }====================================================== */ + + + +/* +** {====================================================== +** types and prototypes +** ======================================================= +*/ + + +union Value { + GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + int b; /* booleans */ + lua_CFunction f; /* light C functions */ + numfield /* numbers */ +}; + + +struct lua_TValue { + TValuefields; +}; + + +typedef TValue *StkId; /* index to stack elements */ + + + + +/* +** Header for string value; string bytes follow the end of this structure +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + unsigned int hash; + size_t len; /* number of characters in string */ + } tsv; +} TString; + + +/* get the actual string (array of bytes) from a TString */ +#define getstr(ts) cast(const char *, (ts) + 1) + +/* get the actual string (array of bytes) from a Lua value */ +#define svalue(o) getstr(rawtsvalue(o)) + + +/* +** Header for userdata; memory area follows the end of this structure +*/ +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; /* number of bytes */ + } uv; +} Udata; + + + +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines (debug information) */ + LocVar *locvars; /* information about local variables (debug information) */ + Upvaldesc *upvalues; /* upvalue information */ + union Closure *cache; /* last created closure with this prototype */ + TString *source; /* used for debug information */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte numparams; /* number of fixed parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* maximum stack used by this function */ +} Proto; + + + +/* +** Lua Upvalues +*/ +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define isLfunction(o) ttisLclosure(o) + +#define getproto(o) (clLvalue(o)->p) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +/* +** (address of) a fixed nil value +*/ +#define luaO_nilobject (&luaO_nilobject_) + + +LUAI_DDEC const TValue luaO_nilobject_; + + +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); +LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); +LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/src/external/lua-5.2.3/src/lopcodes.c b/src/external/lua-5.2.3/src/lopcodes.c new file mode 100644 index 000000000..4190dc762 --- /dev/null +++ b/src/external/lua-5.2.3/src/lopcodes.c @@ -0,0 +1,107 @@ +/* +** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADKX", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETTABUP", + "GETTABLE", + "SETTABUP", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "EXTRAARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ +}; + diff --git a/src/external/lua-5.2.3/src/lopcodes.h b/src/external/lua-5.2.3/src/lopcodes.h new file mode 100644 index 000000000..51f579154 --- /dev/null +++ b/src/external/lua-5.2.3/src/lopcodes.h @@ -0,0 +1,288 @@ +/* +** $Id: lopcodes.h,v 1.142.1.1 2013/04/12 18:48:47 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + 'Ax' : 26 bits ('A', 'B', and 'C' together) + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C +#define POS_Ax POS_A + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + +#if SIZE_Ax < LUAI_BITSINT-1 +#define MAXARG_Ax ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>pos) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<= R(A) + 1 */ +OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ +OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ +OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ + +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) > 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/src/external/lua-5.2.3/src/loslib.c b/src/external/lua-5.2.3/src/loslib.c new file mode 100644 index 000000000..052ba1744 --- /dev/null +++ b/src/external/lua-5.2.3/src/loslib.c @@ -0,0 +1,323 @@ +/* +** $Id: loslib.c,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** list of valid conversion specifiers for the 'strftime' function +*/ +#if !defined(LUA_STRFTIMEOPTIONS) + +#if !defined(LUA_USE_POSIX) +#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } +#else +#define LUA_STRFTIMEOPTIONS \ + { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \ + "", "E", "cCxXyY", \ + "O", "deHImMSuUVwWy" } +#endif + +#endif + + + +/* +** By default, Lua uses tmpnam except when POSIX is available, where it +** uses mkstemp. +*/ +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#elif !defined(lua_tmpnam) + +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } + +#endif + + +/* +** By default, Lua uses gmtime/localtime, except when POSIX is available, +** where it uses gmtime_r/localtime_r +*/ +#if defined(LUA_USE_GMTIME_R) + +#define l_gmtime(t,r) gmtime_r(t,r) +#define l_localtime(t,r) localtime_r(t,r) + +#elif !defined(l_gmtime) + +#define l_gmtime(t,r) ((void)r, gmtime(t)) +#define l_localtime(t,r) ((void)r, localtime(t)) + +#endif + + + +static int os_execute (lua_State *L) { + const char *cmd = luaL_optstring(L, 1, NULL); + int stat = system(cmd); + if (cmd != NULL) + return luaL_execresult(L, stat); + else { + lua_pushboolean(L, stat); /* true if there is a shell */ + return 1; + } +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return luaL_fileresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res, isnum; + lua_getfield(L, -1, key); + res = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static const char *checkoption (lua_State *L, const char *conv, char *buff) { + static const char *const options[] = LUA_STRFTIMEOPTIONS; + unsigned int i; + for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { + if (*conv != '\0' && strchr(options[i], *conv) != NULL) { + buff[1] = *conv; + if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ + buff[2] = '\0'; /* end buffer */ + return conv + 1; + } + else if (*(conv + 1) != '\0' && + strchr(options[i + 1], *(conv + 1)) != NULL) { + buff[2] = *(conv + 1); /* valid two-char conversion specifier */ + buff[3] = '\0'; /* end buffer */ + return conv + 2; + } + } + } + luaL_argerror(L, 1, + lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); + return conv; /* to avoid warnings */ +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm tmr, *stm; + if (*s == '!') { /* UTC? */ + stm = l_gmtime(&t, &tmr); + s++; /* skip `!' */ + } + else + stm = l_localtime(&t, &tmr); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[4]; + luaL_Buffer b; + cc[0] = '%'; + luaL_buffinit(L, &b); + while (*s) { + if (*s != '%') /* no conversion specifier? */ + luaL_addchar(&b, *s++); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + s = checkoption(L, s + 1, cc); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + int status; + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); + else + status = luaL_optint(L, 1, EXIT_SUCCESS); + if (lua_toboolean(L, 2)) + lua_close(L); + if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ + return 0; +} + + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUAMOD_API int luaopen_os (lua_State *L) { + luaL_newlib(L, syslib); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/lparser.c b/src/external/lua-5.2.3/src/lparser.c new file mode 100644 index 000000000..9e1a9ca2c --- /dev/null +++ b/src/external/lua-5.2.3/src/lparser.c @@ -0,0 +1,1638 @@ +/* +** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#include + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +/* maximum number of local variables per function (must be smaller + than 250, due to the bytecode format) */ +#define MAXVARS 200 + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + short firstlabel; /* index of first label in this block */ + short firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isloop; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void statement (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + /* last token from outer function must be EOS */ + lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +/* semantic error */ +static l_noret semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove 'near to' from final message */ + luaX_syntaxerror(ls, msg); +} + + +static l_noret error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +} + + +static l_noret errorlimit (FuncState *fs, int limit, const char *what) { + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); +} + + +static void checklimit (FuncState *fs, int v, int l, const char *what) { + if (v > l) errorlimit(fs, l, what); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "%s expected (to close %s at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname (LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +static void new_localvar (LexState *ls, TString *name) { + FuncState *fs = ls->fs; + Dyndata *dyd = ls->dyd; + int reg = registerlocalvar(ls, name); + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, MAX_INT, "local variables"); + dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); +} + + +static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { + new_localvar(ls, luaX_newstring(ls, name, sz)); +} + +#define new_localvarliteral(ls,v) \ + new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) + + +static LocVar *getlocvar (FuncState *fs, int i) { + int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; + lua_assert(idx < fs->nlocvars); + return &fs->f->locvars[idx]; +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; + } +} + + +static void removevars (FuncState *fs, int tolevel) { + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar)->endpc = fs->pc; +} + + +static int searchupvalue (FuncState *fs, TString *name) { + int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) { + if (luaS_eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ +} + + +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; + f->upvalues[fs->nups].instack = (v->k == VLOCAL); + f->upvalues[fs->nups].idx = cast_byte(v->u.info); + f->upvalues[fs->nups].name = name; + luaC_objbarrier(fs->ls->L, f, name); + return fs->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { + if (luaS_eqstr(n, getlocvar(fs, i)->varname)) + return i; + } + return -1; /* not found */ +} + + +/* + Mark block where variable at given level was defined + (to emit close instructions later). +*/ +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl->nactvar > level) bl = bl->previous; + bl->upval = 1; +} + + +/* + Find variable with given name 'n'. If it is an upvalue, add this + upvalue into all intermediate functions. +*/ +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + return VVOID; /* default is global */ + else { + int v = searchvar(fs, n); /* look up locals at current level */ + if (v >= 0) { /* found? */ + init_exp(var, VLOCAL, v); /* variable is local */ + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ + return VVOID; /* not found; is a global */ + /* else was LOCAL or UPVAL */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + } + init_exp(var, VUPVAL, idx); + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k == VLOCAL || var->k == VUPVAL); + codestring(ls, &key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + lua_State *L = ls->L; + ++L->nCcalls; + checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void closegoto (LexState *ls, int g, Labeldesc *label) { + int i; + FuncState *fs = ls->fs; + Labellist *gl = &ls->dyd->gt; + Labeldesc *gt = &gl->arr[g]; + lua_assert(luaS_eqstr(gt->name, label->name)); + if (gt->nactvar < label->nactvar) { + TString *vname = getlocvar(fs, gt->nactvar)->varname; + const char *msg = luaO_pushfstring(ls->L, + " at line %d jumps into the scope of local " LUA_QS, + getstr(gt->name), gt->line, getstr(vname)); + semerror(ls, msg); + } + luaK_patchlist(fs, gt->pc, label->pc); + /* remove goto from pending list */ + for (i = g; i < gl->n - 1; i++) + gl->arr[i] = gl->arr[i + 1]; + gl->n--; +} + + +/* +** try to close a goto with existing labels; this solves backward jumps +*/ +static int findlabel (LexState *ls, int g) { + int i; + BlockCnt *bl = ls->fs->bl; + Dyndata *dyd = ls->dyd; + Labeldesc *gt = &dyd->gt.arr[g]; + /* check labels in current block for a match */ + for (i = bl->firstlabel; i < dyd->label.n; i++) { + Labeldesc *lb = &dyd->label.arr[i]; + if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ + if (gt->nactvar > lb->nactvar && + (bl->upval || dyd->label.n > bl->firstlabel)) + luaK_patchclose(ls->fs, gt->pc, lb->nactvar); + closegoto(ls, g, lb); /* close it */ + return 1; + } + } + return 0; /* label not found; cannot close goto */ +} + + +static int newlabelentry (LexState *ls, Labellist *l, TString *name, + int line, int pc) { + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].pc = pc; + l->n++; + return n; +} + + +/* +** check whether new label 'lb' matches any pending gotos in current +** block; solves forward jumps +*/ +static void findgotos (LexState *ls, Labeldesc *lb) { + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + while (i < gl->n) { + if (luaS_eqstr(gl->arr[i].name, lb->name)) + closegoto(ls, i, lb); + else + i++; + } +} + + +/* +** "export" pending gotos to outer level, to check them against +** outer labels; if the block being exited has upvalues, and +** the goto exits the scope of any variable (which can be the +** upvalue), close those variables being exited. +*/ +static void movegotosout (FuncState *fs, BlockCnt *bl) { + int i = bl->firstgoto; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block and try to close it + with visible labels */ + while (i < gl->n) { + Labeldesc *gt = &gl->arr[i]; + if (gt->nactvar > bl->nactvar) { + if (bl->upval) + luaK_patchclose(fs, gt->pc, bl->nactvar); + gt->nactvar = bl->nactvar; + } + if (!findlabel(fs->ls, i)) + i++; /* move to next one */ + } +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { + bl->isloop = isloop; + bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +/* +** create a label named "break" to resolve break statements +*/ +static void breaklabel (LexState *ls) { + TString *n = luaS_new(ls->L, "break"); + int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); + findgotos(ls, &ls->dyd->label.arr[l]); +} + +/* +** generates an error for an undefined 'goto'; choose appropriate +** message when label name is a reserved word (which can only be 'break') +*/ +static l_noret undefgoto (LexState *ls, Labeldesc *gt) { + const char *msg = isreserved(gt->name) + ? "<%s> at line %d not inside a loop" + : "no visible label " LUA_QS " for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + semerror(ls, msg); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + if (bl->previous && bl->upval) { + /* create a 'jump to here' to close upvalues */ + int j = luaK_jump(fs); + luaK_patchclose(fs, j, bl->nactvar); + luaK_patchtohere(fs, j); + } + if (bl->isloop) + breaklabel(ls); /* close pending breaks */ + fs->bl = bl->previous; + removevars(fs, bl->nactvar); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + if (bl->previous) /* inner block? */ + movegotosout(fs, bl); /* update pending gotos to outer block */ + else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ +} + + +/* +** adds a new prototype into list of prototypes +*/ +static Proto *addprototype (LexState *ls) { + Proto *clp; + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; +} + + +/* +** codes instruction to create new closure in parent function. +** The OP_CLOSURE instruction must use the last available register, +** so that, if it invokes the GC, the GC knows which registers +** are in use at that time. +*/ +static void codeclosure (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ +} + + +static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { + lua_State *L = ls->L; + Proto *f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = 0; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nups = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->firstlocal = ls->dyd->actvar.n; + fs->bl = NULL; + f = fs->f; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L); + /* anchor table of constants (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + enterblock(fs, bl, 0); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_ret(fs, 0, 0); /* final return */ + leaveblock(fs); + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + /* last token read was anchored in defunct function; must re-anchor it */ + anchor_token(ls); + L->top--; /* pop table of constants */ + luaC_checkGC(L); +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +/* +** check whether current token is in the follow set of a block. +** 'until' closes syntactical blocks, but do not close scope, +** so it handled in separate. +*/ +static int block_follow (LexState *ls, int withuntil) { + switch (ls->t.token) { + case TK_ELSE: case TK_ELSEIF: + case TK_END: case TK_EOS: + return 1; + case TK_UNTIL: return withuntil; + default: return 0; + } +} + + +static void statlist (LexState *ls) { + /* statlist -> { stat [`;'] } */ + while (!block_follow(ls, 1)) { + if (ls->t.token == TK_RETURN) { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } +} + + +static void fieldsel (LexState *ls, expdesc *v) { + /* fieldsel -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyregup(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + /* listfield -> exp */ + expr(ls, &cc->v); + checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void field (LexState *ls, struct ConsControl *cc) { + /* field -> listfield | recfield */ + switch(ls->t.token) { + case TK_NAME: { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': { + recfield(ls, cc); + break; + } + default: { + listfield(ls, cc); + break; + } + } +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> '{' [ field { sep field } [sep] ] '}' + sep -> ',' | ';' */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + field(ls, &cc); + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls)); + nparams++; + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); + f->is_vararg = 1; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int ismethod, int line) { + /* body -> `(' parlist `)' block END */ + FuncState new_fs; + BlockCnt bl; + new_fs.f = addprototype(ls); + new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); + checknext(ls, '('); + if (ismethod) { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + statlist(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); + close_func(ls); +} + + +static int explist (LexState *ls, expdesc *v) { + /* explist -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f, int line) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist ] `)' */ + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + } + } +} + + +static void suffixedexp (LexState *ls, expdesc *v) { + /* suffixedexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + primaryexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* fieldsel */ + fieldsel(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyregup(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v, line); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v, line); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | + constructor | FUNCTION body | suffixedexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + suffixedexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '/': return OPR_DIV; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ + {10, 9}, {5, 4}, /* ^, .. (right associative) */ + {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ + {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ + {2, 2}, {1, 1} /* and, or */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + int line = ls->linenumber; + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v, line); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + int line = ls->linenumber; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2, line); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static void block (LexState *ls) { + /* block -> statlist */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + statlist(ls); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to an upvalue/local variable, the +** upvalue/local variable is begin used in a previous assignment to a +** table. If so, save original upvalue/local value in a safe place and +** use this safe copy in the previous assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { /* check all previous assignments */ + if (lh->v.k == VINDEXED) { /* assigning to a table? */ + /* table is the upvalue/local being assigned now? */ + if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { + conflict = 1; + lh->v.u.ind.vt = VLOCAL; + lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ + } + /* index is the local being assigned? (index cannot be upvalue) */ + if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { + conflict = 1; + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + /* copy upvalue/local value to a temporary (in position 'extra') */ + OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, op, extra, v->u.info, 0); + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + suffixedexp(ls, &nv.v); + if (nv.v.k != VINDEXED) + check_conflict(ls, lh, &nv.v); + checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, + "C levels"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist */ + int nexps; + checknext(ls, '='); + nexps = explist(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void gotostat (LexState *ls, int pc) { + int line = ls->linenumber; + TString *label; + int g; + if (testnext(ls, TK_GOTO)) + label = str_checkname(ls); + else { + luaX_next(ls); /* skip break */ + label = luaS_new(ls->L, "break"); + } + g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); + findlabel(ls, g); /* close it if label already defined */ +} + + +/* check for repeated labels on the same block */ +static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { + int i; + for (i = fs->bl->firstlabel; i < ll->n; i++) { + if (luaS_eqstr(label, ll->arr[i].name)) { + const char *msg = luaO_pushfstring(fs->ls->L, + "label " LUA_QS " already defined on line %d", + getstr(label), ll->arr[i].line); + semerror(fs->ls, msg); + } + } +} + + +/* skip no-op statements */ +static void skipnoopstat (LexState *ls) { + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); +} + + +static void labelstat (LexState *ls, TString *label, int line) { + /* label -> '::' NAME '::' */ + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l; /* index of new label being created */ + checkrepeated(fs, ll, label); /* check for repeated labels */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + /* create new entry for this label */ + l = newlabelentry(ls, ll, label, line, fs->pc); + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + findgotos(ls, &ll->arr[l]); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_jumpto(fs, whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + statlist(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (bl2.upval) /* upvalues? */ + luaK_patchclose(fs, condexit, bl2.nactvar); + leaveblock(fs); /* finish scope */ + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int reg; + expr(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + lua_assert(e.k == VNONRELOC); + reg = e.u.info; + return reg; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + if (isnum) /* numeric for? */ + endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); + else { /* generic for */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); + } + luaK_patchlist(fs, endfor, prep + 1); + luaK_fixline(fs, line); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)"); + new_localvarliteral(ls, "(for limit)"); + new_localvarliteral(ls, "(for step)"); + new_localvar(ls, varname); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 4; /* gen, state, control, plus at least one declared var */ + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for control)"); + /* create declared variables */ + new_localvar(ls, indexname); + while (testnext(ls, ',')) { + new_localvar(ls, str_checkname(ls)); + nvars++; + } + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static void test_then_block (LexState *ls, int *escapelist) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ + luaX_next(ls); /* skip IF or ELSEIF */ + expr(ls, &v); /* read condition */ + checknext(ls, TK_THEN); + if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { + luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + gotostat(ls, v.t); /* handle goto/break */ + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else { /* regular case (not goto/break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* `then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) + block(ls); /* `else' part */ + check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ +} + + +static void localfunc (LexState *ls) { + expdesc b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ + /* debug information will only see the variable after this point! */ + getlocvar(fs, b.u.info)->startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls)); + nvars++; + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {fieldsel} [`:' NAME] */ + int ismethod = 0; + singlevar(ls, v); + while (ls->t.token == '.') + fieldsel(ls, v); + if (ls->t.token == ':') { + ismethod = 1; + fieldsel(ls, v); + } + return ismethod; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int ismethod; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ + v.prev = NULL; + assignment(ls, &v, 1); + } + else { /* stat -> func */ + check_condition(ls, v.v.k == VCALL, "syntax error"); + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN [explist] [';'] */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + if (block_follow(ls, 1) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ +} + + +static void statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); + switch (ls->t.token) { + case ';': { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + break; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + break; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + break; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + break; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + break; + } + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + break; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + break; + } + case TK_DBCOLON: { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; + } + case TK_RETURN: { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ + retstat(ls); + break; + } + case TK_BREAK: /* stat -> breakstat */ + case TK_GOTO: { /* stat -> 'goto' NAME */ + gotostat(ls, luaK_jump(ls->fs)); + break; + } + default: { /* stat -> func | assignment */ + exprstat(ls); + break; + } + } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + leavelevel(ls); +} + +/* }====================================================================== */ + + +/* +** compiles the main function, which is a regular vararg function with an +** upvalue named LUA_ENV +*/ +static void mainfunc (LexState *ls, FuncState *fs) { + BlockCnt bl; + expdesc v; + open_func(ls, fs, &bl); + fs->f->is_vararg = 1; /* main function is always vararg */ + init_exp(&v, VLOCAL, 0); /* create and... */ + newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); +} + + +Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) { + LexState lexstate; + FuncState funcstate; + Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ + /* anchor closure (to avoid being collected) */ + setclLvalue(L, L->top, cl); + incr_top(L); + funcstate.f = cl->l.p = luaF_newproto(L); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + return cl; /* it's on the stack too */ +} + diff --git a/src/external/lua-5.2.3/src/lparser.h b/src/external/lua-5.2.3/src/lparser.h new file mode 100644 index 000000000..0346e3c41 --- /dev/null +++ b/src/external/lua-5.2.3/src/lparser.h @@ -0,0 +1,119 @@ +/* +** $Id: lparser.h,v 1.70.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VNONRELOC, /* info = result register */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in 'upvalues' */ + VINDEXED, /* t = table register/upvalue; idx = index R/K */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) +#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) + +typedef struct expdesc { + expkind k; + union { + struct { /* for indexed variables (VINDEXED) */ + short idx; /* index (R/K) */ + lu_byte t; /* table (register or upvalue) */ + lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ + } ind; + int info; /* for generic use */ + lua_Number nval; /* for VKNUM */ + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +/* description of active local variable */ +typedef struct Vardesc { + short idx; /* variable index in stack */ +} Vardesc; + + +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* local level where it appears in current block */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int jpc; /* list of pending jumps to `pc' */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + short nlocvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ +} FuncState; + + +LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); + + +#endif diff --git a/src/external/lua-5.2.3/src/lstate.c b/src/external/lua-5.2.3/src/lstate.c new file mode 100644 index 000000000..c7f2672be --- /dev/null +++ b/src/external/lua-5.2.3/src/lstate.c @@ -0,0 +1,323 @@ +/* +** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#if !defined(LUAI_GCPAUSE) +#define LUAI_GCPAUSE 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMAJOR) +#define LUAI_GCMAJOR 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMUL) +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +#endif + + +#define MEMERRMSG "not enough memory" + + +/* +** a macro to help the creation of a unique random seed when a state is +** created; the seed is used to randomize hashes. +*/ +#if !defined(luai_makeseed) +#include +#define luai_makeseed() cast(unsigned int, time(NULL)) +#endif + + + +/* +** thread state + extra space +*/ +typedef struct LX { +#if defined(LUAI_EXTRASPACE) + char buff[LUAI_EXTRASPACE]; +#endif + lua_State l; +} LX; + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + LX l; + global_State g; +} LG; + + + +#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) + + +/* +** Compute an initial seed as random as possible. In ANSI, rely on +** Address Space Layout Randomization (if present) to increase +** randomness.. +*/ +#define addbuff(b,p,e) \ + { size_t t = cast(size_t, e); \ + memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } + +static unsigned int makeseed (lua_State *L) { + char buff[4 * sizeof(size_t)]; + unsigned int h = luai_makeseed(); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, luaO_nilobject); /* global variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); +} + + +/* +** set GCdebt to a new value keeping the value (totalbytes + GCdebt) +** invariant +*/ +void luaE_setdebt (global_State *g, l_mem debt) { + g->totalbytes -= (debt - g->GCdebt); + g->GCdebt = debt; +} + + +CallInfo *luaE_extendCI (lua_State *L) { + CallInfo *ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + return ci; +} + + +void luaE_freeCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) { + next = ci->next; + luaM_free(L, ci); + } +} + + +static void stack_init (lua_State *L1, lua_State *L) { + int i; CallInfo *ci; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); + L1->stacksize = BASIC_STACK_SIZE; + for (i = 0; i < BASIC_STACK_SIZE; i++) + setnilvalue(L1->stack + i); /* erase new stack */ + L1->top = L1->stack; + L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = 0; + ci->func = L1->top; + setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ + ci->top = L1->top + LUA_MINSTACK; + L1->ci = ci; +} + + +static void freestack (lua_State *L) { + if (L->stack == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + luaE_freeCI(L); + luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ +} + + +/* +** Create registry table and its predefined values +*/ +static void init_registry (lua_State *L, global_State *g) { + TValue mt; + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, &mt, L); + luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); + /* registry[LUA_RIDX_GLOBALS] = table of globals */ + sethvalue(L, &mt, luaH_new(L)); + luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); +} + + +/* +** open parts of the state that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + init_registry(L, g); + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaS_fix(g->memerrmsg); /* it should never be collected */ + g->gcrunning = 1; /* allow gc */ + g->version = lua_version(NULL); + luai_userstateopen(L); +} + + +/* +** preinitialize a state with consistent values without allocating +** any memory (to avoid errors) +*/ +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->ci = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->nCcalls = 0; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->nny = 1; + L->status = LUA_OK; + L->errfunc = 0; +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeallobjects(L); /* collect all objects */ + if (g->version) /* closing a fully built state? */ + luai_userstateclose(L); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); + luaZ_freebuffer(L, &g->buff); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; + setthvalue(L, L->top, L1); + api_incr_top(L); + preinit_state(L1, G(L)); + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + LX *l = fromstate(L1); + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); + if (l == NULL) return NULL; + L = &l->l.l; + g = &l->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + g->gckind = KGC_NORMAL; + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->seed = makeseed(L); + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->gcrunning = 0; /* no GC while building state */ + g->GCestimate = 0; + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->version = NULL; + g->gcstate = GCSpause; + g->allgc = NULL; + g->finobj = NULL; + g->tobefnz = NULL; + g->sweepgc = g->sweepfin = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; + g->totalbytes = sizeof(LG); + g->GCdebt = 0; + g->gcpause = LUAI_GCPAUSE; + g->gcmajorinc = LUAI_GCMAJOR; + g->gcstepmul = LUAI_GCMUL; + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + return L; +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + close_state(L); +} + + diff --git a/src/external/lua-5.2.3/src/lstate.h b/src/external/lua-5.2.3/src/lstate.h new file mode 100644 index 000000000..daffd9aac --- /dev/null +++ b/src/external/lua-5.2.3/src/lstate.h @@ -0,0 +1,228 @@ +/* +** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* + +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed. +** +** Lua keeps most objects linked in list g->allgc. The link uses field +** 'next' of the CommonHeader. +** +** Strings are kept in several lists headed by the array g->strt.hash. +** +** Open upvalues are not subject to independent garbage collection. They +** are collected together with their respective threads. Lua keeps a +** double-linked list with all open upvalues (g->uvhead) so that it can +** mark objects referred by them. (They are always gray, so they must +** be remarked in the atomic step. Usually their contents would be marked +** when traversing the respective threads, but the thread may already be +** dead, while the upvalue is still accessible through closures.) +** +** Objects with finalizers are kept in the list g->finobj. +** +** The list g->tobefnz links all objects being finalized. + +*/ + + +struct lua_longjmp; /* defined in ldo.c */ + + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + +/* kinds of Garbage Collection */ +#define KGC_NORMAL 0 +#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ +#define KGC_GEN 2 /* generational collection */ + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** information about a call +*/ +typedef struct CallInfo { + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + short nresults; /* expected number of results from this function */ + lu_byte callstatus; + ptrdiff_t extra; + union { + struct { /* only for Lua functions */ + StkId base; /* base for this function */ + const Instruction *savedpc; + } l; + struct { /* only for C functions */ + int ctx; /* context info. in case of yields */ + lua_CFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lu_byte old_allowhook; + lu_byte status; + } c; + } u; +} CallInfo; + + +/* +** Bits in CallInfo status +*/ +#define CIST_LUA (1<<0) /* call is running a Lua function */ +#define CIST_HOOKED (1<<1) /* call is running a debug hook */ +#define CIST_REENTRY (1<<2) /* call is running on same invocation of + luaV_execute of previous call */ +#define CIST_YIELDED (1<<3) /* call reentered after suspension */ +#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ +#define CIST_STAT (1<<5) /* call has an error status (pcall) */ +#define CIST_TAIL (1<<6) /* call was tail called */ +#define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ + + +#define isLua(ci) ((ci)->callstatus & CIST_LUA) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCmemtrav; /* memory traversed by the GC */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcrunning; /* true if GC is running */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *allgc; /* list of all collectable objects */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject **sweepgc; /* current position of sweep in list 'allgc' */ + GCObject **sweepfin; /* current position of sweep in list 'finobj' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + UpVal uvhead; /* head of double-linked list of all open upvalues */ + Mbuffer buff; /* temporary buffer for string concatenation */ + int gcpause; /* size of pause between successive GCs */ + int gcmajorinc; /* pause between major collections (only in gen. mode) */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + const lua_Number *version; /* pointer to version number */ + TString *memerrmsg; /* memory-error message */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *oldpc; /* last pc traced */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + int stacksize; + unsigned short nny; /* number of non-yieldable calls in stack */ + unsigned short nCcalls; /* number of nested C calls */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; /* common header */ + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +#define gch(o) (&(o)->gch) + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) \ + check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) +#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) +#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +/* actual number of total bytes allocated */ +#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_freeCI (lua_State *L); + + +#endif + diff --git a/src/external/lua-5.2.3/src/lstring.c b/src/external/lua-5.2.3/src/lstring.c new file mode 100644 index 000000000..af96c89c1 --- /dev/null +++ b/src/external/lua-5.2.3/src/lstring.c @@ -0,0 +1,185 @@ +/* +** $Id: lstring.c,v 2.26.1.1 2013/04/12 18:48:47 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + +/* +** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to +** compute its hash +*/ +#if !defined(LUAI_HASHLIMIT) +#define LUAI_HASHLIMIT 5 +#endif + + +/* +** equality for long strings +*/ +int luaS_eqlngstr (TString *a, TString *b) { + size_t len = a->tsv.len; + lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->tsv.len) && /* equal length and ... */ + (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ +} + + +/* +** equality for strings +*/ +int luaS_eqstr (TString *a, TString *b) { + return (a->tsv.tt == b->tsv.tt) && + (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); +} + + +unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { + unsigned int h = seed ^ cast(unsigned int, l); + size_t l1; + size_t step = (l >> LUAI_HASHLIMIT) + 1; + for (l1 = l; l1 >= step; l1 -= step) + h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); + return h; +} + + +/* +** resizes the string table +*/ +void luaS_resize (lua_State *L, int newsize) { + int i; + stringtable *tb = &G(L)->strt; + /* cannot resize while GC is traversing strings */ + luaC_runtilstate(L, ~bitmask(GCSsweepstring)); + if (newsize > tb->size) { + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; + } + /* rehash */ + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + tb->hash[i] = NULL; + while (p) { /* for each node in the list */ + GCObject *next = gch(p)->next; /* save next */ + unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ + gch(p)->next = tb->hash[h]; /* chain it */ + tb->hash[h] = p; + resetoldbit(p); /* see MOVE OLD rule */ + p = next; + } + } + if (newsize < tb->size) { + /* shrinking slice must be empty */ + lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + } + tb->size = newsize; +} + + +/* +** creates a new string object +*/ +static TString *createstrobj (lua_State *L, const char *str, size_t l, + int tag, unsigned int h, GCObject **list) { + TString *ts; + size_t totalsize; /* total size of TString object */ + totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); + ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.extra = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + return ts; +} + + +/* +** creates a new short string, inserting it into string table +*/ +static TString *newshrstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + GCObject **list; /* (pointer to) list where it will be inserted */ + stringtable *tb = &G(L)->strt; + TString *s; + if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + list = &tb->hash[lmod(h, tb->size)]; + s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); + tb->nuse++; + return s; +} + + +/* +** checks whether short string exists and reuses it or creates a new one +*/ +static TString *internshrstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + global_State *g = G(L); + unsigned int h = luaS_hash(str, l, g->seed); + for (o = g->strt.hash[lmod(h, g->strt.size)]; + o != NULL; + o = gch(o)->next) { + TString *ts = rawgco2ts(o); + if (h == ts->tsv.hash && + l == ts->tsv.len && + (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { + if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ + changewhite(o); /* resurrect it */ + return ts; + } + } + return newshrstr(L, str, l, h); /* not found; create a new string */ +} + + +/* +** new string (with explicit length) +*/ +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else { + if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); + } +} + + +/* +** new zero-terminated string +*/ +TString *luaS_new (lua_State *L, const char *str) { + return luaS_newlstr(L, str, strlen(str)); +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + return u; +} + diff --git a/src/external/lua-5.2.3/src/lstring.h b/src/external/lua-5.2.3/src/lstring.h new file mode 100644 index 000000000..260e7f169 --- /dev/null +++ b/src/external/lua-5.2.3/src/lstring.h @@ -0,0 +1,46 @@ +/* +** $Id: lstring.h,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC int luaS_eqstr (TString *a, TString *b); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); + + +#endif diff --git a/src/external/lua-5.2.3/src/lstrlib.c b/src/external/lua-5.2.3/src/lstrlib.c new file mode 100644 index 000000000..9261fd220 --- /dev/null +++ b/src/external/lua-5.2.3/src/lstrlib.c @@ -0,0 +1,1019 @@ +/* +** $Id: lstrlib.c,v 1.178.1.1 2013/04/12 18:48:47 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** maximum number of captures that a pattern can do during +** pattern-matching. This limit is arbitrary. +*/ +#if !defined(LUA_MAXCAPTURES) +#define LUA_MAXCAPTURES 32 +#endif + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (lua_Integer)l); + return 1; +} + + +/* translate a relative string position: negative means back from end */ +static size_t posrelat (ptrdiff_t pos, size_t len) { + if (pos >= 0) return (size_t)pos; + else if (0u - (size_t)pos > len) return 0; + else return len - ((size_t)-pos) + 1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t start = posrelat(luaL_checkinteger(L, 2), l); + size_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > l) end = l; + if (start <= end) + lua_pushlstring(L, s + start - 1, end - start + 1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l, i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i=0; i> 1) + +static int str_rep (lua_State *L) { + size_t l, lsep; + const char *s = luaL_checklstring(L, 1, &l); + int n = luaL_checkint(L, 2); + const char *sep = luaL_optlstring(L, 3, "", &lsep); + if (n <= 0) lua_pushliteral(L, ""); + else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ + return luaL_error(L, "resulting string too large"); + else { + size_t totallen = n * l + (n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); p += l; + if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */ + memcpy(p, sep, lsep * sizeof(char)); p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + size_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi < 1) posi = 1; + if (pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* (size_t -> int) overflow? */ + return luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'g' : res = isgraph(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; /* deprecated option */ + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (MatchState *ms, const char *s, const char *p, + const char *ep) { + if (s >= ms->src_end) + return 0; + else { + int c = uchar(*s); + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } + } +} + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (p >= ms->p_end - 1) + luaL_error(ms->L, "malformed pattern " + "(missing arguments to " LUA_QL("%%b") ")"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while (singlematch(ms, s + i, p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + if (ms->matchdepth-- == 0) + luaL_error(ms->L, "pattern too complex"); + init: /* using goto's to optimize tail recursion */ + if (p != ms->p_end) { /* end of pattern? */ + switch (*p) { + case '(': { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': { + if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) { + p += 4; goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) { + p = ep; goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) { + p += 2; goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: goto dflt; + } + break; + } + default: dflt: { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) { + if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ + p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ + } + else { /* matched once */ + switch (*ep) { /* handle optional suffix */ + case '?': { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else { + p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* go through */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ + } + } + break; + } + } + } + ms->matchdepth++; + return s; +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +/* check whether pattern has no special characters */ +static int nospecials (const char *p, size_t l) { + size_t upto = 0; + do { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); + if (init < 1) init = 1; + else if (init > ls + 1) { /* start after string's end? */ + lua_pushnil(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { + /* do a plain search */ + const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); + if (s2) { + lua_pushinteger(L, s2 - s + 1); + lua_pushinteger(L, s2 - s + lp); + return 2; + } + } + else { + MatchState ms; + const char *s1 = s + init - 1; + int anchor = (*p == '^'); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = s; + ms.src_end = s + ls; + ms.p_end = p + lp; + do { + const char *res; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1 - s + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls, lp; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); + const char *src; + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = s; + ms.src_end = s+ls; + ms.p_end = p + lp; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) { + if (news[i] != L_ESC) + luaL_error(ms->L, "invalid use of " LUA_QL("%c") + " in replacement string", L_ESC); + luaL_addchar(b, news[i]); + } + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e, int tr) { + lua_State *L = ms->L; + switch (tr) { + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); + return; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl, lp; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checklstring(L, 2, &lp); + int tr = lua_type(L, 3); + size_t max_s = luaL_optinteger(L, 4, srcl+1); + int anchor = (*p == '^'); + size_t n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + if (anchor) { + p++; lp--; /* skip anchor character */ + } + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = src; + ms.src_end = src+srcl; + ms.p_end = p + lp; + while (n < max_s) { + const char *e; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e, tr); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** STRING FORMAT +** ======================================================= +*/ + +/* +** LUA_INTFRMLEN is the length modifier for integer conversions in +** 'string.format'; LUA_INTFRM_T is the integer type corresponding to +** the previous length +*/ +#if !defined(LUA_INTFRMLEN) /* { */ +#if defined(LUA_USE_LONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif +#endif /* } */ + + +/* +** LUA_FLTFRMLEN is the length modifier for float conversions in +** 'string.format'; LUA_FLTFRM_T is the float type corresponding to +** the previous length +*/ +#if !defined(LUA_FLTFRMLEN) + +#define LUA_FLTFRMLEN "" +#define LUA_FLTFRM_T double + +#endif + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + if (*s == '"' || *s == '\\' || *s == '\n') { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + } + else if (*s == '\0' || iscntrl(uchar(*s))) { + char buff[10]; + if (!isdigit(uchar(*(s+1)))) + sprintf(buff, "\\%d", (int)uchar(*s)); + else + sprintf(buff, "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +/* +** add length modifier into formats +*/ +static void addlenmod (char *form, const char *lenmod) { + size_t l = strlen(form); + size_t lm = strlen(lenmod); + char spec = form[l - 1]; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; +} + + +static int str_format (lua_State *L) { + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ + int nb = 0; /* number of bytes in added item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + nb = sprintf(buff, form, luaL_checkint(L, arg)); + break; + } + case 'd': case 'i': { + lua_Number n = luaL_checknumber(L, arg); + LUA_INTFRM_T ni = (LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = sprintf(buff, form, ni); + break; + } + case 'o': case 'u': case 'x': case 'X': { + lua_Number n = luaL_checknumber(L, arg); + unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a non-negative number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = sprintf(buff, form, ni); + break; + } + case 'e': case 'E': case 'f': +#if defined(LUA_USE_AFORMAT) + case 'a': case 'A': +#endif + case 'g': case 'G': { + addlenmod(form, LUA_FLTFRMLEN); + nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'q': { + addquoted(L, &b, arg); + break; + } + case 's': { + size_t l; + const char *s = luaL_tolstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + luaL_addvalue(&b); + break; + } + else { + nb = sprintf(buff, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addsize(&b, nb); + } + } + luaL_pushresult(&b); + return 1; +} + +/* }====================================================== */ + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* table to be metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUAMOD_API int luaopen_string (lua_State *L) { + luaL_newlib(L, strlib); + createmetatable(L); + return 1; +} + diff --git a/src/external/lua-5.2.3/src/ltable.c b/src/external/lua-5.2.3/src/ltable.c new file mode 100644 index 000000000..5d76f97ec --- /dev/null +++ b/src/external/lua-5.2.3/src/ltable.c @@ -0,0 +1,588 @@ +/* +** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lvm.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT >= 32 +#define MAXBITS 30 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +#define dummynode (&dummynode_) + +#define isdummy(n) ((n) == dummynode) + +static const Node dummynode_ = { + {NILCONSTANT}, /* value */ + {{NILCONSTANT, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + int i; + luai_hashnum(i, n); + if (i < 0) { + if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */ + i = 0; /* handle INT_MIN */ + i = -i; /* must be a positive value */ + } + return hashmod(t, i); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TLNGSTR: { + TString *s = rawtsvalue(key); + if (s->tsv.extra == 0) { /* no hash? */ + s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); + s->tsv.extra = 1; /* now it has its hash */ + } + return hashstr(t, rawtsvalue(key)); + } + case LUA_TSHRSTR: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + case LUA_TLCF: + return hashpointer(t, fvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signaled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + for (;;) { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaV_rawequalobj(gkey(n), key) || + (ttisdeadkey(gkey(n)) && iscollectable(key) && + deadvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + if (n == NULL) + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + } + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, gkey(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[luaO_ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(gkey(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = luaO_ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + luaH_setint(L, t, i + 1, &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) { + /* doesn't need barrier/invalidate cache, as entry was + already present in the table */ + setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); + } + } + if (!isdummy(nold)) + luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = isdummy(t->node) ? 0 : sizenode(t); + luaH_resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + luaH_resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L) { + Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; + t->metatable = NULL; + t->flags = cast_byte(~0); + t->array = NULL; + t->sizearray = 0; + setnodevector(L, t, 0); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (!isdummy(t->node)) + luaM_freearray(L, t->node, cast(size_t, sizenode(t))); + luaM_freearray(L, t->array, t->sizearray); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree > t->node) { + t->lastfree--; + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp; + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) + luaG_runerror(L, "table index is NaN"); + mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + /* whatever called 'newkey' take care of TM cache and GC barrier */ + return luaH_set(L, t, key); /* insert key into grown table */ + } + lua_assert(!isdummy(n)); + othern = mainposition(t, gkey(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + setobj2t(L, gkey(mp), key); + luaC_barrierback(L, obj2gco(t), key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getint (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for short strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + lua_assert(key->tsv.tt == LUA_TSHRSTR); + do { /* check whether `key' is somewhere in the chain */ + if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNIL: return luaO_nilobject; + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) /* index is int? */ + return luaH_getint(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaV_rawequalobj(gkey(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +/* +** beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else return luaH_newkey(L, t, key); +} + + +void luaH_setint (lua_State *L, Table *t, int key, TValue *value) { + const TValue *p = luaH_getint(t, key); + TValue *cell; + if (p != luaO_nilobject) + cell = cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + cell = luaH_newkey(L, t, &k); + } + setobj2t(L, cell, value); +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getint(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getint(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getint(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (isdummy(t->node)) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return isdummy(n); } + +#endif diff --git a/src/external/lua-5.2.3/src/ltable.h b/src/external/lua-5.2.3/src/ltable.h new file mode 100644 index 000000000..d69449b2b --- /dev/null +++ b/src/external/lua-5.2.3/src/ltable.h @@ -0,0 +1,45 @@ +/* +** $Id: ltable.h,v 2.16.1.2 2013/08/30 15:49:41 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.tvk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define invalidateTMcache(t) ((t)->flags = 0) + +/* returns the key, given the value of a table entry */ +#define keyfromval(v) \ + (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) + + +LUAI_FUNC const TValue *luaH_getint (Table *t, int key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif diff --git a/src/external/lua-5.2.3/src/ltablib.c b/src/external/lua-5.2.3/src/ltablib.c new file mode 100644 index 000000000..6001224e3 --- /dev/null +++ b/src/external/lua-5.2.3/src/ltablib.c @@ -0,0 +1,283 @@ +/* +** $Id: ltablib.c,v 1.65.1.1 2013/04/12 18:48:47 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) + + + +#if defined(LUA_COMPAT_MAXN) +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} +#endif + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int size = aux_getn(L, 1); + int pos = luaL_optint(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ; pos < size; pos++) { + lua_rawgeti(L, 1, pos+1); + lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ + } + lua_pushnil(L); + lua_rawseti(L, 1, pos); /* t[pos] = nil */ + return 1; +} + + +static void addfield (lua_State *L, luaL_Buffer *b, int i) { + lua_rawgeti(L, 1, i); + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid value (%s) at index %d in table for " + LUA_QL("concat"), luaL_typename(L, -1), i); + luaL_addvalue(b); +} + + +static int tconcat (lua_State *L) { + luaL_Buffer b; + size_t lsep; + int i, last; + const char *sep = luaL_optlstring(L, 2, "", &lsep); + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 3, 1); + last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); + luaL_buffinit(L, &b); + for (; i < last; i++) { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); + } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); + luaL_pushresult(&b); + return 1; +} + + +/* +** {====================================================== +** Pack/unpack +** ======================================================= +*/ + +static int pack (lua_State *L) { + int n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_pushinteger(L, n); + lua_setfield(L, -2, "n"); /* t.n = number of elements */ + if (n > 0) { /* at least one element? */ + int i; + lua_pushvalue(L, 1); + lua_rawseti(L, -2, 1); /* insert first element */ + lua_replace(L, 1); /* move table into index 1 */ + for (i = n; i >= 2; i--) /* assign other elements */ + lua_rawseti(L, 1, i); + } + return 1; /* return table */ +} + + +static int unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Quicksort +** (based on `Algorithms in MODULA-3', Robert Sedgewick; +** Addison-Wesley, 1993.) +** ======================================================= +*/ + + +static void set2 (lua_State *L, int i, int j) { + lua_rawseti(L, 1, i); + lua_rawseti(L, 1, j); +} + +static int sort_comp (lua_State *L, int a, int b) { + if (!lua_isnil(L, 2)) { /* function? */ + int res; + lua_pushvalue(L, 2); + lua_pushvalue(L, a-1); /* -1 to compensate function */ + lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ + lua_call(L, 2, 1); + res = lua_toboolean(L, -1); + lua_pop(L, 1); + return res; + } + else /* a < b? */ + return lua_compare(L, a, b, LUA_OPLT); +} + +static void auxsort (lua_State *L, int l, int u) { + while (l < u) { /* for tail recursion */ + int i, j; + /* sort elements a[l], a[(l+u)/2] and a[u] */ + lua_rawgeti(L, 1, l); + lua_rawgeti(L, 1, u); + if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ + set2(L, l, u); /* swap a[l] - a[u] */ + else + lua_pop(L, 2); + if (u-l == 1) break; /* only 2 elements */ + i = (l+u)/2; + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 1, l); + if (sort_comp(L, -2, -1)) /* a[i]= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>=u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j<=l) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + if (j + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +static const char udatatypename[] = "userdata"; + +LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { + "no value", + "nil", "boolean", udatatypename, "number", + "string", "table", "function", udatatypename, "thread", + "proto", "upval" /* these last two cases are used for tests only */ +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__len", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttypenv(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + diff --git a/src/external/lua-5.2.3/src/ltm.h b/src/external/lua-5.2.3/src/ltm.h new file mode 100644 index 000000000..7f89c841f --- /dev/null +++ b/src/external/lua-5.2.3/src/ltm.h @@ -0,0 +1,57 @@ +/* +** $Id: ltm.h,v 2.11.1.1 2013/04/12 18:48:47 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +#define ttypename(x) luaT_typenames_[(x) + 1] +#define objtypename(x) ttypename(ttypenv(x)) + +LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif diff --git a/src/external/lua-5.2.3/src/lua.c b/src/external/lua-5.2.3/src/lua.c new file mode 100644 index 000000000..4345e554e --- /dev/null +++ b/src/external/lua-5.2.3/src/lua.c @@ -0,0 +1,497 @@ +/* +** $Id: lua.c,v 1.206.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#if !defined(LUA_PROMPT) +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " +#endif + +#if !defined(LUA_PROGNAME) +#define LUA_PROGNAME "lua" +#endif + +#if !defined(LUA_MAXINPUT) +#define LUA_MAXINPUT 512 +#endif + +#if !defined(LUA_INIT) +#define LUA_INIT "LUA_INIT" +#endif + +#define LUA_INITVERSION \ + LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + + +/* +** lua_stdin_is_tty detects whether the standard input is a 'tty' (that +** is, whether we're running lua interactively). +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +** lua_readline defines how to show a prompt and then read a line from +** the standard input. +** lua_saveline defines how to "save" a read line in a "history". +** lua_freeline defines how to free a line read by lua_readline. +*/ +#if defined(LUA_USE_READLINE) + +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) + +#elif !defined(lua_readline) + +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } + +#endif + + + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + + + +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} + + +static void print_usage (const char *badoption) { + luai_writestringerror("%s: ", progname); + if (badoption[1] == 'e' || badoption[1] == 'l') + luai_writestringerror("'%s' needs argument\n", badoption); + else + luai_writestringerror("unrecognized option '%s'\n", badoption); + luai_writestringerror( + "usage: %s [options] [script [args]]\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -l name require library " LUA_QL("name") "\n" + " -v show version information\n" + " -E ignore environment variables\n" + " -- stop handling options\n" + " - stop handling options and execute stdin\n" + , + progname); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) luai_writestringerror("%s: ", pname); + luai_writestringerror("%s\n", msg); +} + + +static int report (lua_State *L, int status) { + if (status != LUA_OK && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + /* force a complete garbage collection in case of errors */ + lua_gc(L, LUA_GCCOLLECT, 0); + } + return status; +} + + +/* the next function is called unprotected, so it must avoid errors */ +static void finalreport (lua_State *L, int status) { + if (status != LUA_OK) { + const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) + : NULL; + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } +} + + +static int traceback (lua_State *L) { + const char *msg = lua_tostring(L, 1); + if (msg) + luaL_traceback(L, L, msg, 1); + else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */ + if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ + lua_pushliteral(L, "(no error message)"); + } + return 1; +} + + +static int docall (lua_State *L, int narg, int nres) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + globalL = L; /* to be available to 'laction' */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, nres, base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + return status; +} + + +static void print_version (void) { + luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); + luai_writeline(); +} + + +static int getargs (lua_State *L, char **argv, int n) { + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i=0; i < argc; i++) { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; +} + + +static int dofile (lua_State *L, const char *name) { + int status = luaL_loadfile(L, name); + if (status == LUA_OK) status = docall(L, 0, 0); + return report(L, status); +} + + +static int dostring (lua_State *L, const char *s, const char *name) { + int status = luaL_loadbuffer(L, s, strlen(s), name); + if (status == LUA_OK) status = docall(L, 0, 0); + return report(L, status); +} + + +static int dolibrary (lua_State *L, const char *name) { + int status; + lua_getglobal(L, "require"); + lua_pushstring(L, name); + status = docall(L, 1, 1); /* call 'require(name)' */ + if (status == LUA_OK) + lua_setglobal(L, name); /* global[name] = require return */ + return report(L, status); +} + + +static const char *get_prompt (lua_State *L, int firstline) { + const char *p; + lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + return p; +} + +/* mark in error messages for incomplete statements */ +#define EOFMARK "" +#define marklen (sizeof(EOFMARK)/sizeof(char) - 1) + +static int incomplete (lua_State *L, int status) { + if (status == LUA_ERRSYNTAX) { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ +} + + +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + int readstatus = lua_readline(L, b, prmt); + lua_pop(L, 1); /* remove result from 'get_prompt' */ + if (readstatus == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + +static int loadline (lua_State *L) { + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) { /* repeat until gets a complete line */ + size_t l; + const char *line = lua_tolstring(L, 1, &l); + status = luaL_loadbuffer(L, line, l, "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void dotty (lua_State *L) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) { + if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); + report(L, status); + if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ + luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + luai_writeline(); + progname = oldprogname; +} + + +static int handle_script (lua_State *L, char **argv, int n) { + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg+1)); + if (status == LUA_OK) + status = docall(L, narg, LUA_MULTRET); + else + lua_pop(L, narg); + return report(L, status); +} + + +/* check that argument has no extra characters at the end */ +#define noextrachars(x) {if ((x)[2] != '\0') return -1;} + + +/* indices of various argument indicators in array args */ +#define has_i 0 /* -i */ +#define has_v 1 /* -v */ +#define has_e 2 /* -e */ +#define has_E 3 /* -E */ + +#define num_has 4 /* number of 'has_*' */ + + +static int collectargs (char **argv, int *args) { + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) { /* option */ + case '-': + noextrachars(argv[i]); + return (argv[i+1] != NULL ? i+1 : 0); + case '\0': + return i; + case 'E': + args[has_E] = 1; + break; + case 'i': + noextrachars(argv[i]); + args[has_i] = 1; /* go through */ + case 'v': + noextrachars(argv[i]); + args[has_v] = 1; + break; + case 'e': + args[has_e] = 1; /* go through */ + case 'l': /* both options need an argument */ + if (argv[i][2] == '\0') { /* no concatenated argument? */ + i++; /* try next 'argv' */ + if (argv[i] == NULL || argv[i][0] == '-') + return -(i - 1); /* no next argument or it is another option */ + } + break; + default: /* invalid option; return its index... */ + return -i; /* ...as a negative value */ + } + } + return 0; +} + + +static int runargs (lua_State *L, char **argv, int n) { + int i; + for (i = 1; i < n; i++) { + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) { /* option */ + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != LUA_OK) + return 0; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename) != LUA_OK) + return 0; /* stop if file fails */ + break; + } + default: break; + } + } + return 1; +} + + +static int handle_luainit (lua_State *L) { + const char *name = "=" LUA_INITVERSION; + const char *init = getenv(name + 1); + if (init == NULL) { + name = "=" LUA_INIT; + init = getenv(name + 1); /* try alternative name */ + } + if (init == NULL) return LUA_OK; + else if (init[0] == '@') + return dofile(L, init+1); + else + return dostring(L, init, name); +} + + +static int pmain (lua_State *L) { + int argc = (int)lua_tointeger(L, 1); + char **argv = (char **)lua_touserdata(L, 2); + int script; + int args[num_has]; + args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0; + if (argv[0] && argv[0][0]) progname = argv[0]; + script = collectargs(argv, args); + if (script < 0) { /* invalid arg? */ + print_usage(argv[-script]); + return 0; + } + if (args[has_v]) print_version(); + if (args[has_E]) { /* option '-E'? */ + lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + } + /* open standard libraries */ + luaL_checkversion(L); + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + if (!args[has_E] && handle_luainit(L) != LUA_OK) + return 0; /* error running LUA_INIT */ + /* execute arguments -e and -l */ + if (!runargs(L, argv, (script > 0) ? script : argc)) return 0; + /* execute main script (if there is one) */ + if (script && handle_script(L, argv, script) != LUA_OK) return 0; + if (args[has_i]) /* -i option? */ + dotty(L); + else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */ + if (lua_stdin_is_tty()) { + print_version(); + dotty(L); + } + else dofile(L, NULL); /* executes stdin as a file */ + } + lua_pushboolean(L, 1); /* signal no errors */ + return 1; +} + + +int main (int argc, char **argv) { + int status, result; + lua_State *L = luaL_newstate(); /* create state */ + if (L == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + /* call 'pmain' in protected mode */ + lua_pushcfunction(L, &pmain); + lua_pushinteger(L, argc); /* 1st argument */ + lua_pushlightuserdata(L, argv); /* 2nd argument */ + status = lua_pcall(L, 2, 1, 0); + result = lua_toboolean(L, -1); /* get result */ + finalreport(L, status); + lua_close(L); + return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; +} + diff --git a/src/external/lua-5.2.3/src/lua.h b/src/external/lua-5.2.3/src/lua.h new file mode 100644 index 000000000..149a2c37b --- /dev/null +++ b/src/external/lua-5.2.3/src/lua.h @@ -0,0 +1,444 @@ +/* +** $Id: lua.h,v 1.285.1.2 2013/11/11 12:09:16 roberto Exp $ +** Lua - A Scripting Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "2" +#define LUA_VERSION_NUM 502 +#define LUA_VERSION_RELEASE "3" + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" + + +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) + + +/* thread status */ +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRGCMM 5 +#define LUA_ERRERR 6 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTAGS 9 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* +** RCS ident string +*/ +extern const char lua_ident[]; + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +LUA_API const lua_Number *(lua_version) (lua_State *L); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_absindex) (lua_State *L, int idx); +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_rawlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPDIV 3 +#define LUA_OPMOD 4 +#define LUA_OPPOW 5 +#define LUA_OPUNM 6 + +LUA_API void (lua_arith) (lua_State *L, int op); + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n); +LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_getglobal) (lua_State *L, const char *var); +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getuservalue) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_setglobal) (lua_State *L, const char *var); +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API void (lua_setuservalue) (lua_State *L, int idx); + + +/* +** 'load' and 'call' functions (load and run Lua code) +*/ +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_getctx) (lua_State *L, int *ctx); + +LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k); +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, + const char *mode); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx, + lua_CFunction k); +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCSETMAJORINC 8 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); +LUA_API void (lua_len) (lua_State *L, int idx); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) +#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_pushglobaltable(L) \ + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILCALL 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debugger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); +LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); + +LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); +LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, + int fidx2, int n2); + +LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook (lua_gethook) (lua_State *L); +LUA_API int (lua_gethookmask) (lua_State *L); +LUA_API int (lua_gethookcount) (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2013 Lua.org, PUC-Rio. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/src/external/lua-5.2.3/src/lua.hpp b/src/external/lua-5.2.3/src/lua.hpp new file mode 100644 index 000000000..ec417f594 --- /dev/null +++ b/src/external/lua-5.2.3/src/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/src/external/lua-5.2.3/src/luac.c b/src/external/lua-5.2.3/src/luac.c new file mode 100644 index 000000000..7409706ec --- /dev/null +++ b/src/external/lua-5.2.3/src/luac.c @@ -0,0 +1,432 @@ +/* +** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +static void PrintFunction(const Proto* f, int full); +#define luaU_print PrintFunction + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames]\n" + "Available options are:\n" + " -l list (use -l -l for full listing)\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n" + " - stop handling options and process stdin\n" + ,progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i)) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + Proto* f; + int i=n; + if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1)); + f=toproto(L,-1); + for (i=0; ip[i]=toproto(L,i-n-1); + if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; + } + f->sizelineinfo=0; + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +static int pmain(lua_State* L) +{ + int argc=(int)lua_tointeger(L,1); + char** argv=(char**)lua_touserdata(L,2); + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=luaL_newstate(); + if (L==NULL) fatal("cannot create state: not enough memory"); + lua_pushcfunction(L,&pmain); + lua_pushinteger(L,argc); + lua_pushlightuserdata(L,argv); + if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} + +/* +** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" + +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + printf("%c",'"'); + for (i=0; ik[i]; + switch (ttypenv(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") +#define MYK(x) (-1-(x)) + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); + break; + case iABx: + printf("%d",a); + if (getBMode(o)==OpArgK) printf(" %d",MYK(bx)); + if (getBMode(o)==OpArgU) printf(" %d",bx); + break; + case iAsBx: + printf("%d %d",a,sbx); + break; + case iAx: + printf("%d",MYK(ax)); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s",UPVALNAME(b)); + break; + case OP_GETTABUP: + printf("\t; %s",UPVALNAME(b)); + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABUP: + printf("\t; %s",UPVALNAME(a)); + if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + case OP_TFORLOOP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); + break; + case OP_EXTRAARG: + printf("\t; "); PrintConstant(f,ax); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) ((x==1)?"":"s") +#define S(x) (int)(x),SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=f->source ? getstr(f->source) : "=?"; + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->sizeupvalues)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintDebug(const Proto* f) +{ + int i,n; + n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } + n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + for (i=0; iupvalues[i].instack,f->upvalues[i].idx); + } +} + +static void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) PrintDebug(f); + for (i=0; ip[i],full); +} diff --git a/src/external/lua-5.2.3/src/luaconf.h b/src/external/lua-5.2.3/src/luaconf.h new file mode 100644 index 000000000..2928bbd63 --- /dev/null +++ b/src/external/lua-5.2.3/src/luaconf.h @@ -0,0 +1,551 @@ +/* +** $Id: luaconf.h,v 1.176.1.1 2013/04/12 18:48:47 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_WIN /* enable goodies for regular Windows platforms */ +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#endif + + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* does not need -ldl */ +#define LUA_USE_READLINE /* needs an extra library: -lreadline */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionality listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#define LUA_USE_GMTIME_R +#endif + + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" + +#else /* }{ */ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" +#define LUA_ROOT PREFIX +#define LUA_LDIR LUA_ROOT "/lua/native/" +#define LUA_CDIR LUA_ROOT "/lua/compiled/" +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_ENV is the name of the variable that holds the current +@@ environment, used to access global names. +** CHANGE it if you do not like this name. +*/ +#define LUA_ENV "_ENV" + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API +#define LUAMOD_API LUALIB_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables +@* that are not to be exported to outside modules (LUAI_DDEF for +@* definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DDEC LUAI_FUNC +#define LUAI_DDEF /* empty */ + +#else /* }{ */ +#define LUAI_FUNC extern +#define LUAI_DDEC extern +#define LUAI_DDEF /* empty */ +#endif /* } */ + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ luai_writestring/luai_writeline define how 'print' prints its results. +** They are only used in libraries and the stand-alone program. (The #if +** avoids including 'stdio.h' everywhere.) +*/ +#if defined(LUA_LIB) || defined(lua_c) +#include +#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) +#endif + +/* +@@ luai_writestringerror defines how to print error messages. +** (A format string with one argument is enough for Lua...) +*/ +#define luai_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) + + +/* +@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, +** strings that are internalized. (Cannot be smaller than reserved words +** or tags for metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#define LUAI_MAXSHORTLEN 40 + + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_ALL controls all compatibility options. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_ALL) /* { */ + +/* +@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. +** You can replace it with 'table.unpack'. +*/ +#define LUA_COMPAT_UNPACK + +/* +@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. +** You can replace it with 'package.searchers'. +*/ +#define LUA_COMPAT_LOADERS + +/* +@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. +** You can call your C function directly (with light C functions). +*/ +#define lua_cpcall(L,f,u) \ + (lua_pushcfunction(L, (f)), \ + lua_pushlightuserdata(L,(u)), \ + lua_pcall(L,1,0,0)) + + +/* +@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. +** You can rewrite 'log10(x)' as 'log(x, 10)'. +*/ +#define LUA_COMPAT_LOG10 + +/* +@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base +** library. You can rewrite 'loadstring(s)' as 'load(s)'. +*/ +#define LUA_COMPAT_LOADSTRING + +/* +@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. +*/ +#define LUA_COMPAT_MAXN + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +/* +@@ LUA_COMPAT_MODULE controls compatibility with previous +** module functions 'module' (Lua) and 'luaL_register' (C). +*/ +#define LUA_COMPAT_MODULE + +#endif /* } */ + +/* }================================================================== */ + + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 /* { */ +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L /* }{ */ +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else /* }{ */ +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif /* } */ + + +/* +@@ LUA_INT32 is an signed integer with exactly 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. Probably you do not need to change +** this. +*/ +#if LUAI_BITSINT >= 32 /* { */ +#define LUA_INT32 int +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else /* }{ */ +/* 16-bit ints */ +#define LUA_INT32 long +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif /* } */ + + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua to consume unlimited stack +** space (and to reserve some numbers for pseudo-indices). +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + +/* reserve some space for error handling */ +#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) + + + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +** CHANGE it if it uses too much C-stack space. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ + + +/* +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations +*/ +#define l_mathop(x) (x) + + +/* +@@ lua_str2number converts a decimal numeric string to a number. +@@ lua_strx2number converts an hexadecimal numeric string to a number. +** In C99, 'strtod' does both conversions. C89, however, has no function +** to convert floating hexadecimal strings to numbers. For these +** systems, you can leave 'lua_strx2number' undefined and Lua will +** provide its own implementation. +*/ +#define lua_str2number(s,p) strtod((s), (p)) + +#if defined(LUA_USE_STRTODHEX) +#define lua_strx2number(s,p) strtod((s), (p)) +#endif + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ + +/* the following operations need the math library */ +#if defined(lobject_c) || defined(lvm_c) +#include +#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) +#define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) +#endif + +/* these are quite standard operations */ +#if defined(LUA_CORE) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numdiv(L,a,b) ((a)/(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(L,a,b) ((a)<(b)) +#define luai_numle(L,a,b) ((a)<=(b)) +#define luai_numisnan(L,a) (!luai_numeq((a), (a))) +#endif + + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + +/* +@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. +** It must have at least 32 bits. +*/ +#define LUA_UNSIGNED unsigned LUA_INT32 + + + +/* +** Some tricks with doubles +*/ + +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ +/* +** The next definitions activate some tricks to speed up the +** conversion from doubles to integer types, mainly to LUA_UNSIGNED. +** +@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a +** DirectX idiosyncrasy. +** +@@ LUA_IEEE754TRICK uses a trick that should work on any machine +** using IEEE754 with a 32-bit integer type. +** +@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be +** defined when LUA_INTEGER is a 32-bit integer. +** +@@ LUA_IEEEENDIAN is the endianness of doubles in your machine +** (0 for little endian, 1 for big endian); if not defined, Lua will +** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK). +** +@@ LUA_NANTRICK controls the use of a trick to pack all types into +** a single double value, using NaN values to represent non-number +** values. The trick only works on 32-bit machines (ints and pointers +** are 32-bit values) with numbers represented as IEEE 754-2008 doubles +** with conventional endianess (12345678 or 87654321), in CPUs that do +** not produce signaling NaN values (all NaNs are quiet). +*/ + +/* Microsoft compiler on a Pentium (32 bit) ? */ +#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ + +#define LUA_MSASMTRICK +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + + +/* pentium 32 bits? */ +#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEELL +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + +/* pentium 64 bits? */ +#elif defined(__x86_64) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 0 + +#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 1 + +#else /* }{ */ + +/* assume IEEE754 and a 32-bit integer type */ +#define LUA_IEEE754TRICK + +#endif /* } */ + +#endif /* } */ + +/* }================================================================== */ + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/src/external/lua-5.2.3/src/lualib.h b/src/external/lua-5.2.3/src/lualib.h new file mode 100644 index 000000000..da82005c9 --- /dev/null +++ b/src/external/lua-5.2.3/src/lualib.h @@ -0,0 +1,55 @@ +/* +** $Id: lualib.h,v 1.43.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + + +LUAMOD_API int (luaopen_base) (lua_State *L); + +#define LUA_COLIBNAME "coroutine" +LUAMOD_API int (luaopen_coroutine) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUAMOD_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUAMOD_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUAMOD_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_BITLIBNAME "bit32" +LUAMOD_API int (luaopen_bit32) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUAMOD_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUAMOD_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUAMOD_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#if !defined(lua_assert) +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/src/external/lua-5.2.3/src/lundump.c b/src/external/lua-5.2.3/src/lundump.c new file mode 100644 index 000000000..4163cb5d3 --- /dev/null +++ b/src/external/lua-5.2.3/src/lundump.c @@ -0,0 +1,258 @@ +/* +** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +static l_noret error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +#if !defined(luai_verifycode) +#define luai_verifycode(L,b,f) /* empty */ +#endif + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + if (x<0) error(S,"corrupted"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size*sizeof(char)); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static void LoadFunction(LoadState* S, Proto* f); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: lua_assert(0); + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=luaF_newproto(S->L); + LoadFunction(S,f->p[i]); + } +} + +static void LoadUpvalues(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,Upvaldesc); + f->sizeupvalues=n; + for (i=0; iupvalues[i].name=NULL; + for (i=0; iupvalues[i].instack=LoadByte(S); + f->upvalues[i].idx=LoadByte(S); + } +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + f->source=LoadString(S); + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + for (i=0; iupvalues[i].name=LoadString(S); +} + +static void LoadFunction(LoadState* S, Proto* f) +{ + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadUpvalues(S,f); + LoadDebug(S,f); +} + +/* the code below must be consistent with the code in luaU_header */ +#define N0 LUAC_HEADERSIZE +#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) +#define N2 N1+2 +#define N3 N2+6 + +static void LoadHeader(LoadState* S) +{ + lu_byte h[LUAC_HEADERSIZE]; + lu_byte s[LUAC_HEADERSIZE]; + luaU_header(h); + memcpy(s,h,sizeof(char)); /* first char already read */ + LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); + if (memcmp(h,s,N0)==0) return; + if (memcmp(h,s,N1)!=0) error(S,"not a"); + if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); + if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); +} + +/* +** load precompiled chunk +*/ +Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + Closure* cl; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + cl=luaF_newLclosure(L,1); + setclLvalue(L,L->top,cl); incr_top(L); + cl->l.p=luaF_newproto(L); + LoadFunction(&S,cl->l.p); + if (cl->l.p->sizeupvalues != 1) + { + Proto* p=cl->l.p; + cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); + cl->l.p=p; + setclLvalue(L,L->top-1,cl); + } + luai_verifycode(L,buff,cl->l.p); + return cl; +} + +#define MYINT(s) (s[0]-'0') +#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) +#define FORMAT 0 /* this is the official format */ + +/* +* make header for precompiled chunks +* if you change the code below be sure to update LoadHeader and FORMAT above +* and LUAC_HEADERSIZE in lundump.h +*/ +void luaU_header (lu_byte* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); + h+=sizeof(LUA_SIGNATURE)-sizeof(char); + *h++=cast_byte(VERSION); + *h++=cast_byte(FORMAT); + *h++=cast_byte(*(char*)&x); /* endianness */ + *h++=cast_byte(sizeof(int)); + *h++=cast_byte(sizeof(size_t)); + *h++=cast_byte(sizeof(Instruction)); + *h++=cast_byte(sizeof(lua_Number)); + *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ + memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); +} diff --git a/src/external/lua-5.2.3/src/lundump.h b/src/external/lua-5.2.3/src/lundump.h new file mode 100644 index 000000000..5255db259 --- /dev/null +++ b/src/external/lua-5.2.3/src/lundump.h @@ -0,0 +1,28 @@ +/* +** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (lu_byte* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +/* data to catch conversion errors */ +#define LUAC_TAIL "\x19\x93\r\n\x1a\n" + +/* size in bytes of header of binary files */ +#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) + +#endif diff --git a/src/external/lua-5.2.3/src/lvm.c b/src/external/lua-5.2.3/src/lvm.c new file mode 100644 index 000000000..141b9fd19 --- /dev/null +++ b/src/external/lua-5.2.3/src/lvm.c @@ -0,0 +1,867 @@ +/* +** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + int l = lua_number2str(s, n); + setsvalue2s(L, obj, luaS_newlstr(L, s, l)); + return 1; + } +} + + +static void traceexec (lua_State *L) { + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; + int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); + if (counthook) + resethookcount(L); /* reset count */ + if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return; /* do not call hook again (VM yielded, so it did not move) */ + } + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(ci)->p; + int npc = pcRel(ci->u.l.savedpc, p); + int newline = getfuncline(p, npc); + if (npc == 0 || /* call linehook when enter a new function, */ + ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ + newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ + luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ + } + L->oldpc = ci->u.l.savedpc; + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + ci->func = L->top - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } +} + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, TValue *p3, int hasres) { + ptrdiff_t result = savestack(L, p3); + setobj2s(L, L->top++, f); /* push function */ + setobj2s(L, L->top++, p1); /* 1st argument */ + setobj2s(L, L->top++, p2); /* 2nd argument */ + if (!hasres) /* no result? 'p3' is third argument */ + setobj2s(L, L->top++, p3); /* 3rd argument */ + /* metamethod may yield only when called from Lua code */ + luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); + if (hasres) { /* if has result, move it to its place */ + p3 = restorestack(L, result); + setobjs2s(L, p3, --L->top); + } +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is not nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val, 1); + return; + } + t = tm; /* else repeat with 'tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = cast(TValue *, luaH_get(h, key)); + /* if previous value is not nil, there must be a previous entry + in the table; moreover, a metamethod has no relevance */ + if (!ttisnil(oldval) || + /* previous value is nil; must check the metamethod */ + ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && + /* no metamethod; is there a previous entry in the table? */ + (oldval != luaO_nilobject || + /* no previous entry; must create one. (The next test is + always true; we only need the assignment.) */ + (oldval = luaH_newkey(L, h, key), 1)))) { + /* no metamethod and (now) there is an entry with given key */ + setobj2t(L, oldval, val); /* assign new value to that entry */ + invalidateTMcache(h); + luaC_barrierback(L, obj2gco(h), val); + return; + } + /* else will try the metamethod */ + } + else /* not a table; check metamethod */ + if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + /* there is a metamethod */ + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val, 0); + return; + } + t = tm; /* else repeat with 'tm' */ + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTM(L, tm, p1, p2, res, 1); + return 1; +} + + +static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + if (!call_binTM(L, p1, p2, L->top, event)) + return -1; /* no metamethod */ + else + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttisnumber(l) && ttisnumber(r)) + return luai_numlt(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) + luaG_ordererror(L, l, r); + return res; +} + + +int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttisnumber(l) && ttisnumber(r)) + return luai_numle(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ + luaG_ordererror(L, l, r); + return !res; +} + + +/* +** equality of Lua values. L == NULL means raw equality (no metamethods) +*/ +int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttisequal(t1, t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TLCF: return fvalue(t1) == fvalue(t2); + case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + else if (L == NULL) return 0; + tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTM(L, tm, t1, t2, L->top, 1); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total) { + lua_assert(total >= 2); + do { + StkId top = L->top; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } + else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ + (void)tostring(L, top - 2); /* result is first operand */ + else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { + setobjs2s(L, top - 2, top - 1); /* result is second op. */ + } + else { + /* at least two non-empty string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (i = 1; i < total && tostring(L, top-i-1); i++) { + size_t l = tsvalue(top-i-1)->len; + if (l >= (MAX_SIZET/sizeof(char)) - tl) + luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + n = i; + do { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); + tl += l; + } while (--i > 0); + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got 'n' strings to create 1 new */ + L->top -= n-1; /* popped 'n' strings and pushed one */ + } while (total > 1); /* repeat until only 1 result left */ +} + + +void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { + const TValue *tm; + switch (ttypenv(rb)) { + case LUA_TTABLE: { + Table *h = hvalue(rb); + tm = fasttm(L, h->metatable, TM_LEN); + if (tm) break; /* metamethod? break switch to call it */ + setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ + return; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + return; + } + default: { /* try metamethod */ + tm = luaT_gettmbyobj(L, rb, TM_LEN); + if (ttisnil(tm)) /* no metamethod? */ + luaG_typeerror(L, rb, "get length of"); + break; + } + } + callTM(L, tm, rb, rb, ra, 1); +} + + +void luaV_arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); + setnvalue(ra, res); + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + +/* +** check whether cached closure in prototype 'p' may be reused, that is, +** whether there is a cached closure with the same upvalues needed by +** new closure to be created. +*/ +static Closure *getcached (Proto *p, UpVal **encup, StkId base) { + Closure *c = p->cache; + if (c != NULL) { /* is there a cached closure? */ + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ + TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; + if (c->l.upvals[i]->v != v) + return NULL; /* wrong upvalue; cannot reuse closure */ + } + } + return c; /* return cached closure (or NULL if no cached closure) */ +} + + +/* +** create a new Lua closure, push it in the stack, and initialize +** its upvalues. Note that the call to 'luaC_barrierproto' must come +** before the assignment to 'p->cache', as the function needs the +** original value of that field. +*/ +static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, + StkId ra) { + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + Closure *ncl = luaF_newLclosure(L, nup); + ncl->l.p = p; + setclLvalue(L, ra, ncl); /* anchor new closure in stack */ + for (i = 0; i < nup; i++) { /* fill in its upvalues */ + if (uv[i].instack) /* upvalue refers to local variable? */ + ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); + else /* get upvalue from enclosing function */ + ncl->l.upvals[i] = encup[uv[i].idx]; + } + luaC_barrierproto(L, p, ncl); + p->cache = ncl; /* save it on cache for reuse */ +} + + +/* +** finish execution of an opcode interrupted by an yield +*/ +void luaV_finishOp (lua_State *L) { + CallInfo *ci = L->ci; + StkId base = ci->u.l.base; + Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ + OpCode op = GET_OPCODE(inst); + switch (op) { /* finish its execution */ + case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: + case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: + case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { + setobjs2s(L, base + GETARG_A(inst), --L->top); + break; + } + case OP_LE: case OP_LT: case OP_EQ: { + int res = !l_isfalse(L->top - 1); + L->top--; + /* metamethod should not be called when operand is K */ + lua_assert(!ISK(GETARG_B(inst))); + if (op == OP_LE && /* "<=" using "<" instead? */ + ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) + res = !res; /* invert result */ + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); + if (res != GETARG_A(inst)) /* condition failed? */ + ci->u.l.savedpc++; /* skip jump instruction */ + break; + } + case OP_CONCAT: { + StkId top = L->top - 1; /* top when 'call_binTM' was called */ + int b = GETARG_B(inst); /* first element to concatenate */ + int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ + setobj2s(L, top - 2, top); /* put TM result in proper position */ + if (total > 1) { /* are there elements to concat? */ + L->top = top - 1; /* top is one after last element (at top-2) */ + luaV_concat(L, total); /* concat them (may yield again) */ + } + /* move final result to final position */ + setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); + L->top = ci->top; /* restore top */ + break; + } + case OP_TFORCALL: { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); + L->top = ci->top; /* correct top */ + break; + } + case OP_CALL: { + if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ + L->top = ci->top; /* adjust results */ + break; + } + case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: + break; + default: lua_assert(0); + } +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#if !defined luai_runtimecheck +#define luai_runtimecheck(L, c) /* void */ +#endif + + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) \ + (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) + + +/* execute a jump instruction */ +#define dojump(ci,i,e) \ + { int a = GETARG_A(i); \ + if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ + ci->u.l.savedpc += GETARG_sBx(i) + e; } + +/* for test instructions, execute the jump instruction that follows it */ +#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } + + +#define Protect(x) { {x;}; base = ci->u.l.base; } + +#define checkGC(L,c) \ + Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ + luaC_step(L); \ + L->top = ci->top;}) /* restore top */ \ + luai_threadyield(L); ) + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(L, nb, nc)); \ + } \ + else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } + + +#define vmdispatch(o) switch(o) +#define vmcase(l,b) case l: {b} break; +#define vmcasenb(l,b) case l: {b} /* nb = no break */ + +void luaV_execute (lua_State *L) { + CallInfo *ci = L->ci; + LClosure *cl; + TValue *k; + StkId base; + newframe: /* reentry point when frame changes (call/return) */ + lua_assert(ci == L->ci); + cl = clLvalue(ci->func); + k = cl->p->k; + base = ci->u.l.base; + /* main loop of interpreter */ + for (;;) { + Instruction i = *(ci->u.l.savedpc++); + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + Protect(traceexec(L)); + } + /* WARNING: several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == ci->u.l.base); + lua_assert(base <= L->top && L->top < L->stack + L->stacksize); + vmdispatch (GET_OPCODE(i)) { + vmcase(OP_MOVE, + setobjs2s(L, ra, RB(i)); + ) + vmcase(OP_LOADK, + TValue *rb = k + GETARG_Bx(i); + setobj2s(L, ra, rb); + ) + vmcase(OP_LOADKX, + TValue *rb; + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + rb = k + GETARG_Ax(*ci->u.l.savedpc++); + setobj2s(L, ra, rb); + ) + vmcase(OP_LOADBOOL, + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ + ) + vmcase(OP_LOADNIL, + int b = GETARG_B(i); + do { + setnilvalue(ra++); + } while (b--); + ) + vmcase(OP_GETUPVAL, + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + ) + vmcase(OP_GETTABUP, + int b = GETARG_B(i); + Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); + ) + vmcase(OP_GETTABLE, + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + ) + vmcase(OP_SETTABUP, + int a = GETARG_A(i); + Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); + ) + vmcase(OP_SETUPVAL, + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + ) + vmcase(OP_SETTABLE, + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + ) + vmcase(OP_NEWTABLE, + int b = GETARG_B(i); + int c = GETARG_C(i); + Table *t = luaH_new(L); + sethvalue(L, ra, t); + if (b != 0 || c != 0) + luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); + checkGC(L, ra + 1); + ) + vmcase(OP_SELF, + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + ) + vmcase(OP_ADD, + arith_op(luai_numadd, TM_ADD); + ) + vmcase(OP_SUB, + arith_op(luai_numsub, TM_SUB); + ) + vmcase(OP_MUL, + arith_op(luai_nummul, TM_MUL); + ) + vmcase(OP_DIV, + arith_op(luai_numdiv, TM_DIV); + ) + vmcase(OP_MOD, + arith_op(luai_nummod, TM_MOD); + ) + vmcase(OP_POW, + arith_op(luai_numpow, TM_POW); + ) + vmcase(OP_UNM, + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(L, nb)); + } + else { + Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); + } + ) + vmcase(OP_NOT, + TValue *rb = RB(i); + int res = l_isfalse(rb); /* next assignment may change this value */ + setbvalue(ra, res); + ) + vmcase(OP_LEN, + Protect(luaV_objlen(L, ra, RB(i))); + ) + vmcase(OP_CONCAT, + int b = GETARG_B(i); + int c = GETARG_C(i); + StkId rb; + L->top = base + c + 1; /* mark the end of concat operands */ + Protect(luaV_concat(L, c - b + 1)); + ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ + rb = b + base; + setobjs2s(L, ra, rb); + checkGC(L, (ra >= rb ? ra + 1 : rb)); + L->top = ci->top; /* restore top */ + ) + vmcase(OP_JMP, + dojump(ci, i, 0); + ) + vmcase(OP_EQ, + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + ) + vmcase(OP_LT, + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + ) + vmcase(OP_LE, + Protect( + if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + ) + vmcase(OP_TEST, + if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + vmcase(OP_TESTSET, + TValue *rb = RB(i); + if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) + ci->u.l.savedpc++; + else { + setobjs2s(L, ra, rb); + donextjump(ci); + } + ) + vmcase(OP_CALL, + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + if (luaD_precall(L, ra, nresults)) { /* C function? */ + if (nresults >= 0) L->top = ci->top; /* adjust results */ + base = ci->u.l.base; + } + else { /* Lua function */ + ci = L->ci; + ci->callstatus |= CIST_REENTRY; + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcase(OP_TAILCALL, + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ + base = ci->u.l.base; + else { + /* tail call: put called frame (n) in place of caller one (o) */ + CallInfo *nci = L->ci; /* called frame */ + CallInfo *oci = nci->previous; /* caller frame */ + StkId nfunc = nci->func; /* called function */ + StkId ofunc = oci->func; /* caller function */ + /* last stack slot filled by 'precall' */ + StkId lim = nci->u.l.base + getproto(nfunc)->numparams; + int aux; + /* close all upvalues from previous call */ + if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); + /* move new frame into old one */ + for (aux = 0; nfunc + aux < lim; aux++) + setobjs2s(L, ofunc + aux, nfunc + aux); + oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ + oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ + oci->u.l.savedpc = nci->u.l.savedpc; + oci->callstatus |= CIST_TAIL; /* function was tail called */ + ci = L->ci = oci; /* remove new frame */ + lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcasenb(OP_RETURN, + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (cl->p->sizep > 0) luaF_close(L, base); + b = luaD_poscall(L, ra); + if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ + return; /* external invocation: return */ + else { /* invocation via reentry: continue execution */ + ci = L->ci; + if (b) L->top = ci->top; + lua_assert(isLua(ci)); + lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcase(OP_FORLOOP, + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) + : luai_numle(L, limit, idx)) { + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + ) + vmcase(OP_FORPREP, + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); + ci->u.l.savedpc += GETARG_sBx(i); + ) + vmcasenb(OP_TFORCALL, + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb + 3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i), 1)); + L->top = ci->top; + i = *(ci->u.l.savedpc++); /* go to next instruction */ + ra = RA(i); + lua_assert(GET_OPCODE(i) == OP_TFORLOOP); + goto l_tforloop; + ) + vmcase(OP_TFORLOOP, + l_tforloop: + if (!ttisnil(ra + 1)) { /* continue loop? */ + setobjs2s(L, ra, ra + 1); /* save control variable */ + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ + } + ) + vmcase(OP_SETLIST, + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) n = cast_int(L->top - ra) - 1; + if (c == 0) { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + c = GETARG_Ax(*ci->u.l.savedpc++); + } + luai_runtimecheck(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-allocate it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + luaH_setint(L, h, last--, val); + luaC_barrierback(L, obj2gco(h), val); + } + L->top = ci->top; /* correct top (in case of previous open call) */ + ) + vmcase(OP_CLOSURE, + Proto *p = cl->p->p[GETARG_Bx(i)]; + Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ + if (ncl == NULL) /* no match? */ + pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ + else + setclLvalue(L, ra, ncl); /* push cashed closure */ + checkGC(L, ra + 1); + ) + vmcase(OP_VARARG, + int b = GETARG_B(i) - 1; + int j; + int n = cast_int(base - ci->func) - cl->p->numparams - 1; + if (b < 0) { /* B == 0? */ + b = n; /* get all var. arguments */ + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, base - n + j); + } + else { + setnilvalue(ra + j); + } + } + ) + vmcase(OP_EXTRAARG, + lua_assert(0); + ) + } + } +} + diff --git a/src/external/lua-5.2.3/src/lvm.h b/src/external/lua-5.2.3/src/lvm.h new file mode 100644 index 000000000..5380270da --- /dev/null +++ b/src/external/lua-5.2.3/src/lvm.h @@ -0,0 +1,44 @@ +/* +** $Id: lvm.h,v 2.18.1.1 2013/04/12 18:48:47 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) + +#define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) + + +/* not to called directly */ +LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_finishOp (lua_State *L); +LUAI_FUNC void luaV_execute (lua_State *L); +LUAI_FUNC void luaV_concat (lua_State *L, int total); +LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op); +LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); + +#endif diff --git a/src/external/lua-5.2.3/src/lzio.c b/src/external/lua-5.2.3/src/lzio.c new file mode 100644 index 000000000..20efea983 --- /dev/null +++ b/src/external/lua-5.2.3/src/lzio.c @@ -0,0 +1,76 @@ +/* +** $Id: lzio.c,v 1.35.1.1 2013/04/12 18:48:47 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; /* discount char being returned */ + z->p = buff; + return cast_uchar(*(z->p++)); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (z->n == 0) { /* no bytes in buffer? */ + if (luaZ_fill(z) == EOZ) /* try to read more */ + return n; /* no more input; return number of missing bytes */ + else { + z->n++; /* luaZ_fill consumed first byte; put it back */ + z->p--; + } + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + diff --git a/src/external/lua-5.2.3/src/lzio.h b/src/external/lua-5.2.3/src/lzio.h new file mode 100644 index 000000000..441f7479c --- /dev/null +++ b/src/external/lua-5.2.3/src/lzio.h @@ -0,0 +1,65 @@ +/* +** $Id: lzio.h,v 1.26.1.1 2013/04/12 18:48:47 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) + + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; /* reader function */ + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/src/external/zlib-1.2.11/CMakeLists.txt b/src/external/zlib-1.2.11/CMakeLists.txt new file mode 100644 index 000000000..0fe939df6 --- /dev/null +++ b/src/external/zlib-1.2.11/CMakeLists.txt @@ -0,0 +1,249 @@ +cmake_minimum_required(VERSION 2.4.4) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) + +project(zlib C) + +set(VERSION "1.2.11") + +option(ASM686 "Enable building i686 assembly implementation") +option(AMD64 "Enable building amd64 assembly implementation") + +set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") +set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") +set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") +set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") +set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") + +include(CheckTypeSize) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +enable_testing() + +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stddef.h HAVE_STDDEF_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) +# We add these other definitions here because CheckTypeSize.cmake +# in CMake 2.4.x does not automatically do so and we want +# compatibility with CMake 2.4.x. +if(HAVE_SYS_TYPES_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) +endif() +if(HAVE_STDINT_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) +endif() +if(HAVE_STDDEF_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) +endif() +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +# +# Check for unistd.h +# +check_include_file(unistd.h Z_HAVE_UNISTD_H) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") + message(STATUS "to 'zconf.h.included' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) + endif() +endif() + +set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h + zlib.h +) +set(ZLIB_PRIVATE_HDRS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c +) + +if(NOT MINGW) + set(ZLIB_DLL_SRCS + win32/zlib1.rc # If present will override custom build rule below. + ) +endif() + +if(CMAKE_COMPILER_IS_GNUCC) + if(ASM686) + set(ZLIB_ASMS contrib/asm686/match.S) + elseif (AMD64) + set(ZLIB_ASMS contrib/amd64/amd64-match.S) + endif () + + if(ZLIB_ASMS) + add_definitions(-DASMV) + set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) + endif() +endif() + +if(MSVC) + if(ASM686) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx86/inffas32.asm + contrib/masmx86/match686.asm + ) + elseif (AMD64) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx64/gvmat64.asm + contrib/masmx64/inffasx64.asm + ) + endif() + + if(ZLIB_ASMS) + add_definitions(-DASMV -DASMINF) + endif() +endif() + +# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) + +if(MINGW) + # This gets us DLL resource information when compiling on MinGW. + if(NOT CMAKE_RC_COMPILER) + set(CMAKE_RC_COMPILER windres.exe) + endif() + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + COMMAND ${CMAKE_RC_COMPILER} + -D GCC_WINDRES + -I ${CMAKE_CURRENT_SOURCE_DIR} + -I ${CMAKE_CURRENT_BINARY_DIR} + -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) + set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) +endif(MINGW) + +add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) +set_target_properties(zlib PROPERTIES SOVERSION 1) + +if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version + # encoded into their final filename. We disable this on Cygwin because + # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll + # seems to be the default. + # + # This has no effect with MSVC, on that platform the version info for + # the DLL comes from the resource file win32/zlib1.rc + set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) +endif() + +if(UNIX) + # On unix-like platforms the library is almost always called libz + set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) + if(NOT APPLE) + set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") + endif() +elseif(BUILD_SHARED_LIBS AND WIN32) + # Creates zlib1.dll when building shared library version + set_target_properties(zlib PROPERTIES SUFFIX "1.dll") +endif() + +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) + install(TARGETS zlib zlibstatic + RUNTIME DESTINATION "${INSTALL_BIN_DIR}" + ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" + LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) +endif() +if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) + install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) + install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) + install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") +endif() + +#============================================================================ +# Example binaries +#============================================================================ + +add_executable(example test/example.c) +target_link_libraries(example zlib) +add_test(example example) + +add_executable(minigzip test/minigzip.c) +target_link_libraries(minigzip zlib) + +if(HAVE_OFF64_T) + add_executable(example64 test/example.c) + target_link_libraries(example64 zlib) + set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") + add_test(example64 example64) + + add_executable(minigzip64 test/minigzip.c) + target_link_libraries(minigzip64 zlib) + set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") +endif() diff --git a/src/external/zlib-1.2.11/ChangeLog b/src/external/zlib-1.2.11/ChangeLog new file mode 100644 index 000000000..30199a65a --- /dev/null +++ b/src/external/zlib-1.2.11/ChangeLog @@ -0,0 +1,1515 @@ + + ChangeLog file for zlib + +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + +Changes in 1.2.9 (31 Dec 2016) +- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] +- Improve contrib/blast to return unused bytes +- Assure that gzoffset() is correct when appending +- Improve compress() and uncompress() to support large lengths +- Fix bug in test/example.c where error code not saved +- Remedy Coverity warning [Randers-Pehrson] +- Improve speed of gzprintf() in transparent mode +- Fix inflateInit2() bug when windowBits is 16 or 32 +- Change DEBUG macro to ZLIB_DEBUG +- Avoid uninitialized access by gzclose_w() +- Allow building zlib outside of the source directory +- Fix bug that accepted invalid zlib header when windowBits is zero +- Fix gzseek() problem on MinGW due to buggy _lseeki64 there +- Loop on write() calls in gzwrite.c in case of non-blocking I/O +- Add --warn (-w) option to ./configure for more compiler warnings +- Reject a window size of 256 bytes if not using the zlib wrapper +- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE +- Add --debug (-d) option to ./configure to define ZLIB_DEBUG +- Fix bugs in creating a very large gzip header +- Add uncompress2() function, which returns the input size used +- Assure that deflateParams() will not switch functions mid-block +- Dramatically speed up deflation for level 0 (storing) +- Add gzfread(), duplicating the interface of fread() +- Add gzfwrite(), duplicating the interface of fwrite() +- Add deflateGetDictionary() function +- Use snprintf() for later versions of Microsoft C +- Fix *Init macros to use z_ prefix when requested +- Replace as400 with os400 for OS/400 support [Monnerat] +- Add crc32_z() and adler32_z() functions with size_t lengths +- Update Visual Studio project files [AraHaan] + +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Roß] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix uninitialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Suport i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no library use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminancy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assmebler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generate bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/src/external/zlib-1.2.11/FAQ b/src/external/zlib-1.2.11/FAQ new file mode 100644 index 000000000..99b7cf92e --- /dev/null +++ b/src/external/zlib-1.2.11/FAQ @@ -0,0 +1,368 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://zlib.net/ which may have more recent information. +The lastest zlib FAQ is at http://zlib.net/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at http://zlib.net/ . + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://marknelson.us/1997/01/01/zlib-engine/ + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a + heavily annotated example. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h . Examples of zlib usage are in the files test/example.c + and test/minigzip.c, with more in examples/ . + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + By default a shared (and a static) library is built for Unix. So: + + make distclean + ./configure + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.pdflib.com/ . To modify PDF forms, see + http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://zlib.net/ . + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specification in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. + +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/src/external/zlib-1.2.11/INDEX b/src/external/zlib-1.2.11/INDEX new file mode 100644 index 000000000..2ba064120 --- /dev/null +++ b/src/external/zlib-1.2.11/INDEX @@ -0,0 +1,68 @@ +CMakeLists.txt cmake build file +ChangeLog history of changes +FAQ Frequently Asked Questions about zlib +INDEX this file +Makefile dummy Makefile that tells you to ./configure +Makefile.in template for Unix Makefile +README guess what +configure configure script for Unix +make_vms.com makefile for VMS +test/example.c zlib usages examples for build testing +test/minigzip.c minimal gzip-like functionality for build testing +test/infcover.c inf*.c code coverage for build coverage testing +treebuild.xml XML description of source file dependencies +zconf.h.cmakein zconf.h template for cmake +zconf.h.in zconf.h template for configure +zlib.3 Man page for zlib +zlib.3.pdf Man page in PDF format +zlib.map Linux symbol information +zlib.pc.in Template for pkg-config descriptor +zlib.pc.cmakein zlib.pc template for cmake +zlib2ansi perl script to convert source files for C++ compilation + +amiga/ makefiles for Amiga SAS C +as400/ makefiles for AS/400 +doc/ documentation for formats and algorithms +msdos/ makefiles for MSDOS +nintendods/ makefile for Nintendo DS +old/ makefiles for various architectures and zlib documentation + files that have not yet been updated for zlib 1.2.x +qnx/ makefiles for QNX +watcom/ makefiles for OpenWatcom +win32/ makefiles for Windows + + zlib public header files (required for library use): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +crc32.h +deflate.c +deflate.h +gzclose.c +gzguts.h +gzlib.c +gzread.c +gzwrite.c +infback.c +inffast.c +inffast.h +inffixed.h +inflate.c +inflate.h +inftrees.c +inftrees.h +trees.c +trees.h +uncompr.c +zutil.c +zutil.h + + source files for sample programs +See examples/README.examples + + unsupported contributions by third parties +See contrib/README.contrib diff --git a/src/external/zlib-1.2.11/Makefile.in b/src/external/zlib-1.2.11/Makefile.in new file mode 100644 index 000000000..5a77949ff --- /dev/null +++ b/src/external/zlib-1.2.11/Makefile.in @@ -0,0 +1,410 @@ +# Makefile for zlib +# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static + +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DZLIB_DEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +SFLAGS=-O +LDFLAGS= +TEST_LDFLAGS=-L. libz.a +LDSHARED=$(CC) +CPP=$(CC) -E + +STATICLIB=libz.a +SHAREDLIB=libz.so +SHAREDLIBV=libz.so.1.2.11 +SHAREDLIBM=libz.so.1 +LIBS=$(STATICLIB) $(SHAREDLIBV) + +AR=ar +ARFLAGS=rc +RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC=-lc +TAR=tar +SHELL=/bin/sh +EXE= + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig +SRCDIR= +ZINC= +ZINCOUT=-I. + +OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o +OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o +OBJC = $(OBJZ) $(OBJG) + +PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo +PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo +PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) + +# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo +OBJA = +PIC_OBJA = + +OBJS = $(OBJC) $(OBJA) + +PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) + +all: static shared + +static: example$(EXE) minigzip$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +all64: example64$(EXE) minigzip64$(EXE) + +check: test + +test: all teststatic testshared + +teststatic: static + @TMPST=tmpst_$$; \ + if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; false; \ + fi; \ + rm -f $$TMPST + +testshared: shared + @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ + TMPSH=tmpsh_$$; \ + if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; false; \ + fi; \ + rm -f $$TMPSH + +test64: all64 + @TMP64=tmp64_$$; \ + if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \ + echo ' *** zlib 64-bit test OK ***'; \ + else \ + echo ' *** zlib 64-bit test FAILED ***'; false; \ + fi; \ + rm -f $$TMP64 + +infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c + +infcover: infcover.o libz.a + $(CC) $(CFLAGS) -o $@ infcover.o libz.a + +cover: infcover + rm -f *.gcda + ./infcover + gcov inf*.c + +libz.a: $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +match.lo: match.S + $(CPP) match.S > _match.s + $(CC) -c -fPIC _match.s + mv _match.o match.lo + rm -f _match.s + +example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c + +minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c + +example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c + +minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c + + +adler32.o: $(SRCDIR)adler32.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c + +crc32.o: $(SRCDIR)crc32.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c + +deflate.o: $(SRCDIR)deflate.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c + +infback.o: $(SRCDIR)infback.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c + +inffast.o: $(SRCDIR)inffast.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c + +inflate.o: $(SRCDIR)inflate.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c + +inftrees.o: $(SRCDIR)inftrees.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c + +trees.o: $(SRCDIR)trees.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c + +zutil.o: $(SRCDIR)zutil.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c + +compress.o: $(SRCDIR)compress.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c + +uncompr.o: $(SRCDIR)uncompr.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c + +gzclose.o: $(SRCDIR)gzclose.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c + +gzlib.o: $(SRCDIR)gzlib.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c + +gzread.o: $(SRCDIR)gzread.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c + +gzwrite.o: $(SRCDIR)gzwrite.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c + + +adler32.lo: $(SRCDIR)adler32.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c + -@mv objs/adler32.o $@ + +crc32.lo: $(SRCDIR)crc32.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c + -@mv objs/crc32.o $@ + +deflate.lo: $(SRCDIR)deflate.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c + -@mv objs/deflate.o $@ + +infback.lo: $(SRCDIR)infback.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c + -@mv objs/infback.o $@ + +inffast.lo: $(SRCDIR)inffast.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c + -@mv objs/inffast.o $@ + +inflate.lo: $(SRCDIR)inflate.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c + -@mv objs/inflate.o $@ + +inftrees.lo: $(SRCDIR)inftrees.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c + -@mv objs/inftrees.o $@ + +trees.lo: $(SRCDIR)trees.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c + -@mv objs/trees.o $@ + +zutil.lo: $(SRCDIR)zutil.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c + -@mv objs/zutil.o $@ + +compress.lo: $(SRCDIR)compress.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c + -@mv objs/compress.o $@ + +uncompr.lo: $(SRCDIR)uncompr.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c + -@mv objs/uncompr.o $@ + +gzclose.lo: $(SRCDIR)gzclose.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c + -@mv objs/gzclose.o $@ + +gzlib.lo: $(SRCDIR)gzlib.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c + -@mv objs/gzlib.o $@ + +gzread.lo: $(SRCDIR)gzread.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c + -@mv objs/gzread.o $@ + +gzwrite.lo: $(SRCDIR)gzwrite.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c + -@mv objs/gzwrite.o $@ + + +placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a + $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) + -@rmdir objs + +example$(EXE): example.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) + +minigzip$(EXE): minigzip.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) + +examplesh$(EXE): example.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) + +minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) + +example64$(EXE): example64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + +minigzip64$(EXE): minigzip64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) + +install-libs: $(LIBS) + -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + rm -f $(DESTDIR)$(libdir)/$(STATICLIB) + cp $(STATICLIB) $(DESTDIR)$(libdir) + chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) + -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 + -@if test -n "$(SHAREDLIBV)"; then \ + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ + cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ + echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ + chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ + echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \ + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \ + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ + ($(LDCONFIG) || true) >/dev/null 2>&1; \ + fi + rm -f $(DESTDIR)$(man3dir)/zlib.3 + cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir) + chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc + cp zlib.pc $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir) + chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + +uninstall: + cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h + cd $(DESTDIR)$(libdir) && rm -f libz.a; \ + if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ + fi + cd $(DESTDIR)$(man3dir) && rm -f zlib.3 + cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc + +docs: zlib.3.pdf + +zlib.3.pdf: $(SRCDIR)zlib.3 + groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@ + +zconf.h.cmakein: $(SRCDIR)zconf.h.in + -@ TEMPFILE=zconfh_$$; \ + echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ + sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\ + touch -r $(SRCDIR)zconf.h.in $@ &&\ + rm $$TEMPFILE + +zconf: $(SRCDIR)zconf.h.in + cp -p $(SRCDIR)zconf.h.in zconf.h + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ + example64$(EXE) minigzip64$(EXE) \ + infcover \ + libz.* foo.gz so_locations \ + _match.s maketree contrib/infback9/*.o + rm -rf objs + rm -f *.gcda *.gcno *.gcov + rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov + +maintainer-clean: distclean +distclean: clean zconf zconf.h.cmakein docs + rm -f Makefile zlib.pc configure.log + -@rm -f .DS_Store + @if [ -f Makefile.in ]; then \ + printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ + printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \ + touch -r $(SRCDIR)Makefile.in Makefile ; fi + @if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi + @if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi + +tags: + etags $(SRCDIR)*.[ch] + +adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h +compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h +crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h +deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h +inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h +inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h +trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h + +adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h +compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h +crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h +deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h +infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h +inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h +inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h +trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h diff --git a/src/external/zlib-1.2.11/README b/src/external/zlib-1.2.11/README new file mode 100644 index 000000000..51106de47 --- /dev/null +++ b/src/external/zlib-1.2.11/README @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.11 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.11 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/src/external/zlib-1.2.11/adler32.c b/src/external/zlib-1.2.11/adler32.c new file mode 100644 index 000000000..d0be4380a --- /dev/null +++ b/src/external/zlib-1.2.11/adler32.c @@ -0,0 +1,186 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32_z(adler, buf, len) + uLong adler; + const Bytef *buf; + z_size_t len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + return adler32_z(adler, buf, len); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/src/external/zlib-1.2.11/amiga/Makefile.pup b/src/external/zlib-1.2.11/amiga/Makefile.pup new file mode 100644 index 000000000..8940c120f --- /dev/null +++ b/src/external/zlib-1.2.11/amiga/Makefile.pup @@ -0,0 +1,69 @@ +# Amiga powerUP (TM) Makefile +# makefile for libpng and SAS C V6.58/7.00 PPC compiler +# Copyright (C) 1998 by Andreas R. Kleinert + +LIBNAME = libzip.a + +CC = scppc +CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \ + OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER +AR = ppc-amigaos-ar cr +RANLIB = ppc-amigaos-ranlib +LD = ppc-amigaos-ld -r +LDFLAGS = -o +LDLIBS = LIB:scppc.a LIB:end.o +RM = delete quiet + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example minigzip + +check: test +test: all + example + echo hello world | minigzip | minigzip -d + +$(LIBNAME): $(OBJS) + $(AR) $@ $(OBJS) + -$(RANLIB) $@ + +example: example.o $(LIBNAME) + $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) + +minigzip: minigzip.o $(LIBNAME) + $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) + +mostlyclean: clean +clean: + $(RM) *.o example minigzip $(LIBNAME) foo.gz + +zip: + zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ + descrip.mms *.[ch] + +tgz: + cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ + zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzclose.o: zlib.h zconf.h gzguts.h +gzlib.o: zlib.h zconf.h gzguts.h +gzread.o: zlib.h zconf.h gzguts.h +gzwrite.o: zlib.h zconf.h gzguts.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/src/external/zlib-1.2.11/amiga/Makefile.sas b/src/external/zlib-1.2.11/amiga/Makefile.sas new file mode 100644 index 000000000..749e29152 --- /dev/null +++ b/src/external/zlib-1.2.11/amiga/Makefile.sas @@ -0,0 +1,68 @@ +# SMakefile for zlib +# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly +# Osma Ahvenlampi +# Amiga, SAS/C 6.56 & Smake + +CC=sc +CFLAGS=OPT +#CFLAGS=OPT CPU=68030 +#CFLAGS=DEBUG=LINE +LDFLAGS=LIB z.lib + +SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ + NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \ + DEF=POSTINC + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: SCOPTIONS example minigzip + +check: test +test: all + example + echo hello world | minigzip | minigzip -d + +install: z.lib + copy clone zlib.h zconf.h INCLUDE: + copy clone z.lib LIB: + +z.lib: $(OBJS) + oml z.lib r $(OBJS) + +example: example.o z.lib + $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) + +minigzip: minigzip.o z.lib + $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) + +mostlyclean: clean +clean: + -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS + +SCOPTIONS: Makefile.sas + copy to $@ (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + sourceLen -= stream.avail_in; + } + err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + deflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/src/external/zlib-1.2.11/configure b/src/external/zlib-1.2.11/configure new file mode 100644 index 000000000..e974d1fd7 --- /dev/null +++ b/src/external/zlib-1.2.11/configure @@ -0,0 +1,921 @@ +#!/bin/sh +# configure script for zlib. +# +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +# start off configure.log +echo -------------------- >> configure.log +echo $0 $* >> configure.log +date >> configure.log + +# get source directory +SRCDIR=`dirname $0` +if test $SRCDIR = "."; then + ZINC="" + ZINCOUT="-I." + SRCDIR="" +else + ZINC='-include zconf.h' + ZINCOUT='-I. -I$(SRCDIR)' + SRCDIR="$SRCDIR/" +fi + +# set command prefix for cross-compilation +if [ -n "${CHOST}" ]; then + uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`" + CROSS_PREFIX="${CHOST}-" +fi + +# destination name for static library +STATICLIB=libz.a + +# extract zlib version numbers from zlib.h +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h` +VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h` +VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` +VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` + +# establish commands for library building +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +fi +ARFLAGS=${ARFLAGS-"rc"} +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log +else + RANLIB=${RANLIB-"ranlib"} +fi +if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then + NM=${NM-"${CROSS_PREFIX}nm"} + test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log +else + NM=${NM-"nm"} +fi + +# set defaults before processing command line options +LDCONFIG=${LDCONFIG-"ldconfig"} +LDSHAREDLIBC="${LDSHAREDLIBC--lc}" +ARCHS= +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} +includedir=${includedir-'${prefix}/include'} +mandir=${mandir-'${prefix}/share/man'} +shared_ext='.so' +shared=1 +solo=0 +cover=0 +zprefix=0 +zconst=0 +build64=0 +gcc=0 +warn=0 +debug=0 +old_cc="$CC" +old_cflags="$CFLAGS" +OBJC='$(OBJZ) $(OBJG)' +PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)' + +# leave this script, optionally in a bad way +leave() +{ + if test "$*" != "0"; then + echo "** $0 aborting." | tee -a configure.log + fi + rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + echo -------------------- >> configure.log + echo >> configure.log + echo >> configure.log + exit $1 +} + +# process command line options +while test $# -ge 1 +do +case "$1" in + -h* | --help) + echo 'usage:' | tee -a configure.log + echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; + --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; + -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + --solo) solo=1; shift ;; + --cover) cover=1; shift ;; + -z* | --zprefix) zprefix=1; shift ;; + -6* | --64) build64=1; shift ;; + -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; + -c* | --const) zconst=1; shift ;; + -w* | --warn) warn=1; shift ;; + -d* | --debug) debug=1; shift ;; + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log + leave 1;; + esac +done + +# temporary file name +test=ztest$$ + +# put arguments in log, also put test file in log if used in arguments +show() +{ + case "$*" in + *$test.c*) + echo === $test.c === >> configure.log + cat $test.c >> configure.log + echo === >> configure.log;; + esac + echo $* >> configure.log +} + +# check for gcc vs. cc and set compile and link flags based on the system identified by uname +cat > $test.c <&1` in + *gcc*) gcc=1 ;; + *clang*) gcc=1 ;; +esac + +show $cc -c $test.c +if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then + echo ... using gcc >> configure.log + CC="$cc" + CFLAGS="${CFLAGS--O3}" + SFLAGS="${CFLAGS--O3} -fPIC" + if test "$ARCHS"; then + CFLAGS="${CFLAGS} ${ARCHS}" + LDFLAGS="${LDFLAGS} ${ARCHS}" + fi + if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + fi + if test "$warn" -eq 1; then + if test "$zconst" -eq 1; then + CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST" + else + CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + fi + fi + if test $debug -eq 1; then + CFLAGS="${CFLAGS} -DZLIB_DEBUG" + SFLAGS="${SFLAGS} -DZLIB_DEBUG" + fi + if test -z "$uname"; then + uname=`(uname -s || echo unknown) 2>/dev/null` + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | solaris*) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} ;; + *BSD | *bsd* | DragonFly) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} + LDCONFIG="ldconfig -m" ;; + CYGWIN* | Cygwin* | cygwin* | OS/2*) + EXE='.exe' ;; + MINGW* | mingw*) +# temporary bypass + rm -f $test.[co] $test $test$shared_ext + echo "Please use win32/Makefile.gcc instead." | tee -a configure.log + leave 1 + LDSHARED=${LDSHARED-"$cc -shared"} + LDSHAREDLIBC="" + EXE='.exe' ;; + QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 + # (alain.bonnefoy@icbt.com) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; + HP-UX*) + LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} + case `(uname -m || echo unknown) 2>/dev/null` in + ia64) + shared_ext='.so' + SHAREDLIB='libz.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='libz.sl' ;; + esac ;; + Darwin* | darwin*) + shared_ext='.dylib' + SHAREDLIB=libz$shared_ext + SHAREDLIBV=libz.$VER$shared_ext + SHAREDLIBM=libz.$VER1$shared_ext + LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} + if libtool -V 2>&1 | grep Apple > /dev/null; then + AR="libtool" + else + AR="/usr/bin/libtool" + fi + ARFLAGS="-o" ;; + *) LDSHARED=${LDSHARED-"$cc -shared"} ;; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + gcc=0 + echo ... using $CC >> configure.log + if test -z "$uname"; then + uname=`(uname -sr || echo unknown) 2>/dev/null` + fi + case "$uname" in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} +# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} + LDSHARED=${LDSHARED-"ld -b"} + case `(uname -m || echo unknown) 2>/dev/null` in + ia64) + shared_ext='.so' + SHAREDLIB='libz.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='libz.sl' ;; + esac ;; + IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} + CFLAGS=${CFLAGS-"-ansi -O2"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; + OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDFLAGS="${LDFLAGS} -Wl,-rpath,." + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;; + OSF1*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; + QNX*) SFLAGS=${CFLAGS-"-4 -O"} + CFLAGS=${CFLAGS-"-4 -O"} + LDSHARED=${LDSHARED-"cc"} + RANLIB=${RANLIB-"true"} + AR="cc" + ARFLAGS="-A" ;; + SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;; + SunOS\ 5* | solaris*) + LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"} + SFLAGS=${CFLAGS-"-fast -KPIC"} + CFLAGS=${CFLAGS-"-fast"} + if test $build64 -eq 1; then + # old versions of SunPRO/Workshop/Studio don't support -m64, + # but newer ones do. Check for it. + flag64=`$CC -flags | egrep -- '^-m64'` + if test x"$flag64" != x"" ; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + else + case `(uname -m || echo unknown) 2>/dev/null` in + i86*) + SFLAGS="$SFLAGS -xarch=amd64" + CFLAGS="$CFLAGS -xarch=amd64" ;; + *) + SFLAGS="$SFLAGS -xarch=v9" + CFLAGS="$CFLAGS -xarch=v9" ;; + esac + fi + fi + if test -n "$ZINC"; then + ZINC='-I- -I. -I$(SRCDIR)' + fi + ;; + SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} + CFLAGS=${CFLAGS-"-O2"} + LDSHARED=${LDSHARED-"ld"} ;; + SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} + CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"} + LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;; + UNIX_System_V\ 4.2.0) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + UNIX_SV\ 4.2MP) + SFLAGS=${CFLAGS-"-Kconform_pic -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + OpenUNIX\ 5) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + AIX*) # Courtesy of dbakker@arrayasolutions.com + SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + LDSHARED=${LDSHARED-"xlc -G"} ;; + # send working options for other systems to zlib@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -shared"} ;; + esac +fi + +# destination names for shared library if not defined above +SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} +SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} +SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} + +echo >> configure.log + +# define functions for testing compiler and library characteristics and logging the results + +cat > $test.c </dev/null; then + try() + { + show $* + test "`( $* ) 2>&1 | tee -a configure.log`" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else + try() + { + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code "$ret")" >> configure.log + fi + return $ret + } +fi + +tryboth() +{ + show $* + got=`( $* ) 2>&1` + ret=$? + printf %s "$got" >> configure.log + if test $ret -ne 0; then + return $ret + fi + test "$got" = "" +} + +cat > $test.c << EOF +int foo() { return 0; } +EOF +echo "Checking for obsessive-compulsive compiler options..." >> configure.log +if try $CC -c $CFLAGS $test.c; then + : +else + echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log + leave 1 +fi + +echo >> configure.log + +# see if shared library build supported +cat > $test.c <> configure.log + show "$NM $test.o | grep _hello" + if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then + CPP="$CPP -DNO_UNDERLINE" + echo Checking for underline in external names... No. | tee -a configure.log + else + echo Checking for underline in external names... Yes. | tee -a configure.log + fi ;; +esac + +echo >> configure.log + +# check for size_t +cat > $test.c < +#include +size_t dummy = 0; +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking for size_t... Yes." | tee -a configure.log + need_sizet=0 +else + echo "Checking for size_t... No." | tee -a configure.log + need_sizet=1 +fi + +echo >> configure.log + +# find the size_t integer type, if needed +if test $need_sizet -eq 1; then + cat > $test.c < $test.c < +int main(void) { + if (sizeof(void *) <= sizeof(int)) puts("int"); + else if (sizeof(void *) <= sizeof(long)) puts("long"); + else puts("z_longlong"); + return 0; +} +EOF + else + echo "Checking for long long... No." | tee -a configure.log + cat > $test.c < +int main(void) { + if (sizeof(void *) <= sizeof(int)) puts("int"); + else puts("long"); + return 0; +} +EOF + fi + if try $CC $CFLAGS -o $test $test.c; then + sizet=`./$test` + echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log + else + echo "Failed to find a pointer-size integer type." | tee -a configure.log + leave 1 + fi +fi + +if test $need_sizet -eq 1; then + CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}" + SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}" +fi + +echo >> configure.log + +# check for large file support, and if none, check for fseeko() +cat > $test.c < +off64_t dummy = 0; +EOF +if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + ALL="${ALL} all64" + TEST="${TEST} test64" + echo "Checking for off64_t... Yes." | tee -a configure.log + echo "Checking for fseeko... Yes." | tee -a configure.log +else + echo "Checking for off64_t... No." | tee -a configure.log + echo >> configure.log + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for fseeko... Yes." | tee -a configure.log + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." | tee -a configure.log + fi +fi + +echo >> configure.log + +# check for strerror() for use by gz* functions +cat > $test.c < +#include +int main() { return strlen(strerror(errno)); } +EOF +if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for strerror... Yes." | tee -a configure.log +else + CFLAGS="${CFLAGS} -DNO_STRERROR" + SFLAGS="${SFLAGS} -DNO_STRERROR" + echo "Checking for strerror... No." | tee -a configure.log +fi + +# copy clean zconf.h for subsequent edits +cp -p ${SRCDIR}zconf.h.in zconf.h + +echo >> configure.log + +# check for unistd.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Checking for unistd.h... Yes." | tee -a configure.log +else + echo "Checking for unistd.h... No." | tee -a configure.log +fi + +echo >> configure.log + +# check for stdarg.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Checking for stdarg.h... Yes." | tee -a configure.log +else + echo "Checking for stdarg.h... No." | tee -a configure.log +fi + +# if the z_ prefix was requested, save that in zconf.h +if test $zprefix -eq 1; then + sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo >> configure.log + echo "Using z_ prefix on all symbols." | tee -a configure.log +fi + +# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists +if test $solo -eq 1; then + sed '/#define ZCONF_H/a\ +#define Z_SOLO + +' < zconf.h > zconf.temp.h + mv zconf.temp.h zconf.h +OBJC='$(OBJZ)' +PIC_OBJC='$(PIC_OBJZ)' +fi + +# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X +if test $cover -eq 1; then + CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" + if test -n "$GCC_CLASSIC"; then + CC=$GCC_CLASSIC + fi +fi + +echo >> configure.log + +# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions +# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a +# return value. The most secure result is vsnprintf() with a return value. snprintf() with a +# return value is secure as well, but then gzprintf() will be limited to 20 arguments. +cat > $test.c < +#include +#include "zconf.h" +int main() +{ +#ifndef STDC + choke me +#endif + return 0; +} +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log + + echo >> configure.log + cat > $test.c < +#include +int mytest(const char *fmt, ...) +{ + char buf[20]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return 0; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +#include +int mytest(const char *fmt, ...) +{ + int n; + char buf[20]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return n; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_vsnprintf_void" + SFLAGS="$SFLAGS -DHAS_vsnprintf_void" + echo "Checking for return value of vsnprintf()... No." | tee -a configure.log + echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + else + CFLAGS="$CFLAGS -DNO_vsnprintf" + SFLAGS="$SFLAGS -DNO_vsnprintf" + echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log + echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log + echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +#include +int mytest(const char *fmt, ...) +{ + int n; + char buf[20]; + va_list ap; + va_start(ap, fmt); + n = vsprintf(buf, fmt, ap); + va_end(ap); + return n; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_vsprintf_void" + SFLAGS="$SFLAGS -DHAS_vsprintf_void" + echo "Checking for return value of vsprintf()... No." | tee -a configure.log + echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + fi +else + echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + snprintf(buf, sizeof(buf), "%s", "foo"); + return 0; +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + return snprintf(buf, sizeof(buf), "%s", "foo"); +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of snprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_snprintf_void" + SFLAGS="$SFLAGS -DHAS_snprintf_void" + echo "Checking for return value of snprintf()... No." | tee -a configure.log + echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + else + CFLAGS="$CFLAGS -DNO_snprintf" + SFLAGS="$SFLAGS -DNO_snprintf" + echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log + echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log + echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + return sprintf(buf, "%s", "foo"); +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of sprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_sprintf_void" + SFLAGS="$SFLAGS -DHAS_sprintf_void" + echo "Checking for return value of sprintf()... No." | tee -a configure.log + echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files +if test "$gcc" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log +echo ALL = $ALL >> configure.log +echo AR = $AR >> configure.log +echo ARFLAGS = $ARFLAGS >> configure.log +echo CC = $CC >> configure.log +echo CFLAGS = $CFLAGS >> configure.log +echo CPP = $CPP >> configure.log +echo EXE = $EXE >> configure.log +echo LDCONFIG = $LDCONFIG >> configure.log +echo LDFLAGS = $LDFLAGS >> configure.log +echo LDSHARED = $LDSHARED >> configure.log +echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log +echo OBJC = $OBJC >> configure.log +echo PIC_OBJC = $PIC_OBJC >> configure.log +echo RANLIB = $RANLIB >> configure.log +echo SFLAGS = $SFLAGS >> configure.log +echo SHAREDLIB = $SHAREDLIB >> configure.log +echo SHAREDLIBM = $SHAREDLIBM >> configure.log +echo SHAREDLIBV = $SHAREDLIBV >> configure.log +echo STATICLIB = $STATICLIB >> configure.log +echo TEST = $TEST >> configure.log +echo VER = $VER >> configure.log +echo Z_U4 = $Z_U4 >> configure.log +echo SRCDIR = $SRCDIR >> configure.log +echo exec_prefix = $exec_prefix >> configure.log +echo includedir = $includedir >> configure.log +echo libdir = $libdir >> configure.log +echo mandir = $mandir >> configure.log +echo prefix = $prefix >> configure.log +echo sharedlibdir = $sharedlibdir >> configure.log +echo uname = $uname >> configure.log + +# udpate Makefile with the configure results +sed < ${SRCDIR}Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^CPP *=/s#=.*#=$CPP# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^EXE *=/s#=.*#=$EXE# +/^SRCDIR *=/s#=.*#=$SRCDIR# +/^ZINC *=/s#=.*#=$ZINC# +/^ZINCOUT *=/s#=.*#=$ZINCOUT# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^OBJC *=/s#=.*#= $OBJC# +/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# +/^all: */s#:.*#: $ALL# +/^test: */s#:.*#: $TEST# +" > Makefile + +# create zlib.pc with the configure results +sed < ${SRCDIR}zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^CPP *=/s#=.*#=$CPP# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +" | sed -e " +s/\@VERSION\@/$VER/g; +" > zlib.pc + +# done +leave 0 diff --git a/src/external/zlib-1.2.11/contrib/README.contrib b/src/external/zlib-1.2.11/contrib/README.contrib new file mode 100644 index 000000000..a411d5c39 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/README.contrib @@ -0,0 +1,78 @@ +All files under this contrib directory are UNSUPPORTED. There were +provided by users of zlib and were not tested by the authors of zlib. +Use at your own risk. Please contact the authors of the contributions +for help about these, not the zlib authors. Thanks. + + +ada/ by Dmitriy Anisimkov + Support for Ada + See http://zlib-ada.sourceforge.net/ + +amd64/ by Mikhail Teterin + asm code for AMD64 + See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393 + +asm686/ by Brian Raiter + asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax + See http://www.muppetlabs.com/~breadbox/software/assembly.html + +blast/ by Mark Adler + Decompressor for output of PKWare Data Compression Library (DCL) + +delphi/ by Cosmin Truta + Support for Delphi and C++ Builder + +dotzlib/ by Henrik Ravn + Support for Microsoft .Net and Visual C++ .Net + +gcc_gvmat64/by Gilles Vollant + GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64 + assembler to replace longest_match() and inflate_fast() + +infback9/ by Mark Adler + Unsupported diffs to infback to decode the deflate64 format + +inflate86/ by Chris Anderson + Tuned x86 gcc asm code to replace inflate_fast() + +iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +iostream3/ by Ludwig Schwardt + and Kevin Ruland + Yet another C++ I/O streams interface + +masmx64/ by Gilles Vollant + x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to + replace longest_match() and inflate_fast(), also masm x86 + 64-bits translation of Chris Anderson inflate_fast() + +masmx86/ by Gilles Vollant + x86 asm code to replace longest_match() and inflate_fast(), + for Visual C++ and MASM (32 bits). + Based on Brian Raiter (asm686) and Chris Anderson (inflate86) + +minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + Includes Zip64 support by Mathias Svensson + See http://www.winimage.com/zLibDll/minizip.html + +pascal/ by Bob Dellaca et al. + Support for Pascal + +puff/ by Mark Adler + Small, low memory usage inflate. Also serves to provide an + unambiguous description of the deflate format. + +testzlib/ by Gilles Vollant + Example of the use of zlib + +untgz/ by Pedro A. Aranda Gutierrez + A very simple tar.gz file extractor using zlib + +vstudio/ by Gilles Vollant + Building a minizip-enhanced zlib with Microsoft Visual Studio + Includes vc11 from kreuzerkrieg and vc12 from davispuh diff --git a/src/external/zlib-1.2.11/contrib/ada/buffer_demo.adb b/src/external/zlib-1.2.11/contrib/ada/buffer_demo.adb new file mode 100644 index 000000000..46b863810 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/buffer_demo.adb @@ -0,0 +1,106 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- +-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $ + +-- This demo program provided by Dr Steve Sangwine +-- +-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer +-- of exactly the correct size is used for decompressed data, and the last +-- few bytes passed in to Zlib are checksum bytes. + +-- This program compresses a string of text, and then decompresses the +-- compressed text into a buffer of the same size as the original text. + +with Ada.Streams; use Ada.Streams; +with Ada.Text_IO; + +with ZLib; use ZLib; + +procedure Buffer_Demo is + EOL : Character renames ASCII.LF; + Text : constant String + := "Four score and seven years ago our fathers brought forth," & EOL & + "upon this continent, a new nation, conceived in liberty," & EOL & + "and dedicated to the proposition that `all men are created equal'."; + + Source : Stream_Element_Array (1 .. Text'Length); + for Source'Address use Text'Address; + +begin + Ada.Text_IO.Put (Text); + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes"); + + declare + Compressed_Data : Stream_Element_Array (1 .. Text'Length); + L : Stream_Element_Offset; + begin + Compress : declare + Compressor : Filter_Type; + I : Stream_Element_Offset; + begin + Deflate_Init (Compressor); + + -- Compress the whole of T at once. + + Translate (Compressor, Source, I, Compressed_Data, L, Finish); + pragma Assert (I = Source'Last); + + Close (Compressor); + + Ada.Text_IO.Put_Line + ("Compressed size : " + & Stream_Element_Offset'Image (L) & " bytes"); + end Compress; + + -- Now we decompress the data, passing short blocks of data to Zlib + -- (because this demonstrates the problem - the last block passed will + -- contain checksum information and there will be no output, only a + -- check inside Zlib that the checksum is correct). + + Decompress : declare + Decompressor : Filter_Type; + + Uncompressed_Data : Stream_Element_Array (1 .. Text'Length); + + Block_Size : constant := 4; + -- This makes sure that the last block contains + -- only Adler checksum data. + + P : Stream_Element_Offset := Compressed_Data'First - 1; + O : Stream_Element_Offset; + begin + Inflate_Init (Decompressor); + + loop + Translate + (Decompressor, + Compressed_Data + (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)), + P, + Uncompressed_Data + (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last), + O, + No_Flush); + + Ada.Text_IO.Put_Line + ("Total in : " & Count'Image (Total_In (Decompressor)) & + ", out : " & Count'Image (Total_Out (Decompressor))); + + exit when P = L; + end loop; + + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Decompressed text matches original text : " + & Boolean'Image (Uncompressed_Data = Source)); + end Decompress; + end; +end Buffer_Demo; diff --git a/src/external/zlib-1.2.11/contrib/ada/mtest.adb b/src/external/zlib-1.2.11/contrib/ada/mtest.adb new file mode 100644 index 000000000..c4dfd080f --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/mtest.adb @@ -0,0 +1,156 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- Continuous test for ZLib multithreading. If the test would fail +-- we should provide thread safe allocation routines for the Z_Stream. +-- +-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $ + +with ZLib; +with Ada.Streams; +with Ada.Numerics.Discrete_Random; +with Ada.Text_IO; +with Ada.Exceptions; +with Ada.Task_Identification; + +procedure MTest is + use Ada.Streams; + use ZLib; + + Stop : Boolean := False; + + pragma Atomic (Stop); + + subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is + new Ada.Numerics.Discrete_Random (Visible_Symbols); + + task type Test_Task; + + task body Test_Task is + Buffer : Stream_Element_Array (1 .. 100_000); + Gen : Random_Elements.Generator; + + Buffer_First : Stream_Element_Offset; + Compare_First : Stream_Element_Offset; + + Deflate : Filter_Type; + Inflate : Filter_Type; + + procedure Further (Item : in Stream_Element_Array); + + procedure Read_Buffer + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + + ------------- + -- Further -- + ------------- + + procedure Further (Item : in Stream_Element_Array) is + + procedure Compare (Item : in Stream_Element_Array); + + ------------- + -- Compare -- + ------------- + + procedure Compare (Item : in Stream_Element_Array) is + Next_First : Stream_Element_Offset := Compare_First + Item'Length; + begin + if Buffer (Compare_First .. Next_First - 1) /= Item then + raise Program_Error; + end if; + + Compare_First := Next_First; + end Compare; + + procedure Compare_Write is new ZLib.Write (Write => Compare); + begin + Compare_Write (Inflate, Item, No_Flush); + end Further; + + ----------------- + -- Read_Buffer -- + ----------------- + + procedure Read_Buffer + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset) + is + Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First; + Next_First : Stream_Element_Offset; + begin + if Item'Length <= Buff_Diff then + Last := Item'Last; + + Next_First := Buffer_First + Item'Length; + + Item := Buffer (Buffer_First .. Next_First - 1); + + Buffer_First := Next_First; + else + Last := Item'First + Buff_Diff; + Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last); + Buffer_First := Buffer'Last + 1; + end if; + end Read_Buffer; + + procedure Translate is new Generic_Translate + (Data_In => Read_Buffer, + Data_Out => Further); + + begin + Random_Elements.Reset (Gen); + + Buffer := (others => 20); + + Main : loop + for J in Buffer'Range loop + Buffer (J) := Random_Elements.Random (Gen); + + Deflate_Init (Deflate); + Inflate_Init (Inflate); + + Buffer_First := Buffer'First; + Compare_First := Buffer'First; + + Translate (Deflate); + + if Compare_First /= Buffer'Last + 1 then + raise Program_Error; + end if; + + Ada.Text_IO.Put_Line + (Ada.Task_Identification.Image + (Ada.Task_Identification.Current_Task) + & Stream_Element_Offset'Image (J) + & ZLib.Count'Image (Total_Out (Deflate))); + + Close (Deflate); + Close (Inflate); + + exit Main when Stop; + end loop; + end loop Main; + exception + when E : others => + Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E)); + Stop := True; + end Test_Task; + + Test : array (1 .. 4) of Test_Task; + + pragma Unreferenced (Test); + + Dummy : Character; + +begin + Ada.Text_IO.Get_Immediate (Dummy); + Stop := True; +end MTest; diff --git a/src/external/zlib-1.2.11/contrib/ada/read.adb b/src/external/zlib-1.2.11/contrib/ada/read.adb new file mode 100644 index 000000000..1f2efbfeb --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/read.adb @@ -0,0 +1,156 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $ + +-- Test/demo program for the generic read interface. + +with Ada.Numerics.Discrete_Random; +with Ada.Streams; +with Ada.Text_IO; + +with ZLib; + +procedure Read is + + use Ada.Streams; + + ------------------------------------ + -- Test configuration parameters -- + ------------------------------------ + + File_Size : Stream_Element_Offset := 100_000; + + Continuous : constant Boolean := False; + -- If this constant is True, the test would be repeated again and again, + -- with increment File_Size for every iteration. + + Header : constant ZLib.Header_Type := ZLib.Default; + -- Do not use Header other than Default in ZLib versions 1.1.4 and older. + + Init_Random : constant := 8; + -- We are using the same random sequence, in case of we catch bug, + -- so we would be able to reproduce it. + + -- End -- + + Pack_Size : Stream_Element_Offset; + Offset : Stream_Element_Offset; + + Filter : ZLib.Filter_Type; + + subtype Visible_Symbols + is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is new + Ada.Numerics.Discrete_Random (Visible_Symbols); + + Gen : Random_Elements.Generator; + Period : constant Stream_Element_Offset := 200; + -- Period constant variable for random generator not to be very random. + -- Bigger period, harder random. + + Read_Buffer : Stream_Element_Array (1 .. 2048); + Read_First : Stream_Element_Offset; + Read_Last : Stream_Element_Offset; + + procedure Reset; + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + -- this procedure is for generic instantiation of + -- ZLib.Read + -- reading data from the File_In. + + procedure Read is new ZLib.Read + (Read, + Read_Buffer, + Rest_First => Read_First, + Rest_Last => Read_Last); + + ---------- + -- Read -- + ---------- + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Last := Stream_Element_Offset'Min + (Item'Last, + Item'First + File_Size - Offset); + + for J in Item'First .. Last loop + if J < Item'First + Period then + Item (J) := Random_Elements.Random (Gen); + else + Item (J) := Item (J - Period); + end if; + + Offset := Offset + 1; + end loop; + end Read; + + ----------- + -- Reset -- + ----------- + + procedure Reset is + begin + Random_Elements.Reset (Gen, Init_Random); + Pack_Size := 0; + Offset := 1; + Read_First := Read_Buffer'Last + 1; + Read_Last := Read_Buffer'Last; + end Reset; + +begin + Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version); + + loop + for Level in ZLib.Compression_Level'Range loop + + Ada.Text_IO.Put ("Level =" + & ZLib.Compression_Level'Image (Level)); + + -- Deflate using generic instantiation. + + ZLib.Deflate_Init + (Filter, + Level, + Header => Header); + + Reset; + + Ada.Text_IO.Put + (Stream_Element_Offset'Image (File_Size) & " ->"); + + loop + declare + Buffer : Stream_Element_Array (1 .. 1024); + Last : Stream_Element_Offset; + begin + Read (Filter, Buffer, Last); + + Pack_Size := Pack_Size + Last - Buffer'First + 1; + + exit when Last < Buffer'Last; + end; + end loop; + + Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size)); + + ZLib.Close (Filter); + end loop; + + exit when not Continuous; + + File_Size := File_Size + 1; + end loop; +end Read; diff --git a/src/external/zlib-1.2.11/contrib/ada/readme.txt b/src/external/zlib-1.2.11/contrib/ada/readme.txt new file mode 100644 index 000000000..ce4d2cadf --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/readme.txt @@ -0,0 +1,65 @@ + ZLib for Ada thick binding (ZLib.Ada) + Release 1.3 + +ZLib.Ada is a thick binding interface to the popular ZLib data +compression library, available at http://www.gzip.org/zlib/. +It provides Ada-style access to the ZLib C library. + + + Here are the main changes since ZLib.Ada 1.2: + +- Attension: ZLib.Read generic routine have a initialization requirement + for Read_Last parameter now. It is a bit incompartible with previous version, + but extends functionality, we could use new parameters Allow_Read_Some and + Flush now. + +- Added Is_Open routines to ZLib and ZLib.Streams packages. + +- Add pragma Assert to check Stream_Element is 8 bit. + +- Fix extraction to buffer with exact known decompressed size. Error reported by + Steve Sangwine. + +- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits + computers. Patch provided by Pascal Obry. + +- Add Status_Error exception definition. + +- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit. + + + How to build ZLib.Ada under GNAT + +You should have the ZLib library already build on your computer, before +building ZLib.Ada. Make the directory of ZLib.Ada sources current and +issue the command: + + gnatmake test -largs -L -lz + +Or use the GNAT project file build for GNAT 3.15 or later: + + gnatmake -Pzlib.gpr -L + + + How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2 + +1. Make a project with all *.ads and *.adb files from the distribution. +2. Build the libz.a library from the ZLib C sources. +3. Rename libz.a to z.lib. +4. Add the library z.lib to the project. +5. Add the libc.lib library from the ObjectAda distribution to the project. +6. Build the executable using test.adb as a main procedure. + + + How to use ZLib.Ada + +The source files test.adb and read.adb are small demo programs that show +the main functionality of ZLib.Ada. + +The routines from the package specifications are commented. + + +Homepage: http://zlib-ada.sourceforge.net/ +Author: Dmitriy Anisimkov + +Contributors: Pascal Obry , Steve Sangwine diff --git a/src/external/zlib-1.2.11/contrib/ada/test.adb b/src/external/zlib-1.2.11/contrib/ada/test.adb new file mode 100644 index 000000000..90773acfa --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/test.adb @@ -0,0 +1,463 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $ + +-- The program has a few aims. +-- 1. Test ZLib.Ada95 thick binding functionality. +-- 2. Show the example of use main functionality of the ZLib.Ada95 binding. +-- 3. Build this program automatically compile all ZLib.Ada95 packages under +-- GNAT Ada95 compiler. + +with ZLib.Streams; +with Ada.Streams.Stream_IO; +with Ada.Numerics.Discrete_Random; + +with Ada.Text_IO; + +with Ada.Calendar; + +procedure Test is + + use Ada.Streams; + use Stream_IO; + + ------------------------------------ + -- Test configuration parameters -- + ------------------------------------ + + File_Size : Count := 100_000; + Continuous : constant Boolean := False; + + Header : constant ZLib.Header_Type := ZLib.Default; + -- ZLib.None; + -- ZLib.Auto; + -- ZLib.GZip; + -- Do not use Header other then Default in ZLib versions 1.1.4 + -- and older. + + Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy; + Init_Random : constant := 10; + + -- End -- + + In_File_Name : constant String := "testzlib.in"; + -- Name of the input file + + Z_File_Name : constant String := "testzlib.zlb"; + -- Name of the compressed file. + + Out_File_Name : constant String := "testzlib.out"; + -- Name of the decompressed file. + + File_In : File_Type; + File_Out : File_Type; + File_Back : File_Type; + File_Z : ZLib.Streams.Stream_Type; + + Filter : ZLib.Filter_Type; + + Time_Stamp : Ada.Calendar.Time; + + procedure Generate_File; + -- Generate file of spetsified size with some random data. + -- The random data is repeatable, for the good compression. + + procedure Compare_Streams + (Left, Right : in out Root_Stream_Type'Class); + -- The procedure compearing data in 2 streams. + -- It is for compare data before and after compression/decompression. + + procedure Compare_Files (Left, Right : String); + -- Compare files. Based on the Compare_Streams. + + procedure Copy_Streams + (Source, Target : in out Root_Stream_Type'Class; + Buffer_Size : in Stream_Element_Offset := 1024); + -- Copying data from one stream to another. It is for test stream + -- interface of the library. + + procedure Data_In + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + -- this procedure is for generic instantiation of + -- ZLib.Generic_Translate. + -- reading data from the File_In. + + procedure Data_Out (Item : in Stream_Element_Array); + -- this procedure is for generic instantiation of + -- ZLib.Generic_Translate. + -- writing data to the File_Out. + + procedure Stamp; + -- Store the timestamp to the local variable. + + procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count); + -- Print the time statistic with the message. + + procedure Translate is new ZLib.Generic_Translate + (Data_In => Data_In, + Data_Out => Data_Out); + -- This procedure is moving data from File_In to File_Out + -- with compression or decompression, depend on initialization of + -- Filter parameter. + + ------------------- + -- Compare_Files -- + ------------------- + + procedure Compare_Files (Left, Right : String) is + Left_File, Right_File : File_Type; + begin + Open (Left_File, In_File, Left); + Open (Right_File, In_File, Right); + Compare_Streams (Stream (Left_File).all, Stream (Right_File).all); + Close (Left_File); + Close (Right_File); + end Compare_Files; + + --------------------- + -- Compare_Streams -- + --------------------- + + procedure Compare_Streams + (Left, Right : in out Ada.Streams.Root_Stream_Type'Class) + is + Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#); + Left_Last, Right_Last : Stream_Element_Offset; + begin + loop + Read (Left, Left_Buffer, Left_Last); + Read (Right, Right_Buffer, Right_Last); + + if Left_Last /= Right_Last then + Ada.Text_IO.Put_Line ("Compare error :" + & Stream_Element_Offset'Image (Left_Last) + & " /= " + & Stream_Element_Offset'Image (Right_Last)); + + raise Constraint_Error; + + elsif Left_Buffer (0 .. Left_Last) + /= Right_Buffer (0 .. Right_Last) + then + Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal."); + raise Constraint_Error; + + end if; + + exit when Left_Last < Left_Buffer'Last; + end loop; + end Compare_Streams; + + ------------------ + -- Copy_Streams -- + ------------------ + + procedure Copy_Streams + (Source, Target : in out Ada.Streams.Root_Stream_Type'Class; + Buffer_Size : in Stream_Element_Offset := 1024) + is + Buffer : Stream_Element_Array (1 .. Buffer_Size); + Last : Stream_Element_Offset; + begin + loop + Read (Source, Buffer, Last); + Write (Target, Buffer (1 .. Last)); + + exit when Last < Buffer'Last; + end loop; + end Copy_Streams; + + ------------- + -- Data_In -- + ------------- + + procedure Data_In + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Read (File_In, Item, Last); + end Data_In; + + -------------- + -- Data_Out -- + -------------- + + procedure Data_Out (Item : in Stream_Element_Array) is + begin + Write (File_Out, Item); + end Data_Out; + + ------------------- + -- Generate_File -- + ------------------- + + procedure Generate_File is + subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is + new Ada.Numerics.Discrete_Random (Visible_Symbols); + + Gen : Random_Elements.Generator; + Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10; + + Buffer_Count : constant Count := File_Size / Buffer'Length; + -- Number of same buffers in the packet. + + Density : constant Count := 30; -- from 0 to Buffer'Length - 2; + + procedure Fill_Buffer (J, D : in Count); + -- Change the part of the buffer. + + ----------------- + -- Fill_Buffer -- + ----------------- + + procedure Fill_Buffer (J, D : in Count) is + begin + for K in 0 .. D loop + Buffer + (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1)) + := Random_Elements.Random (Gen); + + end loop; + end Fill_Buffer; + + begin + Random_Elements.Reset (Gen, Init_Random); + + Create (File_In, Out_File, In_File_Name); + + Fill_Buffer (1, Buffer'Length - 2); + + for J in 1 .. Buffer_Count loop + Write (File_In, Buffer); + + Fill_Buffer (J, Density); + end loop; + + -- fill remain size. + + Write + (File_In, + Buffer + (1 .. Stream_Element_Offset + (File_Size - Buffer'Length * Buffer_Count))); + + Flush (File_In); + Close (File_In); + end Generate_File; + + --------------------- + -- Print_Statistic -- + --------------------- + + procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is + use Ada.Calendar; + use Ada.Text_IO; + + package Count_IO is new Integer_IO (ZLib.Count); + + Curr_Dur : Duration := Clock - Time_Stamp; + begin + Put (Msg); + + Set_Col (20); + Ada.Text_IO.Put ("size ="); + + Count_IO.Put + (Data_Size, + Width => Stream_IO.Count'Image (File_Size)'Length); + + Put_Line (" duration =" & Duration'Image (Curr_Dur)); + end Print_Statistic; + + ----------- + -- Stamp -- + ----------- + + procedure Stamp is + begin + Time_Stamp := Ada.Calendar.Clock; + end Stamp; + +begin + Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version); + + loop + Generate_File; + + for Level in ZLib.Compression_Level'Range loop + + Ada.Text_IO.Put_Line ("Level =" + & ZLib.Compression_Level'Image (Level)); + + -- Test generic interface. + Open (File_In, In_File, In_File_Name); + Create (File_Out, Out_File, Z_File_Name); + + Stamp; + + -- Deflate using generic instantiation. + + ZLib.Deflate_Init + (Filter => Filter, + Level => Level, + Strategy => Strategy, + Header => Header); + + Translate (Filter); + Print_Statistic ("Generic compress", ZLib.Total_Out (Filter)); + ZLib.Close (Filter); + + Close (File_In); + Close (File_Out); + + Open (File_In, In_File, Z_File_Name); + Create (File_Out, Out_File, Out_File_Name); + + Stamp; + + -- Inflate using generic instantiation. + + ZLib.Inflate_Init (Filter, Header => Header); + + Translate (Filter); + Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter)); + + ZLib.Close (Filter); + + Close (File_In); + Close (File_Out); + + Compare_Files (In_File_Name, Out_File_Name); + + -- Test stream interface. + + -- Compress to the back stream. + + Open (File_In, In_File, In_File_Name); + Create (File_Back, Out_File, Z_File_Name); + + Stamp; + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.Out_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => True, + Level => Level, + Strategy => Strategy, + Header => Header); + + Copy_Streams + (Source => Stream (File_In).all, + Target => File_Z); + + -- Flushing internal buffers to the back stream. + + ZLib.Streams.Flush (File_Z, ZLib.Finish); + + Print_Statistic ("Write compress", + ZLib.Streams.Write_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + + Close (File_In); + Close (File_Back); + + -- Compare reading from original file and from + -- decompression stream. + + Open (File_In, In_File, In_File_Name); + Open (File_Back, In_File, Z_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.In_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => True, + Header => Header); + + Stamp; + Compare_Streams (Stream (File_In).all, File_Z); + + Print_Statistic ("Read decompress", + ZLib.Streams.Read_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + Close (File_In); + Close (File_Back); + + -- Compress by reading from compression stream. + + Open (File_Back, In_File, In_File_Name); + Create (File_Out, Out_File, Z_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.In_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => False, + Level => Level, + Strategy => Strategy, + Header => Header); + + Stamp; + Copy_Streams + (Source => File_Z, + Target => Stream (File_Out).all); + + Print_Statistic ("Read compress", + ZLib.Streams.Read_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + + Close (File_Out); + Close (File_Back); + + -- Decompress to decompression stream. + + Open (File_In, In_File, Z_File_Name); + Create (File_Back, Out_File, Out_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.Out_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => False, + Header => Header); + + Stamp; + + Copy_Streams + (Source => Stream (File_In).all, + Target => File_Z); + + Print_Statistic ("Write decompress", + ZLib.Streams.Write_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + Close (File_In); + Close (File_Back); + + Compare_Files (In_File_Name, Out_File_Name); + end loop; + + Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok."); + + exit when not Continuous; + + File_Size := File_Size + 1; + end loop; +end Test; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib-streams.adb b/src/external/zlib-1.2.11/contrib/ada/zlib-streams.adb new file mode 100644 index 000000000..b6497bae2 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib-streams.adb @@ -0,0 +1,225 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $ + +with Ada.Unchecked_Deallocation; + +package body ZLib.Streams is + + ----------- + -- Close -- + ----------- + + procedure Close (Stream : in out Stream_Type) is + procedure Free is new Ada.Unchecked_Deallocation + (Stream_Element_Array, Buffer_Access); + begin + if Stream.Mode = Out_Stream or Stream.Mode = Duplex then + -- We should flush the data written by the writer. + + Flush (Stream, Finish); + + Close (Stream.Writer); + end if; + + if Stream.Mode = In_Stream or Stream.Mode = Duplex then + Close (Stream.Reader); + Free (Stream.Buffer); + end if; + end Close; + + ------------ + -- Create -- + ------------ + + procedure Create + (Stream : out Stream_Type; + Mode : in Stream_Mode; + Back : in Stream_Access; + Back_Compressed : in Boolean; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Header : in Header_Type := Default; + Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size) + is + + subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size); + + procedure Init_Filter + (Filter : in out Filter_Type; + Compress : in Boolean); + + ----------------- + -- Init_Filter -- + ----------------- + + procedure Init_Filter + (Filter : in out Filter_Type; + Compress : in Boolean) is + begin + if Compress then + Deflate_Init + (Filter, Level, Strategy, Header => Header); + else + Inflate_Init (Filter, Header => Header); + end if; + end Init_Filter; + + begin + Stream.Back := Back; + Stream.Mode := Mode; + + if Mode = Out_Stream or Mode = Duplex then + Init_Filter (Stream.Writer, Back_Compressed); + Stream.Buffer_Size := Write_Buffer_Size; + else + Stream.Buffer_Size := 0; + end if; + + if Mode = In_Stream or Mode = Duplex then + Init_Filter (Stream.Reader, not Back_Compressed); + + Stream.Buffer := new Buffer_Subtype; + Stream.Rest_First := Stream.Buffer'Last + 1; + Stream.Rest_Last := Stream.Buffer'Last; + end if; + end Create; + + ----------- + -- Flush -- + ----------- + + procedure Flush + (Stream : in out Stream_Type; + Mode : in Flush_Mode := Sync_Flush) + is + Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size); + Last : Stream_Element_Offset; + begin + loop + Flush (Stream.Writer, Buffer, Last, Mode); + + Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last)); + + exit when Last < Buffer'Last; + end loop; + end Flush; + + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Stream : Stream_Type) return Boolean is + begin + return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer); + end Is_Open; + + ---------- + -- Read -- + ---------- + + procedure Read + (Stream : in out Stream_Type; + Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) + is + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + + ---------- + -- Read -- + ---------- + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Ada.Streams.Read (Stream.Back.all, Item, Last); + end Read; + + procedure Read is new ZLib.Read + (Read => Read, + Buffer => Stream.Buffer.all, + Rest_First => Stream.Rest_First, + Rest_Last => Stream.Rest_Last); + + begin + Read (Stream.Reader, Item, Last); + end Read; + + ------------------- + -- Read_Total_In -- + ------------------- + + function Read_Total_In (Stream : in Stream_Type) return Count is + begin + return Total_In (Stream.Reader); + end Read_Total_In; + + -------------------- + -- Read_Total_Out -- + -------------------- + + function Read_Total_Out (Stream : in Stream_Type) return Count is + begin + return Total_Out (Stream.Reader); + end Read_Total_Out; + + ----------- + -- Write -- + ----------- + + procedure Write + (Stream : in out Stream_Type; + Item : in Stream_Element_Array) + is + + procedure Write (Item : in Stream_Element_Array); + + ----------- + -- Write -- + ----------- + + procedure Write (Item : in Stream_Element_Array) is + begin + Ada.Streams.Write (Stream.Back.all, Item); + end Write; + + procedure Write is new ZLib.Write + (Write => Write, + Buffer_Size => Stream.Buffer_Size); + + begin + Write (Stream.Writer, Item, No_Flush); + end Write; + + -------------------- + -- Write_Total_In -- + -------------------- + + function Write_Total_In (Stream : in Stream_Type) return Count is + begin + return Total_In (Stream.Writer); + end Write_Total_In; + + --------------------- + -- Write_Total_Out -- + --------------------- + + function Write_Total_Out (Stream : in Stream_Type) return Count is + begin + return Total_Out (Stream.Writer); + end Write_Total_Out; + +end ZLib.Streams; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib-streams.ads b/src/external/zlib-1.2.11/contrib/ada/zlib-streams.ads new file mode 100644 index 000000000..8e26cd450 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib-streams.ads @@ -0,0 +1,114 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $ + +package ZLib.Streams is + + type Stream_Mode is (In_Stream, Out_Stream, Duplex); + + type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class; + + type Stream_Type is + new Ada.Streams.Root_Stream_Type with private; + + procedure Read + (Stream : in out Stream_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + + procedure Write + (Stream : in out Stream_Type; + Item : in Ada.Streams.Stream_Element_Array); + + procedure Flush + (Stream : in out Stream_Type; + Mode : in Flush_Mode := Sync_Flush); + -- Flush the written data to the back stream, + -- all data placed to the compressor is flushing to the Back stream. + -- Should not be used until necessary, because it is decreasing + -- compression. + + function Read_Total_In (Stream : in Stream_Type) return Count; + pragma Inline (Read_Total_In); + -- Return total number of bytes read from back stream so far. + + function Read_Total_Out (Stream : in Stream_Type) return Count; + pragma Inline (Read_Total_Out); + -- Return total number of bytes read so far. + + function Write_Total_In (Stream : in Stream_Type) return Count; + pragma Inline (Write_Total_In); + -- Return total number of bytes written so far. + + function Write_Total_Out (Stream : in Stream_Type) return Count; + pragma Inline (Write_Total_Out); + -- Return total number of bytes written to the back stream. + + procedure Create + (Stream : out Stream_Type; + Mode : in Stream_Mode; + Back : in Stream_Access; + Back_Compressed : in Boolean; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Header : in Header_Type := Default; + Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size); + -- Create the Comression/Decompression stream. + -- If mode is In_Stream then Write operation is disabled. + -- If mode is Out_Stream then Read operation is disabled. + + -- If Back_Compressed is true then + -- Data written to the Stream is compressing to the Back stream + -- and data read from the Stream is decompressed data from the Back stream. + + -- If Back_Compressed is false then + -- Data written to the Stream is decompressing to the Back stream + -- and data read from the Stream is compressed data from the Back stream. + + -- !!! When the Need_Header is False ZLib-Ada is using undocumented + -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers. + + function Is_Open (Stream : Stream_Type) return Boolean; + + procedure Close (Stream : in out Stream_Type); + +private + + use Ada.Streams; + + type Buffer_Access is access all Stream_Element_Array; + + type Stream_Type + is new Root_Stream_Type with + record + Mode : Stream_Mode; + + Buffer : Buffer_Access; + Rest_First : Stream_Element_Offset; + Rest_Last : Stream_Element_Offset; + -- Buffer for Read operation. + -- We need to have this buffer in the record + -- because not all read data from back stream + -- could be processed during the read operation. + + Buffer_Size : Stream_Element_Offset; + -- Buffer size for write operation. + -- We do not need to have this buffer + -- in the record because all data could be + -- processed in the write operation. + + Back : Stream_Access; + Reader : Filter_Type; + Writer : Filter_Type; + end record; + +end ZLib.Streams; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib-thin.adb b/src/external/zlib-1.2.11/contrib/ada/zlib-thin.adb new file mode 100644 index 000000000..0ca4a7120 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib-thin.adb @@ -0,0 +1,141 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $ + +package body ZLib.Thin is + + ZLIB_VERSION : constant Chars_Ptr := zlibVersion; + + Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit; + + -------------- + -- Avail_In -- + -------------- + + function Avail_In (Strm : in Z_Stream) return UInt is + begin + return Strm.Avail_In; + end Avail_In; + + --------------- + -- Avail_Out -- + --------------- + + function Avail_Out (Strm : in Z_Stream) return UInt is + begin + return Strm.Avail_Out; + end Avail_Out; + + ------------------ + -- Deflate_Init -- + ------------------ + + function Deflate_Init + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int) + return Int is + begin + return deflateInit2 + (strm, + level, + method, + windowBits, + memLevel, + strategy, + ZLIB_VERSION, + Z_Stream_Size); + end Deflate_Init; + + ------------------ + -- Inflate_Init -- + ------------------ + + function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is + begin + return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size); + end Inflate_Init; + + ------------------------ + -- Last_Error_Message -- + ------------------------ + + function Last_Error_Message (Strm : in Z_Stream) return String is + use Interfaces.C.Strings; + begin + if Strm.msg = Null_Ptr then + return ""; + else + return Value (Strm.msg); + end if; + end Last_Error_Message; + + ------------ + -- Set_In -- + ------------ + + procedure Set_In + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt) is + begin + Strm.Next_In := Buffer; + Strm.Avail_In := Size; + end Set_In; + + ------------------ + -- Set_Mem_Func -- + ------------------ + + procedure Set_Mem_Func + (Strm : in out Z_Stream; + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func) is + begin + Strm.opaque := Opaque; + Strm.zalloc := Alloc; + Strm.zfree := Free; + end Set_Mem_Func; + + ------------- + -- Set_Out -- + ------------- + + procedure Set_Out + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt) is + begin + Strm.Next_Out := Buffer; + Strm.Avail_Out := Size; + end Set_Out; + + -------------- + -- Total_In -- + -------------- + + function Total_In (Strm : in Z_Stream) return ULong is + begin + return Strm.Total_In; + end Total_In; + + --------------- + -- Total_Out -- + --------------- + + function Total_Out (Strm : in Z_Stream) return ULong is + begin + return Strm.Total_Out; + end Total_Out; + +end ZLib.Thin; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib-thin.ads b/src/external/zlib-1.2.11/contrib/ada/zlib-thin.ads new file mode 100644 index 000000000..810173cff --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib-thin.ads @@ -0,0 +1,450 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $ + +with Interfaces.C.Strings; + +with System; + +private package ZLib.Thin is + + -- From zconf.h + + MAX_MEM_LEVEL : constant := 9; -- zconf.h:105 + -- zconf.h:105 + MAX_WBITS : constant := 15; -- zconf.h:115 + -- 32K LZ77 window + -- zconf.h:115 + SEEK_SET : constant := 8#0000#; -- zconf.h:244 + -- Seek from beginning of file. + -- zconf.h:244 + SEEK_CUR : constant := 1; -- zconf.h:245 + -- Seek from current position. + -- zconf.h:245 + SEEK_END : constant := 2; -- zconf.h:246 + -- Set file pointer to EOF plus "offset" + -- zconf.h:246 + + type Byte is new Interfaces.C.unsigned_char; -- 8 bits + -- zconf.h:214 + type UInt is new Interfaces.C.unsigned; -- 16 bits or more + -- zconf.h:216 + type Int is new Interfaces.C.int; + + type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more + -- zconf.h:217 + subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr; + + type ULong_Access is access ULong; + type Int_Access is access Int; + + subtype Voidp is System.Address; -- zconf.h:232 + + subtype Byte_Access is Voidp; + + Nul : constant Voidp := System.Null_Address; + -- end from zconf + + Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125 + -- zlib.h:125 + Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126 + -- will be removed, use + -- Z_SYNC_FLUSH instead + -- zlib.h:126 + Z_SYNC_FLUSH : constant := 2; -- zlib.h:127 + -- zlib.h:127 + Z_FULL_FLUSH : constant := 3; -- zlib.h:128 + -- zlib.h:128 + Z_FINISH : constant := 4; -- zlib.h:129 + -- zlib.h:129 + Z_OK : constant := 8#0000#; -- zlib.h:132 + -- zlib.h:132 + Z_STREAM_END : constant := 1; -- zlib.h:133 + -- zlib.h:133 + Z_NEED_DICT : constant := 2; -- zlib.h:134 + -- zlib.h:134 + Z_ERRNO : constant := -1; -- zlib.h:135 + -- zlib.h:135 + Z_STREAM_ERROR : constant := -2; -- zlib.h:136 + -- zlib.h:136 + Z_DATA_ERROR : constant := -3; -- zlib.h:137 + -- zlib.h:137 + Z_MEM_ERROR : constant := -4; -- zlib.h:138 + -- zlib.h:138 + Z_BUF_ERROR : constant := -5; -- zlib.h:139 + -- zlib.h:139 + Z_VERSION_ERROR : constant := -6; -- zlib.h:140 + -- zlib.h:140 + Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145 + -- zlib.h:145 + Z_BEST_SPEED : constant := 1; -- zlib.h:146 + -- zlib.h:146 + Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147 + -- zlib.h:147 + Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148 + -- zlib.h:148 + Z_FILTERED : constant := 1; -- zlib.h:151 + -- zlib.h:151 + Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152 + -- zlib.h:152 + Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153 + -- zlib.h:153 + Z_BINARY : constant := 8#0000#; -- zlib.h:156 + -- zlib.h:156 + Z_ASCII : constant := 1; -- zlib.h:157 + -- zlib.h:157 + Z_UNKNOWN : constant := 2; -- zlib.h:158 + -- zlib.h:158 + Z_DEFLATED : constant := 8; -- zlib.h:161 + -- zlib.h:161 + Z_NULL : constant := 8#0000#; -- zlib.h:164 + -- for initializing zalloc, zfree, opaque + -- zlib.h:164 + type gzFile is new Voidp; -- zlib.h:646 + + type Z_Stream is private; + + type Z_Streamp is access all Z_Stream; -- zlib.h:89 + + type alloc_func is access function + (Opaque : Voidp; + Items : UInt; + Size : UInt) + return Voidp; -- zlib.h:63 + + type free_func is access procedure (opaque : Voidp; address : Voidp); + + function zlibVersion return Chars_Ptr; + + function Deflate (strm : Z_Streamp; flush : Int) return Int; + + function DeflateEnd (strm : Z_Streamp) return Int; + + function Inflate (strm : Z_Streamp; flush : Int) return Int; + + function InflateEnd (strm : Z_Streamp) return Int; + + function deflateSetDictionary + (strm : Z_Streamp; + dictionary : Byte_Access; + dictLength : UInt) + return Int; + + function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int; + -- zlib.h:478 + + function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495 + + function deflateParams + (strm : Z_Streamp; + level : Int; + strategy : Int) + return Int; -- zlib.h:506 + + function inflateSetDictionary + (strm : Z_Streamp; + dictionary : Byte_Access; + dictLength : UInt) + return Int; -- zlib.h:548 + + function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565 + + function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580 + + function compress + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong) + return Int; -- zlib.h:601 + + function compress2 + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong; + level : Int) + return Int; -- zlib.h:615 + + function uncompress + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong) + return Int; + + function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile; + + function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile; + + function gzsetparams + (file : gzFile; + level : Int; + strategy : Int) + return Int; + + function gzread + (file : gzFile; + buf : Voidp; + len : UInt) + return Int; + + function gzwrite + (file : in gzFile; + buf : in Voidp; + len : in UInt) + return Int; + + function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int; + + function gzputs (file : in gzFile; s : in Chars_Ptr) return Int; + + function gzgets + (file : gzFile; + buf : Chars_Ptr; + len : Int) + return Chars_Ptr; + + function gzputc (file : gzFile; char : Int) return Int; + + function gzgetc (file : gzFile) return Int; + + function gzflush (file : gzFile; flush : Int) return Int; + + function gzseek + (file : gzFile; + offset : Int; + whence : Int) + return Int; + + function gzrewind (file : gzFile) return Int; + + function gztell (file : gzFile) return Int; + + function gzeof (file : gzFile) return Int; + + function gzclose (file : gzFile) return Int; + + function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr; + + function adler32 + (adler : ULong; + buf : Byte_Access; + len : UInt) + return ULong; + + function crc32 + (crc : ULong; + buf : Byte_Access; + len : UInt) + return ULong; + + function deflateInit + (strm : Z_Streamp; + level : Int; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function deflateInit2 + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function Deflate_Init + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int) + return Int; + pragma Inline (Deflate_Init); + + function inflateInit + (strm : Z_Streamp; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function inflateInit2 + (strm : in Z_Streamp; + windowBits : in Int; + version : in Chars_Ptr; + stream_size : in Int) + return Int; + + function inflateBackInit + (strm : in Z_Streamp; + windowBits : in Int; + window : in Byte_Access; + version : in Chars_Ptr; + stream_size : in Int) + return Int; + -- Size of window have to be 2**windowBits. + + function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int; + pragma Inline (Inflate_Init); + + function zError (err : Int) return Chars_Ptr; + + function inflateSyncPoint (z : Z_Streamp) return Int; + + function get_crc_table return ULong_Access; + + -- Interface to the available fields of the z_stream structure. + -- The application must update next_in and avail_in when avail_in has + -- dropped to zero. It must update next_out and avail_out when avail_out + -- has dropped to zero. The application must initialize zalloc, zfree and + -- opaque before calling the init function. + + procedure Set_In + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt); + pragma Inline (Set_In); + + procedure Set_Out + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt); + pragma Inline (Set_Out); + + procedure Set_Mem_Func + (Strm : in out Z_Stream; + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func); + pragma Inline (Set_Mem_Func); + + function Last_Error_Message (Strm : in Z_Stream) return String; + pragma Inline (Last_Error_Message); + + function Avail_Out (Strm : in Z_Stream) return UInt; + pragma Inline (Avail_Out); + + function Avail_In (Strm : in Z_Stream) return UInt; + pragma Inline (Avail_In); + + function Total_In (Strm : in Z_Stream) return ULong; + pragma Inline (Total_In); + + function Total_Out (Strm : in Z_Stream) return ULong; + pragma Inline (Total_Out); + + function inflateCopy + (dest : in Z_Streamp; + Source : in Z_Streamp) + return Int; + + function compressBound (Source_Len : in ULong) return ULong; + + function deflateBound + (Strm : in Z_Streamp; + Source_Len : in ULong) + return ULong; + + function gzungetc (C : in Int; File : in gzFile) return Int; + + function zlibCompileFlags return ULong; + +private + + type Z_Stream is record -- zlib.h:68 + Next_In : Voidp := Nul; -- next input byte + Avail_In : UInt := 0; -- number of bytes available at next_in + Total_In : ULong := 0; -- total nb of input bytes read so far + Next_Out : Voidp := Nul; -- next output byte should be put there + Avail_Out : UInt := 0; -- remaining free space at next_out + Total_Out : ULong := 0; -- total nb of bytes output so far + msg : Chars_Ptr; -- last error message, NULL if no error + state : Voidp; -- not visible by applications + zalloc : alloc_func := null; -- used to allocate the internal state + zfree : free_func := null; -- used to free the internal state + opaque : Voidp; -- private data object passed to + -- zalloc and zfree + data_type : Int; -- best guess about the data type: + -- ascii or binary + adler : ULong; -- adler32 value of the uncompressed + -- data + reserved : ULong; -- reserved for future use + end record; + + pragma Convention (C, Z_Stream); + + pragma Import (C, zlibVersion, "zlibVersion"); + pragma Import (C, Deflate, "deflate"); + pragma Import (C, DeflateEnd, "deflateEnd"); + pragma Import (C, Inflate, "inflate"); + pragma Import (C, InflateEnd, "inflateEnd"); + pragma Import (C, deflateSetDictionary, "deflateSetDictionary"); + pragma Import (C, deflateCopy, "deflateCopy"); + pragma Import (C, deflateReset, "deflateReset"); + pragma Import (C, deflateParams, "deflateParams"); + pragma Import (C, inflateSetDictionary, "inflateSetDictionary"); + pragma Import (C, inflateSync, "inflateSync"); + pragma Import (C, inflateReset, "inflateReset"); + pragma Import (C, compress, "compress"); + pragma Import (C, compress2, "compress2"); + pragma Import (C, uncompress, "uncompress"); + pragma Import (C, gzopen, "gzopen"); + pragma Import (C, gzdopen, "gzdopen"); + pragma Import (C, gzsetparams, "gzsetparams"); + pragma Import (C, gzread, "gzread"); + pragma Import (C, gzwrite, "gzwrite"); + pragma Import (C, gzprintf, "gzprintf"); + pragma Import (C, gzputs, "gzputs"); + pragma Import (C, gzgets, "gzgets"); + pragma Import (C, gzputc, "gzputc"); + pragma Import (C, gzgetc, "gzgetc"); + pragma Import (C, gzflush, "gzflush"); + pragma Import (C, gzseek, "gzseek"); + pragma Import (C, gzrewind, "gzrewind"); + pragma Import (C, gztell, "gztell"); + pragma Import (C, gzeof, "gzeof"); + pragma Import (C, gzclose, "gzclose"); + pragma Import (C, gzerror, "gzerror"); + pragma Import (C, adler32, "adler32"); + pragma Import (C, crc32, "crc32"); + pragma Import (C, deflateInit, "deflateInit_"); + pragma Import (C, inflateInit, "inflateInit_"); + pragma Import (C, deflateInit2, "deflateInit2_"); + pragma Import (C, inflateInit2, "inflateInit2_"); + pragma Import (C, zError, "zError"); + pragma Import (C, inflateSyncPoint, "inflateSyncPoint"); + pragma Import (C, get_crc_table, "get_crc_table"); + + -- since zlib 1.2.0: + + pragma Import (C, inflateCopy, "inflateCopy"); + pragma Import (C, compressBound, "compressBound"); + pragma Import (C, deflateBound, "deflateBound"); + pragma Import (C, gzungetc, "gzungetc"); + pragma Import (C, zlibCompileFlags, "zlibCompileFlags"); + + pragma Import (C, inflateBackInit, "inflateBackInit_"); + + -- I stopped binding the inflateBack routines, because realize that + -- it does not support zlib and gzip headers for now, and have no + -- symmetric deflateBack routines. + -- ZLib-Ada is symmetric regarding deflate/inflate data transformation + -- and has a similar generic callback interface for the + -- deflate/inflate transformation based on the regular Deflate/Inflate + -- routines. + + -- pragma Import (C, inflateBack, "inflateBack"); + -- pragma Import (C, inflateBackEnd, "inflateBackEnd"); + +end ZLib.Thin; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib.adb b/src/external/zlib-1.2.11/contrib/ada/zlib.adb new file mode 100644 index 000000000..8b6fd686a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib.adb @@ -0,0 +1,701 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $ + +with Ada.Exceptions; +with Ada.Unchecked_Conversion; +with Ada.Unchecked_Deallocation; + +with Interfaces.C.Strings; + +with ZLib.Thin; + +package body ZLib is + + use type Thin.Int; + + type Z_Stream is new Thin.Z_Stream; + + type Return_Code_Enum is + (OK, + STREAM_END, + NEED_DICT, + ERRNO, + STREAM_ERROR, + DATA_ERROR, + MEM_ERROR, + BUF_ERROR, + VERSION_ERROR); + + type Flate_Step_Function is access + function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int; + pragma Convention (C, Flate_Step_Function); + + type Flate_End_Function is access + function (Ctrm : in Thin.Z_Streamp) return Thin.Int; + pragma Convention (C, Flate_End_Function); + + type Flate_Type is record + Step : Flate_Step_Function; + Done : Flate_End_Function; + end record; + + subtype Footer_Array is Stream_Element_Array (1 .. 8); + + Simple_GZip_Header : constant Stream_Element_Array (1 .. 10) + := (16#1f#, 16#8b#, -- Magic header + 16#08#, -- Z_DEFLATED + 16#00#, -- Flags + 16#00#, 16#00#, 16#00#, 16#00#, -- Time + 16#00#, -- XFlags + 16#03# -- OS code + ); + -- The simplest gzip header is not for informational, but just for + -- gzip format compatibility. + -- Note that some code below is using assumption + -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make + -- Simple_GZip_Header'Last <= Footer_Array'Last. + + Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum + := (0 => OK, + 1 => STREAM_END, + 2 => NEED_DICT, + -1 => ERRNO, + -2 => STREAM_ERROR, + -3 => DATA_ERROR, + -4 => MEM_ERROR, + -5 => BUF_ERROR, + -6 => VERSION_ERROR); + + Flate : constant array (Boolean) of Flate_Type + := (True => (Step => Thin.Deflate'Access, + Done => Thin.DeflateEnd'Access), + False => (Step => Thin.Inflate'Access, + Done => Thin.InflateEnd'Access)); + + Flush_Finish : constant array (Boolean) of Flush_Mode + := (True => Finish, False => No_Flush); + + procedure Raise_Error (Stream : in Z_Stream); + pragma Inline (Raise_Error); + + procedure Raise_Error (Message : in String); + pragma Inline (Raise_Error); + + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int); + + procedure Free is new Ada.Unchecked_Deallocation + (Z_Stream, Z_Stream_Access); + + function To_Thin_Access is new Ada.Unchecked_Conversion + (Z_Stream_Access, Thin.Z_Streamp); + + procedure Translate_GZip + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- Separate translate routine for make gzip header. + + procedure Translate_Auto + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- translate routine without additional headers. + + ----------------- + -- Check_Error -- + ----------------- + + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is + use type Thin.Int; + begin + if Code /= Thin.Z_OK then + Raise_Error + (Return_Code_Enum'Image (Return_Code (Code)) + & ": " & Last_Error_Message (Stream)); + end if; + end Check_Error; + + ----------- + -- Close -- + ----------- + + procedure Close + (Filter : in out Filter_Type; + Ignore_Error : in Boolean := False) + is + Code : Thin.Int; + begin + if not Ignore_Error and then not Is_Open (Filter) then + raise Status_Error; + end if; + + Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm)); + + if Ignore_Error or else Code = Thin.Z_OK then + Free (Filter.Strm); + else + declare + Error_Message : constant String + := Last_Error_Message (Filter.Strm.all); + begin + Free (Filter.Strm); + Ada.Exceptions.Raise_Exception + (ZLib_Error'Identity, + Return_Code_Enum'Image (Return_Code (Code)) + & ": " & Error_Message); + end; + end if; + end Close; + + ----------- + -- CRC32 -- + ----------- + + function CRC32 + (CRC : in Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) + return Unsigned_32 + is + use Thin; + begin + return Unsigned_32 (crc32 (ULong (CRC), + Data'Address, + Data'Length)); + end CRC32; + + procedure CRC32 + (CRC : in out Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) is + begin + CRC := CRC32 (CRC, Data); + end CRC32; + + ------------------ + -- Deflate_Init -- + ------------------ + + procedure Deflate_Init + (Filter : in out Filter_Type; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Method : in Compression_Method := Deflated; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; + Header : in Header_Type := Default) + is + use type Thin.Int; + Win_Bits : Thin.Int := Thin.Int (Window_Bits); + begin + if Is_Open (Filter) then + raise Status_Error; + end if; + + -- We allow ZLib to make header only in case of default header type. + -- Otherwise we would either do header by ourselfs, or do not do + -- header at all. + + if Header = None or else Header = GZip then + Win_Bits := -Win_Bits; + end if; + + -- For the GZip CRC calculation and make headers. + + if Header = GZip then + Filter.CRC := 0; + Filter.Offset := Simple_GZip_Header'First; + else + Filter.Offset := Simple_GZip_Header'Last + 1; + end if; + + Filter.Strm := new Z_Stream; + Filter.Compression := True; + Filter.Stream_End := False; + Filter.Header := Header; + + if Thin.Deflate_Init + (To_Thin_Access (Filter.Strm), + Level => Thin.Int (Level), + method => Thin.Int (Method), + windowBits => Win_Bits, + memLevel => Thin.Int (Memory_Level), + strategy => Thin.Int (Strategy)) /= Thin.Z_OK + then + Raise_Error (Filter.Strm.all); + end if; + end Deflate_Init; + + ----------- + -- Flush -- + ----------- + + procedure Flush + (Filter : in out Filter_Type; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + No_Data : Stream_Element_Array := (1 .. 0 => 0); + Last : Stream_Element_Offset; + begin + Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush); + end Flush; + + ----------------------- + -- Generic_Translate -- + ----------------------- + + procedure Generic_Translate + (Filter : in out ZLib.Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size) + is + In_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (In_Buffer_Size)); + Out_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (Out_Buffer_Size)); + Last : Stream_Element_Offset; + In_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; + begin + Main : loop + Data_In (In_Buffer, Last); + + In_First := In_Buffer'First; + + loop + Translate + (Filter => Filter, + In_Data => In_Buffer (In_First .. Last), + In_Last => In_Last, + Out_Data => Out_Buffer, + Out_Last => Out_Last, + Flush => Flush_Finish (Last < In_Buffer'First)); + + if Out_Buffer'First <= Out_Last then + Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); + end if; + + exit Main when Stream_End (Filter); + + -- The end of in buffer. + + exit when In_Last = Last; + + In_First := In_Last + 1; + end loop; + end loop Main; + + end Generic_Translate; + + ------------------ + -- Inflate_Init -- + ------------------ + + procedure Inflate_Init + (Filter : in out Filter_Type; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Header : in Header_Type := Default) + is + use type Thin.Int; + Win_Bits : Thin.Int := Thin.Int (Window_Bits); + + procedure Check_Version; + -- Check the latest header types compatibility. + + procedure Check_Version is + begin + if Version <= "1.1.4" then + Raise_Error + ("Inflate header type " & Header_Type'Image (Header) + & " incompatible with ZLib version " & Version); + end if; + end Check_Version; + + begin + if Is_Open (Filter) then + raise Status_Error; + end if; + + case Header is + when None => + Check_Version; + + -- Inflate data without headers determined + -- by negative Win_Bits. + + Win_Bits := -Win_Bits; + when GZip => + Check_Version; + + -- Inflate gzip data defined by flag 16. + + Win_Bits := Win_Bits + 16; + when Auto => + Check_Version; + + -- Inflate with automatic detection + -- of gzip or native header defined by flag 32. + + Win_Bits := Win_Bits + 32; + when Default => null; + end case; + + Filter.Strm := new Z_Stream; + Filter.Compression := False; + Filter.Stream_End := False; + Filter.Header := Header; + + if Thin.Inflate_Init + (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK + then + Raise_Error (Filter.Strm.all); + end if; + end Inflate_Init; + + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Filter : in Filter_Type) return Boolean is + begin + return Filter.Strm /= null; + end Is_Open; + + ----------------- + -- Raise_Error -- + ----------------- + + procedure Raise_Error (Message : in String) is + begin + Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message); + end Raise_Error; + + procedure Raise_Error (Stream : in Z_Stream) is + begin + Raise_Error (Last_Error_Message (Stream)); + end Raise_Error; + + ---------- + -- Read -- + ---------- + + procedure Read + (Filter : in out Filter_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush) + is + In_Last : Stream_Element_Offset; + Item_First : Ada.Streams.Stream_Element_Offset := Item'First; + V_Flush : Flush_Mode := Flush; + + begin + pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1); + pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); + + loop + if Rest_Last = Buffer'First - 1 then + V_Flush := Finish; + + elsif Rest_First > Rest_Last then + Read (Buffer, Rest_Last); + Rest_First := Buffer'First; + + if Rest_Last < Buffer'First then + V_Flush := Finish; + end if; + end if; + + Translate + (Filter => Filter, + In_Data => Buffer (Rest_First .. Rest_Last), + In_Last => In_Last, + Out_Data => Item (Item_First .. Item'Last), + Out_Last => Last, + Flush => V_Flush); + + Rest_First := In_Last + 1; + + exit when Stream_End (Filter) + or else Last = Item'Last + or else (Last >= Item'First and then Allow_Read_Some); + + Item_First := Last + 1; + end loop; + end Read; + + ---------------- + -- Stream_End -- + ---------------- + + function Stream_End (Filter : in Filter_Type) return Boolean is + begin + if Filter.Header = GZip and Filter.Compression then + return Filter.Stream_End + and then Filter.Offset = Footer_Array'Last + 1; + else + return Filter.Stream_End; + end if; + end Stream_End; + + -------------- + -- Total_In -- + -------------- + + function Total_In (Filter : in Filter_Type) return Count is + begin + return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all)); + end Total_In; + + --------------- + -- Total_Out -- + --------------- + + function Total_Out (Filter : in Filter_Type) return Count is + begin + return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all)); + end Total_Out; + + --------------- + -- Translate -- + --------------- + + procedure Translate + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) is + begin + if Filter.Header = GZip and then Filter.Compression then + Translate_GZip + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data, + Out_Last => Out_Last, + Flush => Flush); + else + Translate_Auto + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data, + Out_Last => Out_Last, + Flush => Flush); + end if; + end Translate; + + -------------------- + -- Translate_Auto -- + -------------------- + + procedure Translate_Auto + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + use type Thin.Int; + Code : Thin.Int; + + begin + if not Is_Open (Filter) then + raise Status_Error; + end if; + + if Out_Data'Length = 0 and then In_Data'Length = 0 then + raise Constraint_Error; + end if; + + Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length); + Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length); + + Code := Flate (Filter.Compression).Step + (To_Thin_Access (Filter.Strm), + Thin.Int (Flush)); + + if Code = Thin.Z_STREAM_END then + Filter.Stream_End := True; + else + Check_Error (Filter.Strm.all, Code); + end if; + + In_Last := In_Data'Last + - Stream_Element_Offset (Avail_In (Filter.Strm.all)); + Out_Last := Out_Data'Last + - Stream_Element_Offset (Avail_Out (Filter.Strm.all)); + end Translate_Auto; + + -------------------- + -- Translate_GZip -- + -------------------- + + procedure Translate_GZip + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + Out_First : Stream_Element_Offset; + + procedure Add_Data (Data : in Stream_Element_Array); + -- Add data to stream from the Filter.Offset till necessary, + -- used for add gzip headr/footer. + + procedure Put_32 + (Item : in out Stream_Element_Array; + Data : in Unsigned_32); + pragma Inline (Put_32); + + -------------- + -- Add_Data -- + -------------- + + procedure Add_Data (Data : in Stream_Element_Array) is + Data_First : Stream_Element_Offset renames Filter.Offset; + Data_Last : Stream_Element_Offset; + Data_Len : Stream_Element_Offset; -- -1 + Out_Len : Stream_Element_Offset; -- -1 + begin + Out_First := Out_Last + 1; + + if Data_First > Data'Last then + return; + end if; + + Data_Len := Data'Last - Data_First; + Out_Len := Out_Data'Last - Out_First; + + if Data_Len <= Out_Len then + Out_Last := Out_First + Data_Len; + Data_Last := Data'Last; + else + Out_Last := Out_Data'Last; + Data_Last := Data_First + Out_Len; + end if; + + Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last); + + Data_First := Data_Last + 1; + Out_First := Out_Last + 1; + end Add_Data; + + ------------ + -- Put_32 -- + ------------ + + procedure Put_32 + (Item : in out Stream_Element_Array; + Data : in Unsigned_32) + is + D : Unsigned_32 := Data; + begin + for J in Item'First .. Item'First + 3 loop + Item (J) := Stream_Element (D and 16#FF#); + D := Shift_Right (D, 8); + end loop; + end Put_32; + + begin + Out_Last := Out_Data'First - 1; + + if not Filter.Stream_End then + Add_Data (Simple_GZip_Header); + + Translate_Auto + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data (Out_First .. Out_Data'Last), + Out_Last => Out_Last, + Flush => Flush); + + CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last)); + end if; + + if Filter.Stream_End and then Out_Last <= Out_Data'Last then + -- This detection method would work only when + -- Simple_GZip_Header'Last > Footer_Array'Last + + if Filter.Offset = Simple_GZip_Header'Last + 1 then + Filter.Offset := Footer_Array'First; + end if; + + declare + Footer : Footer_Array; + begin + Put_32 (Footer, Filter.CRC); + Put_32 (Footer (Footer'First + 4 .. Footer'Last), + Unsigned_32 (Total_In (Filter))); + Add_Data (Footer); + end; + end if; + end Translate_GZip; + + ------------- + -- Version -- + ------------- + + function Version return String is + begin + return Interfaces.C.Strings.Value (Thin.zlibVersion); + end Version; + + ----------- + -- Write -- + ----------- + + procedure Write + (Filter : in out Filter_Type; + Item : in Ada.Streams.Stream_Element_Array; + Flush : in Flush_Mode := No_Flush) + is + Buffer : Stream_Element_Array (1 .. Buffer_Size); + In_Last : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset := Item'First; + begin + if Item'Length = 0 and Flush = No_Flush then + return; + end if; + + loop + Translate + (Filter => Filter, + In_Data => Item (In_First .. Item'Last), + In_Last => In_Last, + Out_Data => Buffer, + Out_Last => Out_Last, + Flush => Flush); + + if Out_Last >= Buffer'First then + Write (Buffer (1 .. Out_Last)); + end if; + + exit when In_Last = Item'Last or Stream_End (Filter); + + In_First := In_Last + 1; + end loop; + end Write; + +end ZLib; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib.ads b/src/external/zlib-1.2.11/contrib/ada/zlib.ads new file mode 100644 index 000000000..79ffc4095 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib.ads @@ -0,0 +1,328 @@ +------------------------------------------------------------------------------ +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- This library is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published by -- +-- the Free Software Foundation; either version 2 of the License, or (at -- +-- your option) any later version. -- +-- -- +-- This library is distributed in the hope that it will be useful, but -- +-- WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- +-- General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this library; if not, write to the Free Software Foundation, -- +-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- +-- -- +-- As a special exception, if other files instantiate generics from this -- +-- unit, or you link this unit with other files to produce an executable, -- +-- this unit does not by itself cause the resulting executable to be -- +-- covered by the GNU General Public License. This exception does not -- +-- however invalidate any other reasons why the executable file might be -- +-- covered by the GNU Public License. -- +------------------------------------------------------------------------------ + +-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $ + +with Ada.Streams; + +with Interfaces; + +package ZLib is + + ZLib_Error : exception; + Status_Error : exception; + + type Compression_Level is new Integer range -1 .. 9; + + type Flush_Mode is private; + + type Compression_Method is private; + + type Window_Bits_Type is new Integer range 8 .. 15; + + type Memory_Level_Type is new Integer range 1 .. 9; + + type Unsigned_32 is new Interfaces.Unsigned_32; + + type Strategy_Type is private; + + type Header_Type is (None, Auto, Default, GZip); + -- Header type usage have a some limitation for inflate. + -- See comment for Inflate_Init. + + subtype Count is Ada.Streams.Stream_Element_Count; + + Default_Memory_Level : constant Memory_Level_Type := 8; + Default_Window_Bits : constant Window_Bits_Type := 15; + + ---------------------------------- + -- Compression method constants -- + ---------------------------------- + + Deflated : constant Compression_Method; + -- Only one method allowed in this ZLib version + + --------------------------------- + -- Compression level constants -- + --------------------------------- + + No_Compression : constant Compression_Level := 0; + Best_Speed : constant Compression_Level := 1; + Best_Compression : constant Compression_Level := 9; + Default_Compression : constant Compression_Level := -1; + + -------------------------- + -- Flush mode constants -- + -------------------------- + + No_Flush : constant Flush_Mode; + -- Regular way for compression, no flush + + Partial_Flush : constant Flush_Mode; + -- Will be removed, use Z_SYNC_FLUSH instead + + Sync_Flush : constant Flush_Mode; + -- All pending output is flushed to the output buffer and the output + -- is aligned on a byte boundary, so that the decompressor can get all + -- input data available so far. (In particular avail_in is zero after the + -- call if enough output space has been provided before the call.) + -- Flushing may degrade compression for some compression algorithms and so + -- it should be used only when necessary. + + Block_Flush : constant Flush_Mode; + -- Z_BLOCK requests that inflate() stop + -- if and when it get to the next deflate block boundary. When decoding the + -- zlib or gzip format, this will cause inflate() to return immediately + -- after the header and before the first block. When doing a raw inflate, + -- inflate() will go ahead and process the first block, and will return + -- when it gets to the end of that block, or when it runs out of data. + + Full_Flush : constant Flush_Mode; + -- All output is flushed as with SYNC_FLUSH, and the compression state + -- is reset so that decompression can restart from this point if previous + -- compressed data has been damaged or if random access is desired. Using + -- Full_Flush too often can seriously degrade the compression. + + Finish : constant Flush_Mode; + -- Just for tell the compressor that input data is complete. + + ------------------------------------ + -- Compression strategy constants -- + ------------------------------------ + + -- RLE stategy could be used only in version 1.2.0 and later. + + Filtered : constant Strategy_Type; + Huffman_Only : constant Strategy_Type; + RLE : constant Strategy_Type; + Default_Strategy : constant Strategy_Type; + + Default_Buffer_Size : constant := 4096; + + type Filter_Type is tagged limited private; + -- The filter is for compression and for decompression. + -- The usage of the type is depend of its initialization. + + function Version return String; + pragma Inline (Version); + -- Return string representation of the ZLib version. + + procedure Deflate_Init + (Filter : in out Filter_Type; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Method : in Compression_Method := Deflated; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; + Header : in Header_Type := Default); + -- Compressor initialization. + -- When Header parameter is Auto or Default, then default zlib header + -- would be provided for compressed data. + -- When Header is GZip, then gzip header would be set instead of + -- default header. + -- When Header is None, no header would be set for compressed data. + + procedure Inflate_Init + (Filter : in out Filter_Type; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Header : in Header_Type := Default); + -- Decompressor initialization. + -- Default header type mean that ZLib default header is expecting in the + -- input compressed stream. + -- Header type None mean that no header is expecting in the input stream. + -- GZip header type mean that GZip header is expecting in the + -- input compressed stream. + -- Auto header type mean that header type (GZip or Native) would be + -- detected automatically in the input stream. + -- Note that header types parameter values None, GZip and Auto are + -- supported for inflate routine only in ZLib versions 1.2.0.2 and later. + -- Deflate_Init is supporting all header types. + + function Is_Open (Filter : in Filter_Type) return Boolean; + pragma Inline (Is_Open); + -- Is the filter opened for compression or decompression. + + procedure Close + (Filter : in out Filter_Type; + Ignore_Error : in Boolean := False); + -- Closing the compression or decompressor. + -- If stream is closing before the complete and Ignore_Error is False, + -- The exception would be raised. + + generic + with procedure Data_In + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + with procedure Data_Out + (Item : in Ada.Streams.Stream_Element_Array); + procedure Generic_Translate + (Filter : in out Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size); + -- Compress/decompress data fetch from Data_In routine and pass the result + -- to the Data_Out routine. User should provide Data_In and Data_Out + -- for compression/decompression data flow. + -- Compression or decompression depend on Filter initialization. + + function Total_In (Filter : in Filter_Type) return Count; + pragma Inline (Total_In); + -- Returns total number of input bytes read so far + + function Total_Out (Filter : in Filter_Type) return Count; + pragma Inline (Total_Out); + -- Returns total number of bytes output so far + + function CRC32 + (CRC : in Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) + return Unsigned_32; + pragma Inline (CRC32); + -- Compute CRC32, it could be necessary for make gzip format + + procedure CRC32 + (CRC : in out Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array); + pragma Inline (CRC32); + -- Compute CRC32, it could be necessary for make gzip format + + ------------------------------------------------- + -- Below is more complex low level routines. -- + ------------------------------------------------- + + procedure Translate + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- Compress/decompress the In_Data buffer and place the result into + -- Out_Data. In_Last is the index of last element from In_Data accepted by + -- the Filter. Out_Last is the last element of the received data from + -- Filter. To tell the filter that incoming data are complete put the + -- Flush parameter to Finish. + + function Stream_End (Filter : in Filter_Type) return Boolean; + pragma Inline (Stream_End); + -- Return the true when the stream is complete. + + procedure Flush + (Filter : in out Filter_Type; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + pragma Inline (Flush); + -- Flushing the data from the compressor. + + generic + with procedure Write + (Item : in Ada.Streams.Stream_Element_Array); + -- User should provide this routine for accept + -- compressed/decompressed data. + + Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + -- Buffer size for Write user routine. + + procedure Write + (Filter : in out Filter_Type; + Item : in Ada.Streams.Stream_Element_Array; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from Item to the generic parameter procedure + -- Write. Output buffer size could be set in Buffer_Size generic parameter. + + generic + with procedure Read + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + -- User should provide data for compression/decompression + -- thru this routine. + + Buffer : in out Ada.Streams.Stream_Element_Array; + -- Buffer for keep remaining data from the previous + -- back read. + + Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset; + -- Rest_First have to be initialized to Buffer'Last + 1 + -- Rest_Last have to be initialized to Buffer'Last + -- before usage. + + Allow_Read_Some : in Boolean := False; + -- Is it allowed to return Last < Item'Last before end of data. + + procedure Read + (Filter : in out Filter_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from generic parameter procedure Read to the + -- Item. User should provide Buffer and initialized Rest_First, Rest_Last + -- indicators. If Allow_Read_Some is True, Read routines could return + -- Last < Item'Last only at end of stream. + +private + + use Ada.Streams; + + pragma Assert (Ada.Streams.Stream_Element'Size = 8); + pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8); + + type Flush_Mode is new Integer range 0 .. 5; + + type Compression_Method is new Integer range 8 .. 8; + + type Strategy_Type is new Integer range 0 .. 3; + + No_Flush : constant Flush_Mode := 0; + Partial_Flush : constant Flush_Mode := 1; + Sync_Flush : constant Flush_Mode := 2; + Full_Flush : constant Flush_Mode := 3; + Finish : constant Flush_Mode := 4; + Block_Flush : constant Flush_Mode := 5; + + Filtered : constant Strategy_Type := 1; + Huffman_Only : constant Strategy_Type := 2; + RLE : constant Strategy_Type := 3; + Default_Strategy : constant Strategy_Type := 0; + + Deflated : constant Compression_Method := 8; + + type Z_Stream; + + type Z_Stream_Access is access all Z_Stream; + + type Filter_Type is tagged limited record + Strm : Z_Stream_Access; + Compression : Boolean; + Stream_End : Boolean; + Header : Header_Type; + CRC : Unsigned_32; + Offset : Stream_Element_Offset; + -- Offset for gzip header/footer output. + end record; + +end ZLib; diff --git a/src/external/zlib-1.2.11/contrib/ada/zlib.gpr b/src/external/zlib-1.2.11/contrib/ada/zlib.gpr new file mode 100644 index 000000000..296b22aa9 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/ada/zlib.gpr @@ -0,0 +1,20 @@ +project Zlib is + + for Languages use ("Ada"); + for Source_Dirs use ("."); + for Object_Dir use "."; + for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo"); + + package Compiler is + for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); + end Compiler; + + package Linker is + for Default_Switches ("ada") use ("-lz"); + end Linker; + + package Builder is + for Default_Switches ("ada") use ("-s", "-gnatQ"); + end Builder; + +end Zlib; diff --git a/src/external/zlib-1.2.11/contrib/amd64/amd64-match.S b/src/external/zlib-1.2.11/contrib/amd64/amd64-match.S new file mode 100644 index 000000000..81d4a1c94 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/amd64/amd64-match.S @@ -0,0 +1,452 @@ +/* + * match.S -- optimized version of longest_match() + * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998 + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the BSD License. Use by owners of Che Guevarra + * parafernalia is prohibited, where possible, and highly discouraged + * elsewhere. + */ + +#ifndef NO_UNDERLINE +# define match_init _match_init +# define longest_match _longest_match +#endif + +#define scanend ebx +#define scanendw bx +#define chainlenwmask edx /* high word: current chain len low word: s->wmask */ +#define curmatch rsi +#define curmatchd esi +#define windowbestlen r8 +#define scanalign r9 +#define scanalignd r9d +#define window r10 +#define bestlen r11 +#define bestlend r11d +#define scanstart r12d +#define scanstartw r12w +#define scan r13 +#define nicematch r14d +#define limit r15 +#define limitd r15d +#define prev rcx + +/* + * The 258 is a "magic number, not a parameter -- changing it + * breaks the hell loose + */ +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ +#define LocalVarsSize (112) +#define _chainlenwmask ( 8-LocalVarsSize)(%rsp) +#define _windowbestlen (16-LocalVarsSize)(%rsp) +#define save_r14 (24-LocalVarsSize)(%rsp) +#define save_rsi (32-LocalVarsSize)(%rsp) +#define save_rbx (40-LocalVarsSize)(%rsp) +#define save_r12 (56-LocalVarsSize)(%rsp) +#define save_r13 (64-LocalVarsSize)(%rsp) +#define save_r15 (80-LocalVarsSize)(%rsp) + + +.globl match_init, longest_match + +/* + * On AMD64 the first argument of a function (in our case -- the pointer to + * deflate_state structure) is passed in %rdi, hence our offsets below are + * all off of that. + */ + +/* you can check the structure offset by running + +#include +#include +#include "deflate.h" + +void print_depl() +{ +deflate_state ds; +deflate_state *s=&ds; +printf("size pointer=%u\n",(int)sizeof(void*)); + +printf("#define dsWSize (%3u)(%%rdi)\n",(int)(((char*)&(s->w_size))-((char*)s))); +printf("#define dsWMask (%3u)(%%rdi)\n",(int)(((char*)&(s->w_mask))-((char*)s))); +printf("#define dsWindow (%3u)(%%rdi)\n",(int)(((char*)&(s->window))-((char*)s))); +printf("#define dsPrev (%3u)(%%rdi)\n",(int)(((char*)&(s->prev))-((char*)s))); +printf("#define dsMatchLen (%3u)(%%rdi)\n",(int)(((char*)&(s->match_length))-((char*)s))); +printf("#define dsPrevMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_match))-((char*)s))); +printf("#define dsStrStart (%3u)(%%rdi)\n",(int)(((char*)&(s->strstart))-((char*)s))); +printf("#define dsMatchStart (%3u)(%%rdi)\n",(int)(((char*)&(s->match_start))-((char*)s))); +printf("#define dsLookahead (%3u)(%%rdi)\n",(int)(((char*)&(s->lookahead))-((char*)s))); +printf("#define dsPrevLen (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_length))-((char*)s))); +printf("#define dsMaxChainLen (%3u)(%%rdi)\n",(int)(((char*)&(s->max_chain_length))-((char*)s))); +printf("#define dsGoodMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->good_match))-((char*)s))); +printf("#define dsNiceMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->nice_match))-((char*)s))); +} + +*/ + + +/* + to compile for XCode 3.2 on MacOSX x86_64 + - run "gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S" + */ + + +#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE +#define dsWSize ( 68)(%rdi) +#define dsWMask ( 76)(%rdi) +#define dsWindow ( 80)(%rdi) +#define dsPrev ( 96)(%rdi) +#define dsMatchLen (144)(%rdi) +#define dsPrevMatch (148)(%rdi) +#define dsStrStart (156)(%rdi) +#define dsMatchStart (160)(%rdi) +#define dsLookahead (164)(%rdi) +#define dsPrevLen (168)(%rdi) +#define dsMaxChainLen (172)(%rdi) +#define dsGoodMatch (188)(%rdi) +#define dsNiceMatch (192)(%rdi) + +#else + +#ifndef STRUCT_OFFSET +# define STRUCT_OFFSET (0) +#endif + + +#define dsWSize ( 56 + STRUCT_OFFSET)(%rdi) +#define dsWMask ( 64 + STRUCT_OFFSET)(%rdi) +#define dsWindow ( 72 + STRUCT_OFFSET)(%rdi) +#define dsPrev ( 88 + STRUCT_OFFSET)(%rdi) +#define dsMatchLen (136 + STRUCT_OFFSET)(%rdi) +#define dsPrevMatch (140 + STRUCT_OFFSET)(%rdi) +#define dsStrStart (148 + STRUCT_OFFSET)(%rdi) +#define dsMatchStart (152 + STRUCT_OFFSET)(%rdi) +#define dsLookahead (156 + STRUCT_OFFSET)(%rdi) +#define dsPrevLen (160 + STRUCT_OFFSET)(%rdi) +#define dsMaxChainLen (164 + STRUCT_OFFSET)(%rdi) +#define dsGoodMatch (180 + STRUCT_OFFSET)(%rdi) +#define dsNiceMatch (184 + STRUCT_OFFSET)(%rdi) + +#endif + + + + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: +/* + * Retrieve the function arguments. %curmatch will hold cur_match + * throughout the entire function (passed via rsi on amd64). + * rdi will hold the pointer to the deflate_state (first arg on amd64) + */ + mov %rsi, save_rsi + mov %rbx, save_rbx + mov %r12, save_r12 + mov %r13, save_r13 + mov %r14, save_r14 + mov %r15, save_r15 + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen, %eax + movl dsGoodMatch, %ebx + cmpl %ebx, %eax + movl dsWMask, %eax + movl dsMaxChainLen, %chainlenwmask + jl LastMatchGood + shrl $2, %chainlenwmask +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %chainlenwmask + shll $16, %chainlenwmask + orl %eax, %chainlenwmask + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch, %eax + movl dsLookahead, %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, %nicematch + +/* register Bytef *scan = s->window + s->strstart; */ + + mov dsWindow, %window + movl dsStrStart, %limitd + lea (%limit, %window), %scan + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + mov %scan, %scanalign + negl %scanalignd + andl $3, %scanalignd + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize, %eax + subl $MIN_LOOKAHEAD, %eax + xorl %ecx, %ecx + subl %eax, %limitd + cmovng %ecx, %limitd + +/* int best_len = s->prev_length; */ + + movl dsPrevLen, %bestlend + +/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory. */ + + lea (%window, %bestlen), %windowbestlen + mov %windowbestlen, _windowbestlen + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%scan), %scanstart + movzwl -1(%scan, %bestlen), %scanend + mov dsPrev, %prev + +/* Jump into the main loop. */ + + movl %chainlenwmask, _chainlenwmask + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + */ +LookupLoop: + andl %chainlenwmask, %curmatchd + movzwl (%prev, %curmatch, 2), %curmatchd + cmpl %limitd, %curmatchd + jbe LeaveNow + subl $0x00010000, %chainlenwmask + js LeaveNow +LoopEntry: cmpw -1(%windowbestlen, %curmatch), %scanendw + jne LookupLoop + cmpw %scanstartw, (%window, %curmatch) + jne LookupLoop + +/* Store the current value of chainlen. */ + movl %chainlenwmask, _chainlenwmask + +/* %scan is the string under scrutiny, and %prev to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + mov $(-MAX_MATCH_8), %rdx + lea (%curmatch, %window), %windowbestlen + lea MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen + lea MAX_MATCH_8(%scan, %scanalign), %prev + +/* the prefetching below makes very little difference... */ + prefetcht1 (%windowbestlen, %rdx) + prefetcht1 (%prev, %rdx) + +/* + * Test the strings for equality, 8 bytes at a time. At the end, + * adjust %rdx so that it is offset to the exact byte that mismatched. + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance -- unrolling it, for example, makes no difference. + */ + +#undef USE_SSE /* works, but is 6-7% slower, than non-SSE... */ + +LoopCmps: +#ifdef USE_SSE + /* Preload the SSE registers */ + movdqu (%windowbestlen, %rdx), %xmm1 + movdqu (%prev, %rdx), %xmm2 + pcmpeqb %xmm2, %xmm1 + movdqu 16(%windowbestlen, %rdx), %xmm3 + movdqu 16(%prev, %rdx), %xmm4 + pcmpeqb %xmm4, %xmm3 + movdqu 32(%windowbestlen, %rdx), %xmm5 + movdqu 32(%prev, %rdx), %xmm6 + pcmpeqb %xmm6, %xmm5 + movdqu 48(%windowbestlen, %rdx), %xmm7 + movdqu 48(%prev, %rdx), %xmm8 + pcmpeqb %xmm8, %xmm7 + + /* Check the comparisions' results */ + pmovmskb %xmm1, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + /* this is the only iteration of the loop with a possibility of having + incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40 + and (0x40*4)+8=0x108 */ + add $8, %rdx + jz LenMaximum + add $8, %rdx + + + pmovmskb %xmm3, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + + add $16, %rdx + + + pmovmskb %xmm5, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + add $16, %rdx + + + pmovmskb %xmm7, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + add $16, %rdx + + jmp LoopCmps +LeaveLoopCmps: add %rax, %rdx +#else + mov (%windowbestlen, %rdx), %rax + xor (%prev, %rdx), %rax + jnz LeaveLoopCmps + + mov 8(%windowbestlen, %rdx), %rax + xor 8(%prev, %rdx), %rax + jnz LeaveLoopCmps8 + + mov 16(%windowbestlen, %rdx), %rax + xor 16(%prev, %rdx), %rax + jnz LeaveLoopCmps16 + + add $24, %rdx + jnz LoopCmps + jmp LenMaximum +# if 0 +/* + * This three-liner is tantalizingly simple, but bsf is a slow instruction, + * and the complicated alternative down below is quite a bit faster. Sad... + */ + +LeaveLoopCmps: bsf %rax, %rax /* find the first non-zero bit */ + shrl $3, %eax /* divide by 8 to get the byte */ + add %rax, %rdx +# else +LeaveLoopCmps16: + add $8, %rdx +LeaveLoopCmps8: + add $8, %rdx +LeaveLoopCmps: testl $0xFFFFFFFF, %eax /* Check the first 4 bytes */ + jnz Check16 + add $4, %rdx + shr $32, %rax +Check16: testw $0xFFFF, %ax + jnz LenLower + add $2, %rdx + shrl $16, %eax +LenLower: subb $1, %al + adc $0, %rdx +# endif +#endif + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%prev, %rdx), %rax + sub %scan, %rax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + cmpl %bestlend, %eax + jg LongerMatch + mov _windowbestlen, %windowbestlen + mov dsPrev, %prev + movl _chainlenwmask, %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: + movl %eax, %bestlend + movl %curmatchd, dsMatchStart + cmpl %nicematch, %eax + jge LeaveNow + + lea (%window, %bestlen), %windowbestlen + mov %windowbestlen, _windowbestlen + + movzwl -1(%scan, %rax), %scanend + mov dsPrev, %prev + movl _chainlenwmask, %chainlenwmask + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: + movl $MAX_MATCH, %bestlend + movl %curmatchd, dsMatchStart + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl dsLookahead, %eax + cmpl %eax, %bestlend + cmovngl %bestlend, %eax +LookaheadRet: + +/* Restore the registers and return from whence we came. */ + + mov save_rsi, %rsi + mov save_rbx, %rbx + mov save_r12, %r12 + mov save_r13, %r13 + mov save_r14, %r14 + mov save_r15, %r15 + + ret + +match_init: ret diff --git a/src/external/zlib-1.2.11/contrib/asm686/README.686 b/src/external/zlib-1.2.11/contrib/asm686/README.686 new file mode 100644 index 000000000..a0bf3bea4 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/asm686/README.686 @@ -0,0 +1,51 @@ +This is a patched version of zlib, modified to use +Pentium-Pro-optimized assembly code in the deflation algorithm. The +files changed/added by this patch are: + +README.686 +match.S + +The speedup that this patch provides varies, depending on whether the +compiler used to build the original version of zlib falls afoul of the +PPro's speed traps. My own tests show a speedup of around 10-20% at +the default compression level, and 20-30% using -9, against a version +compiled using gcc 2.7.2.3. Your mileage may vary. + +Note that this code has been tailored for the PPro/PII in particular, +and will not perform particuarly well on a Pentium. + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o + + +Update: + +I've been ignoring these assembly routines for years, believing that +gcc's generated code had caught up with it sometime around gcc 2.95 +and the major rearchitecting of the Pentium 4. However, I recently +learned that, despite what I believed, this code still has some life +in it. On the Pentium 4 and AMD64 chips, it continues to run about 8% +faster than the code produced by gcc 4.1. + +In acknowledgement of its continuing usefulness, I've altered the +license to match that of the rest of zlib. Share and Enjoy! + +Brian Raiter +breadbox@muppetlabs.com +April, 2007 diff --git a/src/external/zlib-1.2.11/contrib/asm686/match.S b/src/external/zlib-1.2.11/contrib/asm686/match.S new file mode 100644 index 000000000..fa4210927 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/asm686/match.S @@ -0,0 +1,357 @@ +/* match.S -- x86 assembly version of the zlib longest_match() function. + * Optimized for the Intel 686 chips (PPro and later). + * + * Copyright (C) 1998, 2007 Brian Raiter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define chainlenwmask 0 /* high word: current chain len */ + /* low word: s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define scanstart 16 /* first two bytes of string */ +#define scanend 12 /* last two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* All the +zlib1222add offsets are due to the addition of fields + * in zlib in the deflate_state structure since the asm code was first written + * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). + * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). + * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + */ + +#define zlib1222add (8) + +#define dsWSize (36+zlib1222add) +#define dsWMask (44+zlib1222add) +#define dsWindow (48+zlib1222add) +#define dsPrev (56+zlib1222add) +#define dsMatchLen (88+zlib1222add) +#define dsPrevMatch (92+zlib1222add) +#define dsStrStart (100+zlib1222add) +#define dsMatchStart (104+zlib1222add) +#define dsLookahead (108+zlib1222add) +#define dsPrevLen (112+zlib1222add) +#define dsMaxChainLen (116+zlib1222add) +#define dsGoodMatch (132+zlib1222add) +#define dsNiceMatch (136+zlib1222add) + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ +.cfi_sections .debug_frame + +longest_match: + +.cfi_startproc +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset ebp, -8 + pushl %edi + .cfi_def_cfa_offset 12 + pushl %esi + .cfi_def_cfa_offset 16 + pushl %ebx + .cfi_def_cfa_offset 20 + subl $LocalVarsSize, %esp + .cfi_def_cfa_offset LocalVarsSize+20 + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsWMask(%edx), %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + orl %eax, %ebx + movl %ebx, chainlenwmask(%esp) + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%edi), %ebx + movl %ebx, scanstart(%esp) + movzwl -1(%edi,%eax), %ebx + movl %ebx, scanend(%esp) + movl dsPrev(%edx), %edi + +/* Jump into the main loop. */ + + movl chainlenwmask(%esp), %edx + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = scanend + * %ecx = curmatch + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + */ +LookupLoop: + andl %edx, %ecx + movzwl (%edi,%ecx,2), %ecx + cmpl %ebp, %ecx + jbe LeaveNow + subl $0x00010000, %edx + js LeaveNow +LoopEntry: movzwl -1(%esi,%ecx), %eax + cmpl %ebx, %eax + jnz LookupLoop + movl window(%esp), %eax + movzwl (%eax,%ecx), %eax + cmpl scanstart(%esp), %eax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %edx, chainlenwmask(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + xorl (%edi,%edx), %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + xorl 4(%edi,%edx), %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl scanend(%esp), %ebx + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movzwl -1(%edi,%eax), %ebx + movl dsPrev(%edx), %edi + movl %ebx, scanend(%esp) + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + .cfi_def_cfa_offset 20 + popl %ebx + .cfi_def_cfa_offset 16 + popl %esi + .cfi_def_cfa_offset 12 + popl %edi + .cfi_def_cfa_offset 8 + popl %ebp + .cfi_def_cfa_offset 4 +.cfi_endproc +match_init: ret diff --git a/src/external/zlib-1.2.11/contrib/blast/Makefile b/src/external/zlib-1.2.11/contrib/blast/Makefile new file mode 100644 index 000000000..9be80bafe --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/blast/Makefile @@ -0,0 +1,8 @@ +blast: blast.c blast.h + cc -DTEST -o blast blast.c + +test: blast + blast < test.pk | cmp - test.txt + +clean: + rm -f blast blast.o diff --git a/src/external/zlib-1.2.11/contrib/blast/README b/src/external/zlib-1.2.11/contrib/blast/README new file mode 100644 index 000000000..e3a60b3f5 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/blast/README @@ -0,0 +1,4 @@ +Read blast.h for purpose and usage. + +Mark Adler +madler@alumni.caltech.edu diff --git a/src/external/zlib-1.2.11/contrib/blast/blast.c b/src/external/zlib-1.2.11/contrib/blast/blast.c new file mode 100644 index 000000000..e6e659073 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/blast/blast.c @@ -0,0 +1,466 @@ +/* blast.c + * Copyright (C) 2003, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in blast.h + * version 1.3, 24 Aug 2013 + * + * blast.c decompresses data compressed by the PKWare Compression Library. + * This function provides functionality similar to the explode() function of + * the PKWare library, hence the name "blast". + * + * This decompressor is based on the excellent format description provided by + * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the + * example Ben provided in the post is incorrect. The distance 110001 should + * instead be 111000. When corrected, the example byte stream becomes: + * + * 00 04 82 24 25 8f 80 7f + * + * which decompresses to "AIAIAIAIAIAIA" (without the quotes). + */ + +/* + * Change history: + * + * 1.0 12 Feb 2003 - First version + * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data + * 1.2 24 Oct 2012 - Add note about using binary mode in stdio + * - Fix comparisons of differently signed integers + * 1.3 24 Aug 2013 - Return unused input from blast() + * - Fix test code to correctly report unused input + * - Enable the provision of initial input to blast() + */ + +#include /* for NULL */ +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "blast.h" /* prototype for blast() */ + +#define local static /* for local function definitions */ +#define MAXBITS 13 /* maximum code length */ +#define MAXWIN 4096 /* maximum window size */ + +/* input and output state */ +struct state { + /* input state */ + blast_in infun; /* input function provided by user */ + void *inhow; /* opaque information passed to infun() */ + unsigned char *in; /* next input location */ + unsigned left; /* available input at in */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; + + /* output state */ + blast_out outfun; /* output function provided by user */ + void *outhow; /* opaque information passed to outfun() */ + unsigned next; /* index of next write location in out[] */ + int first; /* true to check distances (for first 4K) */ + unsigned char out[MAXWIN]; /* output buffer and sliding window */ +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + int val; /* bit accumulator */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ + s->left--; + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = val >> need; + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return val & ((1 << need) - 1); +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -9 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. + * + * - The first code for the shortest length is all ones. Subsequent codes of + * the same length are simply integer decrements of the previous code. When + * moving up a length, a one bit is appended to the code. For a complete + * code, the last code of the longest length will be all zeros. To support + * this ordering, the bits pulled during decoding are inverted to apply the + * more "natural" ordering starting with all zeros and incrementing. + */ +local int decode(struct state *s, struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= (bitbuf & 1) ^ 1; /* invert code */ + bitbuf >>= 1; + count = *next++; + if (code < first + count) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) break; + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + bitbuf = *(s->in)++; + s->left--; + if (left > 8) left = 8; + } + return -9; /* ran out of codes */ +} + +/* + * Given a list of repeated code lengths rep[0..n-1], where each byte is a + * count (high four bits + 1) and a code length (low four bits), generate the + * list of code lengths. This compaction reduces the size of the object code. + * Then given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + */ +local int construct(struct huffman *h, const unsigned char *rep, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + short length[256]; /* code lengths */ + + /* convert compact repeat counts into symbol bit length list */ + symbol = 0; + do { + len = *rep++; + left = (len >> 4) + 1; + len &= 15; + do { + length[symbol++] = len; + } while (--left); + } while (--n); + n = symbol; + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode PKWare Compression Library stream. + * + * Format notes: + * + * - First byte is 0 if literals are uncoded or 1 if they are coded. Second + * byte is 4, 5, or 6 for the number of extra bits in the distance code. + * This is the base-2 logarithm of the dictionary size minus six. + * + * - Compressed data is a combination of literals and length/distance pairs + * terminated by an end code. Literals are either Huffman coded or + * uncoded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - A bit preceding a literal or length/distance pair indicates which comes + * next, 0 for literals, 1 for length/distance. + * + * - If literals are uncoded, then the next eight bits are the literal, in the + * normal bit order in the stream, i.e. no bit-reversal is needed. Similarly, + * no bit reversal is needed for either the length extra bits or the distance + * extra bits. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 518 + * simply copies the last byte 518 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. + */ +local int decomp(struct state *s) +{ + int lit; /* true if literals are coded */ + int dict; /* log2(dictionary size) - 6 */ + int symbol; /* decoded symbol, extra bits for distance */ + int len; /* length for copy */ + unsigned dist; /* distance for copy */ + int copy; /* copy counter */ + unsigned char *from, *to; /* copy pointers */ + static int virgin = 1; /* build tables once */ + static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ + static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ + static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ + static struct huffman litcode = {litcnt, litsym}; /* length code */ + static struct huffman lencode = {lencnt, lensym}; /* length code */ + static struct huffman distcode = {distcnt, distsym};/* distance code */ + /* bit lengths of literal codes */ + static const unsigned char litlen[] = { + 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, + 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, + 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, + 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, + 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, + 44, 173}; + /* bit lengths of length codes 0..15 */ + static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; + /* bit lengths of distance codes 0..63 */ + static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; + static const short base[16] = { /* base for length codes */ + 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; + static const char extra[16] = { /* extra bits for length codes */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; + + /* set up decoding tables (once--might not be thread-safe) */ + if (virgin) { + construct(&litcode, litlen, sizeof(litlen)); + construct(&lencode, lenlen, sizeof(lenlen)); + construct(&distcode, distlen, sizeof(distlen)); + virgin = 0; + } + + /* read header */ + lit = bits(s, 8); + if (lit > 1) return -1; + dict = bits(s, 8); + if (dict < 4 || dict > 6) return -2; + + /* decode literals and length/distance pairs */ + do { + if (bits(s, 1)) { + /* get length */ + symbol = decode(s, &lencode); + len = base[symbol] + bits(s, extra[symbol]); + if (len == 519) break; /* end code */ + + /* get distance */ + symbol = len == 2 ? 2 : dict; + dist = decode(s, &distcode) << symbol; + dist += bits(s, symbol); + dist++; + if (s->first && dist > s->next) + return -3; /* distance too far back */ + + /* copy length bytes from distance bytes back */ + do { + to = s->out + s->next; + from = to - dist; + copy = MAXWIN; + if (s->next < dist) { + from += copy; + copy = dist; + } + copy -= s->next; + if (copy > len) copy = len; + len -= copy; + s->next += copy; + do { + *to++ = *from++; + } while (--copy); + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } while (len != 0); + } + else { + /* get literal and write it */ + symbol = lit ? decode(s, &litcode) : bits(s, 8); + s->out[s->next++] = symbol; + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } + } while (1); + return 0; +} + +/* See comments in blast.h */ +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow, + unsigned *left, unsigned char **in) +{ + struct state s; /* input/output state */ + int err; /* return value */ + + /* initialize input state */ + s.infun = infun; + s.inhow = inhow; + if (left != NULL && *left) { + s.left = *left; + s.in = *in; + } + else + s.left = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* initialize output state */ + s.outfun = outfun; + s.outhow = outhow; + s.next = 0; + s.first = 1; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ + err = 2; /* then skip decomp(), return error */ + else + err = decomp(&s); /* decompress */ + + /* return unused input */ + if (left != NULL) + *left = s.left; + if (in != NULL) + *in = s.left ? s.in : NULL; + + /* write any leftover output and update the error code if needed */ + if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) + err = 1; + return err; +} + +#ifdef TEST +/* Example of how to use blast() */ +#include +#include + +#define CHUNK 16384 + +local unsigned inf(void *how, unsigned char **buf) +{ + static unsigned char hold[CHUNK]; + + *buf = hold; + return fread(hold, 1, CHUNK, (FILE *)how); +} + +local int outf(void *how, unsigned char *buf, unsigned len) +{ + return fwrite(buf, 1, len, (FILE *)how) != len; +} + +/* Decompress a PKWare Compression Library stream from stdin to stdout */ +int main(void) +{ + int ret; + unsigned left; + + /* decompress to stdout */ + left = 0; + ret = blast(inf, stdin, outf, stdout, &left, NULL); + if (ret != 0) + fprintf(stderr, "blast error: %d\n", ret); + + /* count any leftover bytes */ + while (getchar() != EOF) + left++; + if (left) + fprintf(stderr, "blast warning: %u unused bytes of input\n", left); + + /* return blast() error code */ + return ret; +} +#endif diff --git a/src/external/zlib-1.2.11/contrib/blast/blast.h b/src/external/zlib-1.2.11/contrib/blast/blast.h new file mode 100644 index 000000000..6cf65eda1 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/blast/blast.h @@ -0,0 +1,83 @@ +/* blast.h -- interface for blast.c + Copyright (C) 2003, 2012, 2013 Mark Adler + version 1.3, 24 Aug 2013 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * blast() decompresses the PKWare Data Compression Library (DCL) compressed + * format. It provides the same functionality as the explode() function in + * that library. (Note: PKWare overused the "implode" verb, and the format + * used by their library implode() function is completely different and + * incompatible with the implode compression method supported by PKZIP.) + * + * The binary mode for stdio functions should be used to assure that the + * compressed data is not corrupted when read or written. For example: + * fopen(..., "rb") and fopen(..., "wb"). + */ + + +typedef unsigned (*blast_in)(void *how, unsigned char **buf); +typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); +/* Definitions for input/output functions passed to blast(). See below for + * what the provided functions need to do. + */ + + +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow, + unsigned *left, unsigned char **in); +/* Decompress input to output using the provided infun() and outfun() calls. + * On success, the return value of blast() is zero. If there is an error in + * the source data, i.e. it is not in the proper format, then a negative value + * is returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. + * + * The input function is invoked: len = infun(how, &buf), where buf is set by + * infun() to point to the input buffer, and infun() returns the number of + * available bytes there. If infun() returns zero, then blast() returns with + * an input error. (blast() only asks for input if it needs it.) inhow is for + * use by the application to pass an input descriptor to infun(), if desired. + * + * If left and in are not NULL and *left is not zero when blast() is called, + * then the *left bytes are *in are consumed for input before infun() is used. + * + * The output function is invoked: err = outfun(how, buf, len), where the bytes + * to be written are buf[0..len-1]. If err is not zero, then blast() returns + * with an output error. outfun() is always called with len <= 4096. outhow + * is for use by the application to pass an output descriptor to outfun(), if + * desired. + * + * If there is any unused input, *left is set to the number of bytes that were + * read and *in points to them. Otherwise *left is set to zero and *in is set + * to NULL. If left or in are NULL, then they are not set. + * + * The return codes are: + * + * 2: ran out of input before completing decompression + * 1: output error before completing decompression + * 0: successful decompression + * -1: literal flag not zero or one + * -2: dictionary size not in 4..6 + * -3: distance is too far back + * + * At the bottom of blast.c is an example program that uses blast() that can be + * compiled to produce a command-line decompression filter by defining TEST. + */ diff --git a/src/external/zlib-1.2.11/contrib/blast/test.pk b/src/external/zlib-1.2.11/contrib/blast/test.pk new file mode 100644 index 000000000..be10b2bbb Binary files /dev/null and b/src/external/zlib-1.2.11/contrib/blast/test.pk differ diff --git a/src/external/zlib-1.2.11/contrib/blast/test.txt b/src/external/zlib-1.2.11/contrib/blast/test.txt new file mode 100644 index 000000000..bfdf1c5dc --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/blast/test.txt @@ -0,0 +1 @@ +AIAIAIAIAIAIA \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/delphi/ZLib.pas b/src/external/zlib-1.2.11/contrib/delphi/ZLib.pas new file mode 100644 index 000000000..060e19911 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/delphi/ZLib.pas @@ -0,0 +1,557 @@ +{*******************************************************} +{ } +{ Borland Delphi Supplemental Components } +{ ZLIB Data Compression Interface Unit } +{ } +{ Copyright (c) 1997,99 Borland Corporation } +{ } +{*******************************************************} + +{ Updated for zlib 1.2.x by Cosmin Truta } + +unit ZLib; + +interface + +uses SysUtils, Classes; + +type + TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl; + TFree = procedure (AppData, Block: Pointer); cdecl; + + // Internal structure. Ignore. + TZStreamRec = packed record + next_in: PChar; // next input byte + avail_in: Integer; // number of bytes available at next_in + total_in: Longint; // total nb of input bytes read so far + + next_out: PChar; // next output byte should be put here + avail_out: Integer; // remaining free space at next_out + total_out: Longint; // total nb of bytes output so far + + msg: PChar; // last error message, NULL if no error + internal: Pointer; // not visible by applications + + zalloc: TAlloc; // used to allocate the internal state + zfree: TFree; // used to free the internal state + AppData: Pointer; // private data object passed to zalloc and zfree + + data_type: Integer; // best guess about the data type: ascii or binary + adler: Longint; // adler32 value of the uncompressed data + reserved: Longint; // reserved for future use + end; + + // Abstract ancestor class + TCustomZlibStream = class(TStream) + private + FStrm: TStream; + FStrmPos: Integer; + FOnProgress: TNotifyEvent; + FZRec: TZStreamRec; + FBuffer: array [Word] of Char; + protected + procedure Progress(Sender: TObject); dynamic; + property OnProgress: TNotifyEvent read FOnProgress write FOnProgress; + constructor Create(Strm: TStream); + end; + +{ TCompressionStream compresses data on the fly as data is written to it, and + stores the compressed data to another stream. + + TCompressionStream is write-only and strictly sequential. Reading from the + stream will raise an exception. Using Seek to move the stream pointer + will raise an exception. + + Output data is cached internally, written to the output stream only when + the internal output buffer is full. All pending output data is flushed + when the stream is destroyed. + + The Position property returns the number of uncompressed bytes of + data that have been written to the stream so far. + + CompressionRate returns the on-the-fly percentage by which the original + data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100 + If raw data size = 100 and compressed data size = 25, the CompressionRate + is 75% + + The OnProgress event is called each time the output buffer is filled and + written to the output stream. This is useful for updating a progress + indicator when you are writing a large chunk of data to the compression + stream in a single call.} + + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + TCompressionStream = class(TCustomZlibStream) + private + function GetCompressionRate: Single; + public + constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream); + destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; + property CompressionRate: Single read GetCompressionRate; + property OnProgress; + end; + +{ TDecompressionStream decompresses data on the fly as data is read from it. + + Compressed data comes from a separate source stream. TDecompressionStream + is read-only and unidirectional; you can seek forward in the stream, but not + backwards. The special case of setting the stream position to zero is + allowed. Seeking forward decompresses data until the requested position in + the uncompressed data has been reached. Seeking backwards, seeking relative + to the end of the stream, requesting the size of the stream, and writing to + the stream will raise an exception. + + The Position property returns the number of bytes of uncompressed data that + have been read from the stream so far. + + The OnProgress event is called each time the internal input buffer of + compressed data is exhausted and the next block is read from the input stream. + This is useful for updating a progress indicator when you are reading a + large chunk of data from the decompression stream in a single call.} + + TDecompressionStream = class(TCustomZlibStream) + public + constructor Create(Source: TStream); + destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; + property OnProgress; + end; + + + +{ CompressBuf compresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: Integer); + + +{ DecompressBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + OutEstimate = zero, or est. size of the decompressed data + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); + +{ DecompressToUserBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to user-allocated buffer to contain decompressed data + BufSize = number of bytes in OutBuf } +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); + +const + zlib_version = '1.2.11'; + +type + EZlibError = class(Exception); + ECompressionError = class(EZlibError); + EDecompressionError = class(EZlibError); + +implementation + +uses ZLibConst; + +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = (-1); + Z_STREAM_ERROR = (-2); + Z_DATA_ERROR = (-3); + Z_MEM_ERROR = (-4); + Z_BUF_ERROR = (-5); + Z_VERSION_ERROR = (-6); + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = (-1); + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + + +{$L adler32.obj} +{$L compress.obj} +{$L crc32.obj} +{$L deflate.obj} +{$L infback.obj} +{$L inffast.obj} +{$L inflate.obj} +{$L inftrees.obj} +{$L trees.obj} +{$L uncompr.obj} +{$L zutil.obj} + +procedure adler32; external; +procedure compressBound; external; +procedure crc32; external; +procedure deflateInit2_; external; +procedure deflateParams; external; + +function _malloc(Size: Integer): Pointer; cdecl; +begin + Result := AllocMem(Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + + + +// deflate compresses data +function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; + recsize: Integer): Integer; external; +function deflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function deflateEnd(var strm: TZStreamRec): Integer; external; + +// inflate decompresses data +function inflateInit_(var strm: TZStreamRec; version: PChar; + recsize: Integer): Integer; external; +function inflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function inflateEnd(var strm: TZStreamRec): Integer; external; +function inflateReset(var strm: TZStreamRec): Integer; external; + + +function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl; +begin +// GetMem(Result, Items*Size); + Result := AllocMem(Items * Size); +end; + +procedure zlibFreeMem(AppData, Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +{function zlibCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise EZlibError.Create('error'); //!! +end;} + +function CCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise ECompressionError.Create('error'); //!! +end; + +function DCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise EDecompressionError.Create('error'); //!! +end; + +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm))); + try + while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, 256); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := 256; + end; + finally + CCheck(deflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; + BufInc: Integer; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + BufInc := (InBytes + 255) and not 255; + if OutEstimate = 0 then + OutBytes := BufInc + else + OutBytes := OutEstimate; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, BufInc); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := BufInc; + end; + finally + DCheck(inflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); +var + strm: TZStreamRec; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := BufSize; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then + raise EZlibError.CreateRes(@sTargetBufferTooSmall); + finally + DCheck(inflateEnd(strm)); + end; +end; + +// TCustomZlibStream + +constructor TCustomZLibStream.Create(Strm: TStream); +begin + inherited Create; + FStrm := Strm; + FStrmPos := Strm.Position; + FZRec.zalloc := zlibAllocMem; + FZRec.zfree := zlibFreeMem; +end; + +procedure TCustomZLibStream.Progress(Sender: TObject); +begin + if Assigned(FOnProgress) then FOnProgress(Sender); +end; + + +// TCompressionStream + +constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; + Dest: TStream); +const + Levels: array [TCompressionLevel] of ShortInt = + (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); +begin + inherited Create(Dest); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec))); +end; + +destructor TCompressionStream.Destroy; +begin + FZRec.next_in := nil; + FZRec.avail_in := 0; + try + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) + and (FZRec.avail_out = 0) do + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + end; + if FZRec.avail_out < sizeof(FBuffer) then + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out); + finally + deflateEnd(FZRec); + end; + inherited Destroy; +end; + +function TCompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + raise ECompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TCompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + FZRec.next_in := @Buffer; + FZRec.avail_in := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_in > 0) do + begin + CCheck(deflate(FZRec, 0)); + if FZRec.avail_out = 0 then + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + FStrmPos := FStrm.Position; + Progress(Self); + end; + end; + Result := Count; +end; + +function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + if (Offset = 0) and (Origin = soFromCurrent) then + Result := FZRec.total_in + else + raise ECompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TCompressionStream.GetCompressionRate: Single; +begin + if FZRec.total_in = 0 then + Result := 0 + else + Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; +end; + + +// TDecompressionStream + +constructor TDecompressionStream.Create(Source: TStream); +begin + inherited Create(Source); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec))); +end; + +destructor TDecompressionStream.Destroy; +begin + FStrm.Seek(-FZRec.avail_in, 1); + inflateEnd(FZRec); + inherited Destroy; +end; + +function TDecompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + FZRec.next_out := @Buffer; + FZRec.avail_out := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_out > 0) do + begin + if FZRec.avail_in = 0 then + begin + FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); + if FZRec.avail_in = 0 then + begin + Result := Count - FZRec.avail_out; + Exit; + end; + FZRec.next_in := FBuffer; + FStrmPos := FStrm.Position; + Progress(Self); + end; + CCheck(inflate(FZRec, 0)); + end; + Result := Count; +end; + +function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + raise EDecompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +var + I: Integer; + Buf: array [0..4095] of Char; +begin + if (Offset = 0) and (Origin = soFromBeginning) then + begin + DCheck(inflateReset(FZRec)); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + FStrm.Position := 0; + FStrmPos := 0; + end + else if ( (Offset >= 0) and (Origin = soFromCurrent)) or + ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then + begin + if Origin = soFromBeginning then Dec(Offset, FZRec.total_out); + if Offset > 0 then + begin + for I := 1 to Offset div sizeof(Buf) do + ReadBuffer(Buf, sizeof(Buf)); + ReadBuffer(Buf, Offset mod sizeof(Buf)); + end; + end + else + raise EDecompressionError.CreateRes(@sInvalidStreamOp); + Result := FZRec.total_out; +end; + + +end. diff --git a/src/external/zlib-1.2.11/contrib/delphi/ZLibConst.pas b/src/external/zlib-1.2.11/contrib/delphi/ZLibConst.pas new file mode 100644 index 000000000..cdfe13671 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/delphi/ZLibConst.pas @@ -0,0 +1,11 @@ +unit ZLibConst; + +interface + +resourcestring + sTargetBufferTooSmall = 'ZLib error: target buffer may be too small'; + sInvalidStreamOp = 'Invalid stream operation'; + +implementation + +end. diff --git a/src/external/zlib-1.2.11/contrib/delphi/readme.txt b/src/external/zlib-1.2.11/contrib/delphi/readme.txt new file mode 100644 index 000000000..2dc9a8bba --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/delphi/readme.txt @@ -0,0 +1,76 @@ + +Overview +======== + +This directory contains an update to the ZLib interface unit, +distributed by Borland as a Delphi supplemental component. + +The original ZLib unit is Copyright (c) 1997,99 Borland Corp., +and is based on zlib version 1.0.4. There are a series of bugs +and security problems associated with that old zlib version, and +we recommend the users to update their ZLib unit. + + +Summary of modifications +======================== + +- Improved makefile, adapted to zlib version 1.2.1. + +- Some field types from TZStreamRec are changed from Integer to + Longint, for consistency with the zlib.h header, and for 64-bit + readiness. + +- The zlib_version constant is updated. + +- The new Z_RLE strategy has its corresponding symbolic constant. + +- The allocation and deallocation functions and function types + (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl, + and _malloc and _free are added as C RTL stubs. As a result, + the original C sources of zlib can be compiled out of the box, + and linked to the ZLib unit. + + +Suggestions for improvements +============================ + +Currently, the ZLib unit provides only a limited wrapper around +the zlib library, and much of the original zlib functionality is +missing. Handling compressed file formats like ZIP/GZIP or PNG +cannot be implemented without having this functionality. +Applications that handle these formats are either using their own, +duplicated code, or not using the ZLib unit at all. + +Here are a few suggestions: + +- Checksum class wrappers around adler32() and crc32(), similar + to the Java classes that implement the java.util.zip.Checksum + interface. + +- The ability to read and write raw deflate streams, without the + zlib stream header and trailer. Raw deflate streams are used + in the ZIP file format. + +- The ability to read and write gzip streams, used in the GZIP + file format, and normally produced by the gzip program. + +- The ability to select a different compression strategy, useful + to PNG and MNG image compression, and to multimedia compression + in general. Besides the compression level + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + which, in fact, could have used the 'z' prefix and avoided + TColor-like symbols + + TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax); + + there could be a compression strategy + + TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle); + +- ZIP and GZIP stream handling via TStreams. + + +-- +Cosmin Truta diff --git a/src/external/zlib-1.2.11/contrib/delphi/zlibd32.mak b/src/external/zlib-1.2.11/contrib/delphi/zlibd32.mak new file mode 100644 index 000000000..9bb00b7cc --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/delphi/zlibd32.mak @@ -0,0 +1,99 @@ +# Makefile for zlib +# For use with Delphi and C++ Builder under Win32 +# Updated for zlib 1.2.x by Cosmin Truta + +# ------------ Borland C++ ------------ + +# This project uses the Delphi (fastcall/register) calling convention: +LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl + +CC = bcc32 +LD = bcc32 +AR = tlib +# do not use "-pr" in CFLAGS +CFLAGS = -a -d -k- -O2 $(LOC) +LDFLAGS = + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.tds + -del zlib.bak + -del foo.gz + diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.build b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.build new file mode 100644 index 000000000..e69630cec --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.build @@ -0,0 +1,33 @@ + + + A .Net wrapper library around ZLib1.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.chm b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.chm new file mode 100644 index 000000000..f214a444a Binary files /dev/null and b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.chm differ diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.sln b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.sln new file mode 100644 index 000000000..5d533d6bc --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/AssemblyInfo.cs new file mode 100644 index 000000000..724c5347f --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DotZLib")] +[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Henrik Ravn")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/ChecksumImpl.cs new file mode 100644 index 000000000..b110dae6a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/ChecksumImpl.cs @@ -0,0 +1,202 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + #region ChecksumGeneratorBase + ///

+ /// Implements the common functionality needed for all s + /// + /// + public abstract class ChecksumGeneratorBase : ChecksumGenerator + { + /// + /// The value of the current checksum + /// + protected uint _current; + + /// + /// Initializes a new instance of the checksum generator base - the current checksum is + /// set to zero + /// + public ChecksumGeneratorBase() + { + _current = 0; + } + + /// + /// Initializes a new instance of the checksum generator basewith a specified value + /// + /// The value to set the current checksum to + public ChecksumGeneratorBase(uint initialValue) + { + _current = initialValue; + } + + /// + /// Resets the current checksum to zero + /// + public void Reset() { _current = 0; } + + /// + /// Gets the current checksum value + /// + public uint Value { get { return _current; } } + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + /// All the other Update methods are implmeneted in terms of this one. + /// This is therefore the only method a derived class has to implement + public abstract void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with an array of bytes. + /// + /// The data to update the checksum with + public void Update(byte[] data) + { + Update(data, 0, data.Length); + } + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + public void Update(string data) + { + Update(Encoding.UTF8.GetBytes(data)); + } + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + public void Update(string data, Encoding encoding) + { + Update(encoding.GetBytes(data)); + } + + } + #endregion + + #region CRC32 + /// + /// Implements a CRC32 checksum generator + /// + public sealed class CRC32Checksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint crc32(uint crc, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the CRC32 checksum generator + /// + public CRC32Checksum() : base() {} + + /// + /// Initializes a new instance of the CRC32 checksum generator with a specified value + /// + /// The value to set the current checksum to + public CRC32Checksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + + #region Adler + /// + /// Implements a checksum generator that computes the Adler checksum on data + /// + public sealed class AdlerChecksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint adler32(uint adler, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the Adler checksum generator + /// + public AdlerChecksum() : base() {} + + /// + /// Initializes a new instance of the Adler checksum generator with a specified value + /// + /// The value to set the current checksum to + public AdlerChecksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + +} \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/CircularBuffer.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/CircularBuffer.cs new file mode 100644 index 000000000..9c8d60195 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/CircularBuffer.cs @@ -0,0 +1,83 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; + +namespace DotZLib +{ + + /// + /// This class implements a circular buffer + /// + internal class CircularBuffer + { + #region Private data + private int _capacity; + private int _head; + private int _tail; + private int _size; + private byte[] _buffer; + #endregion + + public CircularBuffer(int capacity) + { + Debug.Assert( capacity > 0 ); + _buffer = new byte[capacity]; + _capacity = capacity; + _head = 0; + _tail = 0; + _size = 0; + } + + public int Size { get { return _size; } } + + public int Put(byte[] source, int offset, int count) + { + Debug.Assert( count > 0 ); + int trueCount = Math.Min(count, _capacity - Size); + for (int i = 0; i < trueCount; ++i) + _buffer[(_tail+i) % _capacity] = source[offset+i]; + _tail += trueCount; + _tail %= _capacity; + _size += trueCount; + return trueCount; + } + + public bool Put(byte b) + { + if (Size == _capacity) // no room + return false; + _buffer[_tail++] = b; + _tail %= _capacity; + ++_size; + return true; + } + + public int Get(byte[] destination, int offset, int count) + { + int trueCount = Math.Min(count,Size); + for (int i = 0; i < trueCount; ++i) + destination[offset + i] = _buffer[(_head+i) % _capacity]; + _head += trueCount; + _head %= _capacity; + _size -= trueCount; + return trueCount; + } + + public int Get() + { + if (Size == 0) + return -1; + + int result = (int)_buffer[_head++ % _capacity]; + --_size; + return result; + } + + } +} diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/CodecBase.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/CodecBase.cs new file mode 100644 index 000000000..b0eb78a02 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/CodecBase.cs @@ -0,0 +1,198 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements the common functionality needed for all s + /// + public abstract class CodecBase : Codec, IDisposable + { + + #region Data members + + /// + /// Instance of the internal zlib buffer structure that is + /// passed to all functions in the zlib dll + /// + internal ZStream _ztream = new ZStream(); + + /// + /// True if the object instance has been disposed, false otherwise + /// + protected bool _isDisposed = false; + + /// + /// The size of the internal buffers + /// + protected const int kBufferSize = 16384; + + private byte[] _outBuffer = new byte[kBufferSize]; + private byte[] _inBuffer = new byte[kBufferSize]; + + private GCHandle _hInput; + private GCHandle _hOutput; + + private uint _checksum = 0; + + #endregion + + /// + /// Initializes a new instance of the CodeBase class. + /// + public CodecBase() + { + try + { + _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned); + _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned); + } + catch (Exception) + { + CleanUp(false); + throw; + } + } + + + #region Codec Members + + /// + /// Occurs when more processed data are available. + /// + public event DataAvailableHandler DataAvailable; + + /// + /// Fires the event + /// + protected void OnDataAvailable() + { + if (_ztream.total_out > 0) + { + if (DataAvailable != null) + DataAvailable( _outBuffer, 0, (int)_ztream.total_out); + resetOutput(); + } + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + public void Add(byte[] data) + { + Add(data,0,data.Length); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + /// This must be implemented by a derived class + public abstract void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + /// This must be implemented by a derived class + public abstract void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + public uint Checksum { get { return _checksum; } } + + #endregion + + #region Destructor & IDisposable stuff + + /// + /// Destroys this instance + /// + ~CodecBase() + { + CleanUp(false); + } + + /// + /// Releases any unmanaged resources and calls the method of the derived class + /// + public void Dispose() + { + CleanUp(true); + } + + /// + /// Performs any codec specific cleanup + /// + /// This must be implemented by a derived class + protected abstract void CleanUp(); + + // performs the release of the handles and calls the dereived CleanUp() + private void CleanUp(bool isDisposing) + { + if (!_isDisposed) + { + CleanUp(); + if (_hInput.IsAllocated) + _hInput.Free(); + if (_hOutput.IsAllocated) + _hOutput.Free(); + + _isDisposed = true; + } + } + + + #endregion + + #region Helper methods + + /// + /// Copies a number of bytes to the internal codec buffer - ready for proccesing + /// + /// The byte array that contains the data to copy + /// The index of the first byte to copy + /// The number of bytes to copy from data + protected void copyInput(byte[] data, int startIndex, int count) + { + Array.Copy(data, startIndex, _inBuffer,0, count); + _ztream.next_in = _hInput.AddrOfPinnedObject(); + _ztream.total_in = 0; + _ztream.avail_in = (uint)count; + + } + + /// + /// Resets the internal output buffers to a known state - ready for processing + /// + protected void resetOutput() + { + _ztream.total_out = 0; + _ztream.avail_out = kBufferSize; + _ztream.next_out = _hOutput.AddrOfPinnedObject(); + } + + /// + /// Updates the running checksum property + /// + /// The new checksum value + protected void setChecksum(uint newSum) + { + _checksum = newSum; + } + #endregion + + } +} diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/Deflater.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/Deflater.cs new file mode 100644 index 000000000..9039f41f6 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/Deflater.cs @@ -0,0 +1,106 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data compressor, using the deflate algorithm in the ZLib dll + /// + public sealed class Deflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Deflater + /// + /// The compression level to use for this Deflater + public Deflater(CompressLevel level) : base() + { + int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize deflater"); + + resetOutput(); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + while (err >= 0 && _ztream.avail_in > 0) + { + err = deflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = deflate(ref _ztream, (int)FlushTypes.None); + } + inputIndex += (int)_ztream.total_in; + } + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = deflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + deflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib deflate stream + /// + protected override void CleanUp() { deflateEnd(ref _ztream); } + + } +} diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/DotZLib.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/DotZLib.cs new file mode 100644 index 000000000..90c7c3b38 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/DotZLib.cs @@ -0,0 +1,288 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + + #region Internal types + + /// + /// Defines constants for the various flush types used with zlib + /// + internal enum FlushTypes + { + None, Partial, Sync, Full, Finish, Block + } + + #region ZStream structure + // internal mapping of the zlib zstream structure for marshalling + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)] + internal struct ZStream + { + public IntPtr next_in; + public uint avail_in; + public uint total_in; + + public IntPtr next_out; + public uint avail_out; + public uint total_out; + + [MarshalAs(UnmanagedType.LPStr)] + string msg; + uint state; + + uint zalloc; + uint zfree; + uint opaque; + + int data_type; + public uint adler; + uint reserved; + } + + #endregion + + #endregion + + #region Public enums + /// + /// Defines constants for the available compression levels in zlib + /// + public enum CompressLevel : int + { + /// + /// The default compression level with a reasonable compromise between compression and speed + /// + Default = -1, + /// + /// No compression at all. The data are passed straight through. + /// + None = 0, + /// + /// The maximum compression rate available. + /// + Best = 9, + /// + /// The fastest available compression level. + /// + Fastest = 1 + } + #endregion + + #region Exception classes + /// + /// The exception that is thrown when an error occurs on the zlib dll + /// + public class ZLibException : ApplicationException + { + /// + /// Initializes a new instance of the class with a specified + /// error message and error code + /// + /// The zlib error code that caused the exception + /// A message that (hopefully) describes the error + public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg)) + { + } + + /// + /// Initializes a new instance of the class with a specified + /// error code + /// + /// The zlib error code that caused the exception + public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode)) + { + } + } + #endregion + + #region Interfaces + + /// + /// Declares methods and properties that enables a running checksum to be calculated + /// + public interface ChecksumGenerator + { + /// + /// Gets the current value of the checksum + /// + uint Value { get; } + + /// + /// Clears the current checksum to 0 + /// + void Reset(); + + /// + /// Updates the current checksum with an array of bytes + /// + /// The data to update the checksum with + void Update(byte[] data); + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + void Update(string data); + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + void Update(string data, Encoding encoding); + } + + + /// + /// Represents the method that will be called from a codec when new data + /// are available. + /// + /// The byte array containing the processed data + /// The index of the first processed byte in data + /// The number of processed bytes available + /// On return from this method, the data may be overwritten, so grab it while you can. + /// You cannot assume that startIndex will be zero. + /// + public delegate void DataAvailableHandler(byte[] data, int startIndex, int count); + + /// + /// Declares methods and events for implementing compressors/decompressors + /// + public interface Codec + { + /// + /// Occurs when more processed data are available. + /// + event DataAvailableHandler DataAvailable; + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data); + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + uint Checksum { get; } + + + } + + #endregion + + #region Classes + /// + /// Encapsulates general information about the ZLib library + /// + public class Info + { + #region DLL imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint zlibCompileFlags(); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern string zlibVersion(); + #endregion + + #region Private stuff + private uint _flags; + + // helper function that unpacks a bitsize mask + private static int bitSize(uint bits) + { + switch (bits) + { + case 0: return 16; + case 1: return 32; + case 2: return 64; + } + return -1; + } + #endregion + + /// + /// Constructs an instance of the Info class. + /// + public Info() + { + _flags = zlibCompileFlags(); + } + + /// + /// True if the library is compiled with debug info + /// + public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } } + + /// + /// True if the library is compiled with assembly optimizations + /// + public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } } + + /// + /// Gets the size of the unsigned int that was compiled into Zlib + /// + public int SizeOfUInt { get { return bitSize(_flags & 3); } } + + /// + /// Gets the size of the unsigned long that was compiled into Zlib + /// + public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } } + + /// + /// Gets the size of the pointers that were compiled into Zlib + /// + public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } } + + /// + /// Gets the size of the z_off_t type that was compiled into Zlib + /// + public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } } + + /// + /// Gets the version of ZLib as a string, e.g. "1.2.1" + /// + public static string Version { get { return zlibVersion(); } } + } + + #endregion + +} diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/DotZLib.csproj b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/DotZLib.csproj new file mode 100644 index 000000000..dea7fb16a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/DotZLib.csproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/GZipStream.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/GZipStream.cs new file mode 100644 index 000000000..f0eada1d2 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/GZipStream.cs @@ -0,0 +1,301 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements a compressed , in GZip (.gz) format. + /// + public class GZipStream : Stream, IDisposable + { + #region Dll Imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern IntPtr gzopen(string name, string mode); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzclose(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzwrite(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzread(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzgetc(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzputc(IntPtr gzFile, int c); + + #endregion + + #region Private data + private IntPtr _gzFile; + private bool _isDisposed = false; + private bool _isWriting; + #endregion + + #region Constructors + /// + /// Creates a new file as a writeable GZipStream + /// + /// The name of the compressed file to create + /// The compression level to use when adding data + /// If an error occurred in the internal zlib function + public GZipStream(string fileName, CompressLevel level) + { + _isWriting = true; + _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level)); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + } + + /// + /// Opens an existing file as a readable GZipStream + /// + /// The name of the file to open + /// If an error occurred in the internal zlib function + public GZipStream(string fileName) + { + _isWriting = false; + _gzFile = gzopen(fileName, "rb"); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + + } + #endregion + + #region Access properties + /// + /// Returns true of this stream can be read from, false otherwise + /// + public override bool CanRead + { + get + { + return !_isWriting; + } + } + + + /// + /// Returns false. + /// + public override bool CanSeek + { + get + { + return false; + } + } + + /// + /// Returns true if this tsream is writeable, false otherwise + /// + public override bool CanWrite + { + get + { + return _isWriting; + } + } + #endregion + + #region Destructor & IDispose stuff + + /// + /// Destroys this instance + /// + ~GZipStream() + { + cleanUp(false); + } + + /// + /// Closes the external file handle + /// + public void Dispose() + { + cleanUp(true); + } + + // Does the actual closing of the file handle. + private void cleanUp(bool isDisposing) + { + if (!_isDisposed) + { + gzclose(_gzFile); + _isDisposed = true; + } + } + #endregion + + #region Basic reading and writing + /// + /// Attempts to read a number of bytes from the stream. + /// + /// The destination data buffer + /// The index of the first destination byte in buffer + /// The number of bytes requested + /// The number of bytes read + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not readable. + /// If this stream has been disposed. + public override int Read(byte[] buffer, int offset, int count) + { + if (!CanRead) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + int result; + try + { + result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + return result; + } + + /// + /// Attempts to read a single byte from the stream. + /// + /// The byte that was read, or -1 in case of error or End-Of-File + public override int ReadByte() + { + if (!CanRead) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + return gzgetc(_gzFile); + } + + /// + /// Writes a number of bytes to the stream + /// + /// + /// + /// + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void Write(byte[] buffer, int offset, int count) + { + if (!CanWrite) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + try + { + int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + } + + /// + /// Writes a single byte to the stream + /// + /// The byte to add to the stream. + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void WriteByte(byte value) + { + if (!CanWrite) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + int result = gzputc(_gzFile, (int)value); + if (result < 0) + throw new IOException(); + } + #endregion + + #region Position & length stuff + /// + /// Not supported. + /// + /// + /// Always thrown + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + /// + /// Not suppported. + /// + /// + /// + /// + /// Always thrown + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + /// + /// Flushes the GZipStream. + /// + /// In this implementation, this method does nothing. This is because excessive + /// flushing may degrade the achievable compression rates. + public override void Flush() + { + // left empty on purpose + } + + /// + /// Gets/sets the current position in the GZipStream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Position + { + get + { + throw new NotSupportedException(); + } + set + { + throw new NotSupportedException(); + } + } + + /// + /// Gets the size of the stream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Length + { + get + { + throw new NotSupportedException(); + } + } + #endregion + } +} diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/Inflater.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/Inflater.cs new file mode 100644 index 000000000..d295f2680 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/Inflater.cs @@ -0,0 +1,105 @@ +// +// Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data decompressor, using the inflate algorithm in the ZLib dll + /// + public class Inflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int inflateInit_(ref ZStream sz, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Inflater + /// + public Inflater() : base() + { + int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize inflater"); + + resetOutput(); + } + + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + err = inflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = inflate(ref _ztream, (int)FlushTypes.None); + } + + inputIndex += (int)_ztream.total_in; + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = inflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + inflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib inflate stream + /// + protected override void CleanUp() { inflateEnd(ref _ztream); } + + + } +} diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/UnitTests.cs b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/UnitTests.cs new file mode 100644 index 000000000..6d8aebb79 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/DotZLib/UnitTests.cs @@ -0,0 +1,274 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Collections; +using System.IO; + +// uncomment the define below to include unit tests +//#define nunit +#if nunit +using NUnit.Framework; + +// Unit tests for the DotZLib class library +// ---------------------------------------- +// +// Use this with NUnit 2 from http://www.nunit.org +// + +namespace DotZLibTests +{ + using DotZLib; + + // helper methods + internal class Utils + { + public static bool byteArrEqual( byte[] lhs, byte[] rhs ) + { + if (lhs.Length != rhs.Length) + return false; + for (int i = lhs.Length-1; i >= 0; --i) + if (lhs[i] != rhs[i]) + return false; + return true; + } + + } + + + [TestFixture] + public class CircBufferTests + { + #region Circular buffer tests + [Test] + public void SinglePutGet() + { + CircularBuffer buf = new CircularBuffer(10); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + + Assert.IsTrue(buf.Put( 1 )); + Assert.AreEqual( 1, buf.Size ); + Assert.AreEqual( 1, buf.Get() ); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + } + + [Test] + public void BlockPutGet() + { + CircularBuffer buf = new CircularBuffer(10); + byte[] arr = {1,2,3,4,5,6,7,8,9,10}; + Assert.AreEqual( 10, buf.Put(arr,0,10) ); + Assert.AreEqual( 10, buf.Size ); + Assert.IsFalse( buf.Put(11) ); + Assert.AreEqual( 1, buf.Get() ); + Assert.IsTrue( buf.Put(11) ); + + byte[] arr2 = (byte[])arr.Clone(); + Assert.AreEqual( 9, buf.Get(arr2,1,9) ); + Assert.IsTrue( Utils.byteArrEqual(arr,arr2) ); + } + + #endregion + } + + [TestFixture] + public class ChecksumTests + { + #region CRC32 Tests + [Test] + public void CRC32_Null() + { + CRC32Checksum crc32 = new CRC32Checksum(); + Assert.AreEqual( 0, crc32.Value ); + + crc32 = new CRC32Checksum(1); + Assert.AreEqual( 1, crc32.Value ); + + crc32 = new CRC32Checksum(556); + Assert.AreEqual( 556, crc32.Value ); + } + + [Test] + public void CRC32_Data() + { + CRC32Checksum crc32 = new CRC32Checksum(); + byte[] data = { 1,2,3,4,5,6,7 }; + crc32.Update(data); + Assert.AreEqual( 0x70e46888, crc32.Value ); + + crc32 = new CRC32Checksum(); + crc32.Update("penguin"); + Assert.AreEqual( 0x0e5c1a120, crc32.Value ); + + crc32 = new CRC32Checksum(1); + crc32.Update("penguin"); + Assert.AreEqual(0x43b6aa94, crc32.Value); + + } + #endregion + + #region Adler tests + + [Test] + public void Adler_Null() + { + AdlerChecksum adler = new AdlerChecksum(); + Assert.AreEqual(0, adler.Value); + + adler = new AdlerChecksum(1); + Assert.AreEqual( 1, adler.Value ); + + adler = new AdlerChecksum(556); + Assert.AreEqual( 556, adler.Value ); + } + + [Test] + public void Adler_Data() + { + AdlerChecksum adler = new AdlerChecksum(1); + byte[] data = { 1,2,3,4,5,6,7 }; + adler.Update(data); + Assert.AreEqual( 0x5b001d, adler.Value ); + + adler = new AdlerChecksum(); + adler.Update("penguin"); + Assert.AreEqual(0x0bcf02f6, adler.Value ); + + adler = new AdlerChecksum(1); + adler.Update("penguin"); + Assert.AreEqual(0x0bd602f7, adler.Value); + + } + #endregion + } + + [TestFixture] + public class InfoTests + { + #region Info tests + [Test] + public void Info_Version() + { + Info info = new Info(); + Assert.AreEqual("1.2.11", Info.Version); + Assert.AreEqual(32, info.SizeOfUInt); + Assert.AreEqual(32, info.SizeOfULong); + Assert.AreEqual(32, info.SizeOfPointer); + Assert.AreEqual(32, info.SizeOfOffset); + } + #endregion + } + + [TestFixture] + public class DeflateInflateTests + { + #region Deflate tests + [Test] + public void Deflate_Init() + { + using (Deflater def = new Deflater(CompressLevel.Default)) + { + } + } + + private ArrayList compressedData = new ArrayList(); + private uint adler1; + + private ArrayList uncompressedData = new ArrayList(); + private uint adler2; + + public void CDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + compressedData.Add(data[i+startIndex]); + } + + [Test] + public void Deflate_Compress() + { + compressedData.Clear(); + + byte[] testData = new byte[35000]; + for (int i = 0; i < testData.Length; ++i) + testData[i] = 5; + + using (Deflater def = new Deflater((CompressLevel)5)) + { + def.DataAvailable += new DataAvailableHandler(CDataAvail); + def.Add(testData); + def.Finish(); + adler1 = def.Checksum; + } + } + #endregion + + #region Inflate tests + [Test] + public void Inflate_Init() + { + using (Inflater inf = new Inflater()) + { + } + } + + private void DDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + uncompressedData.Add(data[i+startIndex]); + } + + [Test] + public void Inflate_Expand() + { + uncompressedData.Clear(); + + using (Inflater inf = new Inflater()) + { + inf.DataAvailable += new DataAvailableHandler(DDataAvail); + inf.Add((byte[])compressedData.ToArray(typeof(byte))); + inf.Finish(); + adler2 = inf.Checksum; + } + Assert.AreEqual( adler1, adler2 ); + } + #endregion + } + + [TestFixture] + public class GZipStreamTests + { + #region GZipStream test + [Test] + public void GZipStream_WriteRead() + { + using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best)) + { + BinaryWriter writer = new BinaryWriter(gzOut); + writer.Write("hi there"); + writer.Write(Math.PI); + writer.Write(42); + } + + using (GZipStream gzIn = new GZipStream("gzstream.gz")) + { + BinaryReader reader = new BinaryReader(gzIn); + string s = reader.ReadString(); + Assert.AreEqual("hi there",s); + double d = reader.ReadDouble(); + Assert.AreEqual(Math.PI, d); + int i = reader.ReadInt32(); + Assert.AreEqual(42,i); + } + + } + #endregion + } +} + +#endif diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/LICENSE_1_0.txt b/src/external/zlib-1.2.11/contrib/dotzlib/LICENSE_1_0.txt new file mode 100644 index 000000000..127a5bc39 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/dotzlib/readme.txt b/src/external/zlib-1.2.11/contrib/dotzlib/readme.txt new file mode 100644 index 000000000..4d8c2dd93 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/dotzlib/readme.txt @@ -0,0 +1,58 @@ +This directory contains a .Net wrapper class library for the ZLib1.dll + +The wrapper includes support for inflating/deflating memory buffers, +.Net streaming wrappers for the gz streams part of zlib, and wrappers +for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples. + +Directory structure: +-------------------- + +LICENSE_1_0.txt - License file. +readme.txt - This file. +DotZLib.chm - Class library documentation +DotZLib.build - NAnt build file +DotZLib.sln - Microsoft Visual Studio 2003 solution file + +DotZLib\*.cs - Source files for the class library + +Unit tests: +----------- +The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher. +To include unit tests in the build, define nunit before building. + + +Build instructions: +------------------- + +1. Using Visual Studio.Net 2003: + Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll) + will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on + you are building the release or debug version of the library. Check + DotZLib/UnitTests.cs for instructions on how to include unit tests in the + build. + +2. Using NAnt: + Open a command prompt with access to the build environment and run nant + in the same directory as the DotZLib.build file. + You can define 2 properties on the nant command-line to control the build: + debug={true|false} to toggle between release/debug builds (default=true). + nunit={true|false} to include or esclude unit tests (default=true). + Also the target clean will remove binaries. + Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release + or ./DotZLib/bin/debug, depending on whether you are building the release + or debug version of the library. + + Examples: + nant -D:debug=false -D:nunit=false + will build a release mode version of the library without unit tests. + nant + will build a debug version of the library with unit tests + nant clean + will remove all previously built files. + + +--------------------------------- +Copyright (c) Henrik Ravn 2004 + +Use, modification and distribution are subject to the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/src/external/zlib-1.2.11/contrib/gcc_gvmat64/gvmat64.S b/src/external/zlib-1.2.11/contrib/gcc_gvmat64/gvmat64.S new file mode 100644 index 000000000..23309fa28 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/gcc_gvmat64/gvmat64.S @@ -0,0 +1,574 @@ +/* +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); // current match + +; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64 +; (AMD64 on Athlon 64, Opteron, Phenom +; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7) +; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode) +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software +; 3. This notice may not be removed or altered from any source distribution. +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for zLib, I use option: +; gcc -c -arch x86_64 gvmat64.S + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; // current match / +; +; with XCode for Mac, I had strange error with some jump on intel syntax +; this is why BEFORE_JMP and AFTER_JMP are used + */ + + +#define BEFORE_JMP .att_syntax +#define AFTER_JMP .intel_syntax noprefix + +#ifndef NO_UNDERLINE +# define match_init _match_init +# define longest_match _longest_match +#endif + +.intel_syntax noprefix + +.globl match_init, longest_match +.text +longest_match: + + + +#define LocalVarsSize 96 +/* +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp +*/ + +#define chainlenwmask (rsp + 8 - LocalVarsSize) +#define nicematch (rsp + 16 - LocalVarsSize) + +#define save_rdi (rsp + 24 - LocalVarsSize) +#define save_rsi (rsp + 32 - LocalVarsSize) +#define save_rbx (rsp + 40 - LocalVarsSize) +#define save_rbp (rsp + 48 - LocalVarsSize) +#define save_r12 (rsp + 56 - LocalVarsSize) +#define save_r13 (rsp + 64 - LocalVarsSize) +#define save_r14 (rsp + 72 - LocalVarsSize) +#define save_r15 (rsp + 80 - LocalVarsSize) + + +/* +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure +*/ + +#define MAX_MATCH 258 +#define MIN_MATCH 3 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) + +/* +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). +*/ + + + +/* you can check the structure offset by running + +#include +#include +#include "deflate.h" + +void print_depl() +{ +deflate_state ds; +deflate_state *s=&ds; +printf("size pointer=%u\n",(int)sizeof(void*)); + +printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s))); +printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s))); +printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s))); +printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s))); +printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s))); +printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s))); +printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s))); +printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s))); +printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s))); +printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s))); +printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s))); +printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s))); +printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s))); +} +*/ + +#define dsWSize 68 +#define dsWMask 76 +#define dsWindow 80 +#define dsPrev 96 +#define dsMatchLen 144 +#define dsPrevMatch 148 +#define dsStrStart 156 +#define dsMatchStart 160 +#define dsLookahead 164 +#define dsPrevLen 168 +#define dsMaxChainLen 172 +#define dsGoodMatch 188 +#define dsNiceMatch 192 + +#define window_size [ rcx + dsWSize] +#define WMask [ rcx + dsWMask] +#define window_ad [ rcx + dsWindow] +#define prev_ad [ rcx + dsPrev] +#define strstart [ rcx + dsStrStart] +#define match_start [ rcx + dsMatchStart] +#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip +#define prev_length [ rcx + dsPrevLen] +#define max_chain_length [ rcx + dsMaxChainLen] +#define good_match [ rcx + dsGoodMatch] +#define nice_match [ rcx + dsNiceMatch] + +/* +; windows: +; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + +; +; gcc on macosx-linux: +; see http://www.x86-64.org/documentation/abi-0.99.pdf +; param 1 in rdi, param 2 in rsi +; rbx, rsp, rbp, r12 to r15 must be preserved + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) +; mac: param 1 in rdi, param 2 rsi +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx +*/ + mov [save_rbx],rbx + mov [save_rbp],rbp + + + mov rcx,rdi + + mov r8d,esi + + + mov [save_r12],r12 + mov [save_r13],r13 + mov [save_r14],r14 + mov [save_r15],r15 + + +//;;; uInt wmask = s->w_mask; +//;;; unsigned chain_length = s->max_chain_length; +//;;; if (s->prev_length >= s->good_match) { +//;;; chain_length >>= 2; +//;;; } + + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +//;;; chainlen is decremented once beforehand so that the function can +//;;; use the sign flag instead of the zero flag for the exit test. +//;;; It is then shifted into the high word, to make room for the wmask +//;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +//;;; on zlib only +//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + + + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d + + + +//;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +//;;; Determine how many bytes the scan ptr is off from being +//;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +//;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + + mov eax, window_size + sub eax, MIN_LOOKAHEAD + + + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +//;;; int best_len = s->prev_length; + + +//;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +//;;; register ush scan_start = *(ushf*)scan; +//;;; register ush scan_end = *(ushf*)(scan+best_len-1); +//;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +//;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + + + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + + + + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jz LookupLoopIsZero + AFTER_JMP + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jz LookupLoopIsZero + AFTER_JMP + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jnz LookupLoop1 + jmp LookupLoopIsZero + AFTER_JMP +/* +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit +*/ +.balign 16 +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jnz LookupLoop1 + AFTER_JMP +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + BEFORE_JMP + jnz LookupLoop1 + AFTER_JMP + + +//;;; Store the current value of chainlen. + mov [chainlenwmask], edx +/* +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). +*/ + lea rsi,[r8+r10] + mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + +/* +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. +*/ + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + BEFORE_JMP + jnz LoopCmps + jmp LenMaximum + AFTER_JMP + +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0x0000FFFF + jnz LenLower + + test eax,0xffffffff + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + BEFORE_JMP + jnz LenLower + AFTER_JMP + +LenLower32: + shr eax,16 + add rdx,2 + +LenLower: + sub al, 1 + adc rdx, 0 +//;;; Calculate the length of the match. If it is longer than MAX_MATCH, +//;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + BEFORE_JMP + jge LenMaximum + AFTER_JMP +/* +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// +*/ + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + BEFORE_JMP + jmp LookupLoop + AFTER_JMP +/* +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); +*/ +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + BEFORE_JMP + jge LeaveNow + AFTER_JMP + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + BEFORE_JMP + jmp LookupLoop + AFTER_JMP + +//;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +//;;; return s->lookahead; + +LeaveNow: + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d + + + +//;;; Restore the stack and return from whence we came. + + +// mov rsi,[save_rsi] +// mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] + mov r14,[save_r14] + mov r15,[save_r15] + + + ret 0 +//; please don't remove this string ! +//; Your can freely use gvmat64 in any free or commercial app +//; but it is far better don't remove the string in the binary! + // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 + + +match_init: + ret 0 + + diff --git a/src/external/zlib-1.2.11/contrib/infback9/README b/src/external/zlib-1.2.11/contrib/infback9/README new file mode 100644 index 000000000..e75ed1329 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/README @@ -0,0 +1 @@ +See infback9.h for what this is and how to use it. diff --git a/src/external/zlib-1.2.11/contrib/infback9/infback9.c b/src/external/zlib-1.2.11/contrib/infback9/infback9.c new file mode 100644 index 000000000..05fb3e338 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/infback9.c @@ -0,0 +1,615 @@ +/* infback9.c -- inflate deflate64 data using a call-back interface + * Copyright (C) 1995-2008 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infback9.h" +#include "inftree9.h" +#include "inflate9.h" + +#define WSIZE 65536UL + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + window is a user-supplied window and output buffer that is 64K bytes. + */ +int ZEXPORT inflateBack9Init_(strm, window, version, stream_size) +z_stream FAR *strm; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (voidpf)state; + state->window = window; + return Z_OK; +} + +/* + Build and output length and distance decoding tables for fixed code + decoding. + */ +#ifdef MAKEFIXED +#include + +void makefixed9(void) +{ + unsigned sym, bits, low, size; + code *next, *lenfix, *distfix; + struct inflate_state state; + code fixed[544]; + + /* literal/length table */ + sym = 0; + while (sym < 144) state.lens[sym++] = 8; + while (sym < 256) state.lens[sym++] = 9; + while (sym < 280) state.lens[sym++] = 7; + while (sym < 288) state.lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work); + + /* distance table */ + sym = 0; + while (sym < 32) state.lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work); + + /* write tables */ + puts(" /* inffix9.h -- table for decoding deflate64 fixed codes"); + puts(" * Generated automatically by makefixed9()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits, + lenfix[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 5) == 0) printf("\n "); + printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits, + distfix[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* Macros for inflateBack(): */ + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n <= 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = window; \ + left = WSIZE; \ + wrap = 1; \ + if (out(out_desc, put, (unsigned)left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc) +z_stream FAR *strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have; /* available input */ + unsigned long left; /* available output */ + inflate_mode mode; /* current inflate mode */ + int lastblock; /* true if processing last block */ + int wrap; /* true if the window has wrapped */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned extra; /* extra bits needed */ + unsigned long length; /* literal or length of data to copy */ + unsigned long offset; /* distance back to copy string from */ + unsigned long copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +#include "inffix9.h" + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + mode = TYPE; + lastblock = 0; + wrap = 0; + window = state->window; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = window; + left = WSIZE; + lencode = Z_NULL; + distcode = Z_NULL; + + /* Inflate until end of block marked as last */ + for (;;) + switch (mode) { + case TYPE: + /* determine and dispatch block type */ + if (lastblock) { + BYTEBITS(); + mode = DONE; + break; + } + NEEDBITS(3); + lastblock = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + lastblock ? " (last)" : "")); + mode = STORED; + break; + case 1: /* fixed block */ + lencode = lenfix; + lenbits = 9; + distcode = distfix; + distbits = 5; + Tracev((stderr, "inflate: fixed codes block%s\n", + lastblock ? " (last)" : "")); + mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + lastblock ? " (last)" : "")); + mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + mode = BAD; + break; + } + length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %lu\n", + length)); + INITBITS(); + + /* copy stored block from input to output */ + while (length != 0) { + copy = length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); + if (state->nlen > 286) { + strm->msg = (char *)"too many length symbols"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + lencode = (code const FAR *)(state->next); + lenbits = 7; + ret = inflate_table9(CODES, state->lens, 19, &(state->next), + &(lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = lencode[BITS(lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftree9.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + lencode = (code const FAR *)(state->next); + lenbits = 9; + ret = inflate_table9(LENS, state->lens, state->nlen, + &(state->next), &(lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + mode = BAD; + break; + } + distcode = (code const FAR *)(state->next); + distbits = 6; + ret = inflate_table9(DISTS, state->lens + state->nlen, + state->ndist, &(state->next), &(distbits), + state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + mode = LEN; + + case LEN: + /* get a literal, length, or end-of-block code */ + for (;;) { + here = lencode[BITS(lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(length); + left--; + mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + extra = (unsigned)(here.op) & 31; + if (extra != 0) { + NEEDBITS(extra); + length += BITS(extra); + DROPBITS(extra); + } + Tracevv((stderr, "inflate: length %lu\n", length)); + + /* get distance code */ + for (;;) { + here = distcode[BITS(distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + mode = BAD; + break; + } + offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + extra = (unsigned)(here.op) & 15; + if (extra != 0) { + NEEDBITS(extra); + offset += BITS(extra); + DROPBITS(extra); + } + if (offset > WSIZE - (wrap ? 0: left)) { + strm->msg = (char *)"invalid distance too far back"; + mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %lu\n", offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = WSIZE - offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - offset; + copy = left; + } + if (copy > length) copy = length; + length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < WSIZE) { + if (out(out_desc, window, (unsigned)(WSIZE - left))) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBack9End(strm) +z_stream FAR *strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/src/external/zlib-1.2.11/contrib/infback9/infback9.h b/src/external/zlib-1.2.11/contrib/infback9/infback9.h new file mode 100644 index 000000000..1073c0a38 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/infback9.h @@ -0,0 +1,37 @@ +/* infback9.h -- header for using inflateBack9 functions + * Copyright (C) 2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * This header file and associated patches provide a decoder for PKWare's + * undocumented deflate64 compression method (method 9). Use with infback9.c, + * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported. + * This should be compiled with zlib, since it uses zutil.h and zutil.o. + * This code has not yet been tested on 16-bit architectures. See the + * comments in zlib.h for inflateBack() usage. These functions are used + * identically, except that there is no windowBits parameter, and a 64K + * window must be provided. Also if int's are 16 bits, then a zero for + * the third parameter of the "out" function actually means 65536UL. + * zlib.h must be included before this header file. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm)); +ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define inflateBack9Init(strm, window) \ + inflateBack9Init_((strm), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +#ifdef __cplusplus +} +#endif diff --git a/src/external/zlib-1.2.11/contrib/infback9/inffix9.h b/src/external/zlib-1.2.11/contrib/infback9/inffix9.h new file mode 100644 index 000000000..ee5671d2d --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/inffix9.h @@ -0,0 +1,107 @@ + /* inffix9.h -- table for decoding deflate64 fixed codes + * Generated automatically by makefixed9(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112}, + {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160}, + {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88}, + {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208}, + {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136}, + {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227}, + {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232}, + {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124}, + {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184}, + {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82}, + {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196}, + {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130}, + {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148}, + {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106}, + {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244}, + {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118}, + {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172}, + {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94}, + {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220}, + {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131}, + {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97}, + {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226}, + {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121}, + {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178}, + {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85}, + {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202}, + {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133}, + {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154}, + {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109}, + {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250}, + {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115}, + {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166}, + {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91}, + {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214}, + {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139}, + {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0}, + {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103}, + {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238}, + {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127}, + {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80}, + {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193}, + {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128}, + {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145}, + {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104}, + {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241}, + {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116}, + {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169}, + {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92}, + {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217}, + {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140}, + {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163}, + {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98}, + {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122}, + {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181}, + {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86}, + {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205}, + {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134}, + {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157}, + {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253}, + {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113}, + {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163}, + {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89}, + {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211}, + {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137}, + {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3}, + {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101}, + {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235}, + {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125}, + {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187}, + {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83}, + {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199}, + {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151}, + {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107}, + {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247}, + {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119}, + {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175}, + {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95}, + {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223}, + {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143}, + {0,8,79},{0,9,255} + }; + + static const code distfix[32] = { + {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5}, + {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513}, + {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129}, + {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145}, + {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4}, + {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073}, + {134,5,193},{142,5,49153} + }; diff --git a/src/external/zlib-1.2.11/contrib/infback9/inflate9.h b/src/external/zlib-1.2.11/contrib/infback9/inflate9.h new file mode 100644 index 000000000..ee9a79394 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/inflate9.h @@ -0,0 +1,47 @@ +/* inflate9.h -- internal inflate state definition + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Possible inflate modes between inflate() calls */ +typedef enum { + TYPE, /* i: waiting for type bits, including last-flag bit */ + STORED, /* i: waiting for stored size (length and complement) */ + TABLE, /* i: waiting for dynamic block table lengths */ + LEN, /* i: waiting for length/lit code */ + DONE, /* finished check, done -- remain here until reset */ + BAD /* got a data error -- remain here until reset */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD mode -- not shown for clarity) + + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or DONE + STORED -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LEN or TYPE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + /* sliding window */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/src/external/zlib-1.2.11/contrib/infback9/inftree9.c b/src/external/zlib-1.2.11/contrib/infback9/inftree9.c new file mode 100644 index 000000000..5f4a76798 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/inftree9.c @@ -0,0 +1,324 @@ +/* inftree9.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftree9.h" + +#define MAXBITS 15 + +const char inflate9_copyright[] = + " inflate9 1.2.11 Copyright 1995-2017 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table9(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, + 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, + 131, 163, 195, 227, 3, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, + 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, + 133, 133, 133, 133, 144, 77, 202}; + static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, + 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, + 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153}; + static const unsigned short dext[32] = { /* Distance codes 0..31 extra */ + 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, + 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, + 139, 139, 140, 140, 141, 141, 142, 142}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) return -1; /* no codes! */ + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftree9.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += 1U << curr; + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + curr = root; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/src/external/zlib-1.2.11/contrib/infback9/inftree9.h b/src/external/zlib-1.2.11/contrib/infback9/inftree9.h new file mode 100644 index 000000000..5ab21f0c6 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/infback9/inftree9.h @@ -0,0 +1,61 @@ +/* inftree9.h -- header to use inftree9.c + * Copyright (C) 1995-2008 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 100eeeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1446, which is the sum of 852 for literal/length codes and 594 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 32 6 15" for distance codes returns 594. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in infback9.c. If the root table size is changed, + then these maximum sizes would be need to be recalculated and updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 594 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table9() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table9 OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/src/external/zlib-1.2.11/contrib/inflate86/inffas86.c b/src/external/zlib-1.2.11/contrib/inflate86/inffas86.c new file mode 100644 index 000000000..7292f67b7 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/inflate86/inffas86.c @@ -0,0 +1,1157 @@ +/* inffas86.c is a hand tuned assembler version of + * + * inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } ar; + +#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 ) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->wnext; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + +#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 ) + __asm__ __volatile__ ( +" leaq %0, %%rax\n" +" movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */ +" movq %%rsp, (%%rax)\n" +" movq %%rax, %%rsp\n" /* make rsp point to &ar */ +" movq 16(%%rsp), %%rsi\n" /* rsi = in */ +" movq 32(%%rsp), %%rdi\n" /* rdi = out */ +" movq 24(%%rsp), %%r9\n" /* r9 = last */ +" movq 48(%%rsp), %%r10\n" /* r10 = end */ +" movq 64(%%rsp), %%rbp\n" /* rbp = lcode */ +" movq 72(%%rsp), %%r11\n" /* r11 = dcode */ +" movq 80(%%rsp), %%rdx\n" /* rdx = hold */ +" movl 88(%%rsp), %%ebx\n" /* ebx = bits */ +" movl 100(%%rsp), %%r12d\n" /* r12d = lmask */ +" movl 104(%%rsp), %%r13d\n" /* r13d = dmask */ + /* r14d = len */ + /* r15d = dist */ +" cld\n" +" cmpq %%rdi, %%r10\n" +" je .L_one_time\n" /* if only one decode left */ +" cmpq %%rsi, %%r9\n" +" je .L_one_time\n" +" jmp .L_do_loop\n" + +".L_one_time:\n" +" movq %%r12, %%r8\n" /* r8 = lmask */ +" cmpb $32, %%bl\n" +" ja .L_get_length_code_one_time\n" + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ +" jmp .L_get_length_code_one_time\n" + +".align 32,0x90\n" +".L_while_test:\n" +" cmpq %%rdi, %%r10\n" +" jbe .L_break_loop\n" +" cmpq %%rsi, %%r9\n" +" jbe .L_break_loop\n" + +".L_do_loop:\n" +" movq %%r12, %%r8\n" /* r8 = lmask */ +" cmpb $32, %%bl\n" +" ja .L_get_length_code\n" /* if (32 < bits) */ + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ + +".L_get_length_code:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" movq %%r12, %%r8\n" /* r8 = lmask */ +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" + +".L_get_length_code_one_time:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +".L_dolen:\n" +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_length_base:\n" +" movl %%eax, %%r14d\n" /* len = this */ +" shrl $16, %%r14d\n" /* len = this.val */ +" movb %%al, %%cl\n" + +" testb $16, %%al\n" +" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */ +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_decode_distance\n" /* if (!op) */ + +".L_add_bits_to_len:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrq %%cl, %%rdx\n" +" addl %%eax, %%r14d\n" /* len += hold & mask[op] */ + +".L_decode_distance:\n" +" movq %%r13, %%r8\n" /* r8 = dmask */ +" cmpb $32, %%bl\n" +" ja .L_get_distance_code\n" /* if (32 < bits) */ + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ + +".L_get_distance_code:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */ + +".L_dodist:\n" +" movl %%eax, %%r15d\n" /* dist = this */ +" shrl $16, %%r15d\n" /* dist = this.val */ +" movb %%ah, %%cl\n" +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ +" movb %%al, %%cl\n" /* cl = this.op */ + +" testb $16, %%al\n" /* if ((op & 16) == 0) */ +" jz .L_test_for_second_level_dist\n" +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_check_dist_one\n" + +".L_add_bits_to_dist:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" /* (1 << op) - 1 */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrq %%cl, %%rdx\n" +" addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */ + +".L_check_window:\n" +" movq %%rsi, %%r8\n" /* save in so from can use it's reg */ +" movq %%rdi, %%rax\n" +" subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */ + +" cmpl %%r15d, %%eax\n" +" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ + +" movl %%r14d, %%ecx\n" /* ecx = len */ +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ + +" sarl %%ecx\n" +" jnc .L_copy_two\n" /* if len % 2 == 0 */ + +" rep movsw\n" +" movb (%%rsi), %%al\n" +" movb %%al, (%%rdi)\n" +" incq %%rdi\n" + +" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */ +" jmp .L_while_test\n" + +".L_copy_two:\n" +" rep movsw\n" +" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_check_dist_one:\n" +" cmpl $1, %%r15d\n" /* if dist 1, is a memset */ +" jne .L_check_window\n" +" cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */ +" je .L_check_window\n" + +" movl %%r14d, %%ecx\n" /* ecx = len */ +" movb -1(%%rdi), %%al\n" +" movb %%al, %%ah\n" + +" sarl %%ecx\n" +" jnc .L_set_two\n" +" movb %%al, (%%rdi)\n" +" incq %%rdi\n" + +".L_set_two:\n" +" rep stosw\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_second_level_length:\n" +" testb $64, %%al\n" +" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%r14d, %%eax\n" /* eax += len */ +" movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ +" jmp .L_dolen\n" + +".align 32,0x90\n" +".L_test_for_second_level_dist:\n" +" testb $64, %%al\n" +" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%r15d, %%eax\n" /* eax += dist */ +" movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ +" jmp .L_dodist\n" + +".align 32,0x90\n" +".L_clip_window:\n" +" movl %%eax, %%ecx\n" /* ecx = nbytes */ +" movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */ +" negl %%ecx\n" /* nbytes = -nbytes */ + +" cmpl %%r15d, %%eax\n" +" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ + +" addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */ +" cmpl $0, 96(%%rsp)\n" +" jne .L_wrap_around_window\n" /* if (write != 0) */ + +" movq 56(%%rsp), %%rsi\n" /* from = window */ +" subl %%ecx, %%eax\n" /* eax -= nbytes */ +" addq %%rax, %%rsi\n" /* from += wsize - nbytes */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%r14d\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* eax -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = &out[ -dist ] */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_wrap_around_window:\n" +" movl 96(%%rsp), %%eax\n" /* eax = write */ +" cmpl %%eax, %%ecx\n" +" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ + +" movl 92(%%rsp), %%esi\n" /* from = wsize */ +" addq 56(%%rsp), %%rsi\n" /* from += window */ +" addq %%rax, %%rsi\n" /* from += write */ +" subq %%rcx, %%rsi\n" /* from -= nbytes */ +" subl %%eax, %%ecx\n" /* nbytes -= write */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq 56(%%rsp), %%rsi\n" /* from = window */ +" movl 96(%%rsp), %%ecx\n" /* nbytes = write */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_contiguous_in_window:\n" +" movq 56(%%rsp), %%rsi\n" /* rsi = window */ +" addq %%rax, %%rsi\n" +" subq %%rcx, %%rsi\n" /* from += write - nbytes */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ +" jmp .L_do_copy\n" /* if (nbytes >= len) */ + +".align 32,0x90\n" +".L_do_copy:\n" +" movl %%eax, %%ecx\n" /* ecx = len */ +" rep movsb\n" + +" movq %%r8, %%rsi\n" /* move in back to %esi, toss from */ +" jmp .L_while_test\n" + +".L_test_for_end_of_block:\n" +" testb $32, %%al\n" +" jz .L_invalid_literal_length_code\n" +" movl $1, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_literal_length_code:\n" +" movl $2, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_code:\n" +" movl $3, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_too_far:\n" +" movl $4, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_break_loop:\n" +" movl $0, 116(%%rsp)\n" + +".L_break_loop_with_status:\n" +/* put in, out, bits, and hold back into ar and pop esp */ +" movq %%rsi, 16(%%rsp)\n" /* in */ +" movq %%rdi, 32(%%rsp)\n" /* out */ +" movl %%ebx, 88(%%rsp)\n" /* bits */ +" movq %%rdx, 80(%%rsp)\n" /* hold */ +" movq (%%rsp), %%rax\n" /* restore rbp and rsp */ +" movq 8(%%rsp), %%rbp\n" +" movq %%rax, %%rsp\n" + : + : "m" (ar) + : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" + ); +#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 ) + __asm__ __volatile__ ( +" leal %0, %%eax\n" +" movl %%esp, (%%eax)\n" /* save esp, ebp */ +" movl %%ebp, 4(%%eax)\n" +" movl %%eax, %%esp\n" +" movl 8(%%esp), %%esi\n" /* esi = in */ +" movl 16(%%esp), %%edi\n" /* edi = out */ +" movl 40(%%esp), %%edx\n" /* edx = hold */ +" movl 44(%%esp), %%ebx\n" /* ebx = bits */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ + +" cld\n" +" jmp .L_do_loop\n" + +".align 32,0x90\n" +".L_while_test:\n" +" cmpl %%edi, 24(%%esp)\n" /* out < end */ +" jbe .L_break_loop\n" +" cmpl %%esi, 12(%%esp)\n" /* in < last */ +" jbe .L_break_loop\n" + +".L_do_loop:\n" +" cmpb $15, %%bl\n" +" ja .L_get_length_code\n" /* if (15 < bits) */ + +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ + +".L_get_length_code:\n" +" movl 56(%%esp), %%eax\n" /* eax = lmask */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +".L_dolen:\n" +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrl %%cl, %%edx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_length_base:\n" +" movl %%eax, %%ecx\n" /* len = this */ +" shrl $16, %%ecx\n" /* len = this.val */ +" movl %%ecx, 64(%%esp)\n" /* save len */ +" movb %%al, %%cl\n" + +" testb $16, %%al\n" +" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */ +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_decode_distance\n" /* if (!op) */ +" cmpb %%cl, %%bl\n" +" jae .L_add_bits_to_len\n" /* if (op <= bits) */ + +" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */ +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ +" movb %%ch, %%cl\n" /* move op back to ecx */ + +".L_add_bits_to_len:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrl %%cl, %%edx\n" +" addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */ + +".L_decode_distance:\n" +" cmpb $15, %%bl\n" +" ja .L_get_distance_code\n" /* if (15 < bits) */ + +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ + +".L_get_distance_code:\n" +" movl 60(%%esp), %%eax\n" /* eax = dmask */ +" movl 36(%%esp), %%ecx\n" /* ecx = dcode */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */ + +".L_dodist:\n" +" movl %%eax, %%ebp\n" /* dist = this */ +" shrl $16, %%ebp\n" /* dist = this.val */ +" movb %%ah, %%cl\n" +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrl %%cl, %%edx\n" /* hold >>= this.bits */ +" movb %%al, %%cl\n" /* cl = this.op */ + +" testb $16, %%al\n" /* if ((op & 16) == 0) */ +" jz .L_test_for_second_level_dist\n" +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_check_dist_one\n" +" cmpb %%cl, %%bl\n" +" jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */ + +" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */ +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ +" movb %%ch, %%cl\n" /* move op back to ecx */ + +".L_add_bits_to_dist:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" /* (1 << op) - 1 */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrl %%cl, %%edx\n" +" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */ + +".L_check_window:\n" +" movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */ +" movl %%edi, %%eax\n" +" subl 20(%%esp), %%eax\n" /* nbytes = out - beg */ + +" cmpl %%ebp, %%eax\n" +" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ + +" movl 64(%%esp), %%ecx\n" /* ecx = len */ +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ + +" sarl %%ecx\n" +" jnc .L_copy_two\n" /* if len % 2 == 0 */ + +" rep movsw\n" +" movb (%%esi), %%al\n" +" movb %%al, (%%edi)\n" +" incl %%edi\n" + +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".L_copy_two:\n" +" rep movsw\n" +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_check_dist_one:\n" +" cmpl $1, %%ebp\n" /* if dist 1, is a memset */ +" jne .L_check_window\n" +" cmpl %%edi, 20(%%esp)\n" +" je .L_check_window\n" /* out == beg, if outside window */ + +" movl 64(%%esp), %%ecx\n" /* ecx = len */ +" movb -1(%%edi), %%al\n" +" movb %%al, %%ah\n" + +" sarl %%ecx\n" +" jnc .L_set_two\n" +" movb %%al, (%%edi)\n" +" incl %%edi\n" + +".L_set_two:\n" +" rep stosw\n" +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_second_level_length:\n" +" testb $64, %%al\n" +" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl 64(%%esp), %%eax\n" /* eax += len */ +" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ +" jmp .L_dolen\n" + +".align 32,0x90\n" +".L_test_for_second_level_dist:\n" +" testb $64, %%al\n" +" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%ebp, %%eax\n" /* eax += dist */ +" movl 36(%%esp), %%ecx\n" /* ecx = dcode */ +" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ +" jmp .L_dodist\n" + +".align 32,0x90\n" +".L_clip_window:\n" +" movl %%eax, %%ecx\n" +" movl 48(%%esp), %%eax\n" /* eax = wsize */ +" negl %%ecx\n" /* nbytes = -nbytes */ +" movl 28(%%esp), %%esi\n" /* from = window */ + +" cmpl %%ebp, %%eax\n" +" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ + +" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */ +" cmpl $0, 52(%%esp)\n" +" jne .L_wrap_around_window\n" /* if (write != 0) */ + +" subl %%ecx, %%eax\n" +" addl %%eax, %%esi\n" /* from += wsize - nbytes */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_wrap_around_window:\n" +" movl 52(%%esp), %%eax\n" /* eax = write */ +" cmpl %%eax, %%ecx\n" +" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ + +" addl 48(%%esp), %%esi\n" /* from += wsize */ +" addl %%eax, %%esi\n" /* from += write */ +" subl %%ecx, %%esi\n" /* from -= nbytes */ +" subl %%eax, %%ecx\n" /* nbytes -= write */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl 28(%%esp), %%esi\n" /* from = window */ +" movl 52(%%esp), %%ecx\n" /* nbytes = write */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_contiguous_in_window:\n" +" addl %%eax, %%esi\n" +" subl %%ecx, %%esi\n" /* from += write - nbytes */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" /* if (nbytes >= len) */ + +".align 32,0x90\n" +".L_do_copy:\n" +" movl %%eax, %%ecx\n" +" rep movsb\n" + +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".L_test_for_end_of_block:\n" +" testb $32, %%al\n" +" jz .L_invalid_literal_length_code\n" +" movl $1, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_literal_length_code:\n" +" movl $2, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_code:\n" +" movl $3, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_too_far:\n" +" movl 8(%%esp), %%esi\n" +" movl $4, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_break_loop:\n" +" movl $0, 72(%%esp)\n" + +".L_break_loop_with_status:\n" +/* put in, out, bits, and hold back into ar and pop esp */ +" movl %%esi, 8(%%esp)\n" /* save in */ +" movl %%edi, 16(%%esp)\n" /* save out */ +" movl %%ebx, 44(%%esp)\n" /* save bits */ +" movl %%edx, 40(%%esp)\n" /* save hold */ +" movl 4(%%esp), %%ebp\n" /* restore esp, ebp */ +" movl (%%esp), %%esp\n" + : + : "m" (ar) + : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" + ); +#elif defined( _MSC_VER ) && ! defined( _M_AMD64 ) + __asm { + lea eax, ar + mov [eax], esp /* save esp, ebp */ + mov [eax+4], ebp + mov esp, eax + mov esi, [esp+8] /* esi = in */ + mov edi, [esp+16] /* edi = out */ + mov edx, [esp+40] /* edx = hold */ + mov ebx, [esp+44] /* ebx = bits */ + mov ebp, [esp+32] /* ebp = lcode */ + + cld + jmp L_do_loop + +ALIGN 4 +L_while_test: + cmp [esp+24], edi + jbe L_break_loop + cmp [esp+12], esi + jbe L_break_loop + +L_do_loop: + cmp bl, 15 + ja L_get_length_code /* if (15 < bits) */ + + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + +L_get_length_code: + mov eax, [esp+56] /* eax = lmask */ + and eax, edx /* eax &= hold */ + mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah /* cl = this.bits */ + sub bl, ah /* bits -= this.bits */ + shr edx, cl /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base /* if (op != 0) 45.7% */ + + shr eax, 16 /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov ecx, eax /* len = this */ + shr ecx, 16 /* len = this.val */ + mov [esp+64], ecx /* save len */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */ + and cl, 15 /* op &= 15 */ + jz L_decode_distance /* if (!op) */ + cmp bl, cl + jae L_add_bits_to_len /* if (op <= bits) */ + + mov ch, cl /* stash op in ch, freeing cl */ + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + mov cl, ch /* move op back to ecx */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + shr edx, cl + add [esp+64], eax /* len += hold & mask[op] */ + +L_decode_distance: + cmp bl, 15 + ja L_get_distance_code /* if (15 < bits) */ + + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + +L_get_distance_code: + mov eax, [esp+60] /* eax = dmask */ + mov ecx, [esp+36] /* ecx = dcode */ + and eax, edx /* eax &= hold */ + mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */ + +L_dodist: + mov ebp, eax /* dist = this */ + shr ebp, 16 /* dist = this.val */ + mov cl, ah + sub bl, ah /* bits -= this.bits */ + shr edx, cl /* hold >>= this.bits */ + mov cl, al /* cl = this.op */ + + test al, 16 /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 /* op &= 15 */ + jz L_check_dist_one + cmp bl, cl + jae L_add_bits_to_dist /* if (op <= bits) 97.6% */ + + mov ch, cl /* stash op in ch, freeing cl */ + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + mov cl, ch /* move op back to ecx */ + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax /* (1 << op) - 1 */ + and eax, edx /* eax &= hold */ + shr edx, cl + add ebp, eax /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov [esp+8], esi /* save in so from can use it's reg */ + mov eax, edi + sub eax, [esp+20] /* nbytes = out - beg */ + + cmp eax, ebp + jb L_clip_window /* if (dist > nbytes) 4.2% */ + + mov ecx, [esp+64] /* ecx = len */ + mov esi, edi + sub esi, ebp /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two + + rep movsw + mov al, [esi] + mov [edi], al + inc edi + + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +L_copy_two: + rep movsw + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp ebp, 1 /* if dist 1, is a memset */ + jne L_check_window + cmp [esp+20], edi + je L_check_window /* out == beg, if outside window */ + + mov ecx, [esp+64] /* ecx = len */ + mov al, [edi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [edi], al /* memset out with from[-1] */ + inc edi + +L_set_two: + rep stosw + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + add eax, [esp+64] /* eax += len */ + mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + add eax, ebp /* eax += dist */ + mov ecx, [esp+36] /* ecx = dcode */ + mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax + mov eax, [esp+48] /* eax = wsize */ + neg ecx /* nbytes = -nbytes */ + mov esi, [esp+28] /* from = window */ + + cmp eax, ebp + jb L_invalid_distance_too_far /* if (dist > wsize) */ + + add ecx, ebp /* nbytes = dist - nbytes */ + cmp dword ptr [esp+52], 0 + jne L_wrap_around_window /* if (write != 0) */ + + sub eax, ecx + add esi, eax /* from += wsize - nbytes */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [esp+52] /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window /* if (write >= nbytes) */ + + add esi, [esp+48] /* from += wsize */ + add esi, eax /* from += write */ + sub esi, ecx /* from -= nbytes */ + sub ecx, eax /* nbytes -= write */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, [esp+28] /* from = window */ + mov ecx, [esp+52] /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + add esi, eax + sub esi, ecx /* from += write - nbytes */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_do_copy: + mov ecx, eax + rep movsb + + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [esp+72], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [esp+72], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [esp+72], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov esi, [esp+4] + mov dword ptr [esp+72], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [esp+72], 0 + +L_break_loop_with_status: +/* put in, out, bits, and hold back into ar and pop esp */ + mov [esp+8], esi /* save in */ + mov [esp+16], edi /* save out */ + mov [esp+44], ebx /* save bits */ + mov [esp+40], edx /* save hold */ + mov ebp, [esp+4] /* restore esp, ebp */ + mov esp, [esp] + } +#else +#error "x86 architecture not defined" +#endif + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = ar.hold; + state->bits = ar.bits; + return; +} + diff --git a/src/external/zlib-1.2.11/contrib/inflate86/inffast.S b/src/external/zlib-1.2.11/contrib/inflate86/inffast.S new file mode 100644 index 000000000..2245a2905 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/inflate86/inffast.S @@ -0,0 +1,1368 @@ +/* + * inffast.S is a hand tuned assembler version of: + * + * inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * This version (Jan-23-2003) of inflate_fast was coded and tested under + * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution. On that + * machine, I found that gzip style archives decompressed about 20% faster than + * the gcc-3.2 -O3 -fomit-frame-pointer compiled version. Your results will + * depend on how large of a buffer is used for z_stream.next_in & next_out + * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in + * stream processing I/O and crc32/addler32. In my case, this routine used + * 70% of the cpu time and crc32 used 20%. + * + * I am confident that this version will work in the general case, but I have + * not tested a wide variety of datasets or a wide variety of platforms. + * + * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating. + * It should be a runtime flag instead of compile time flag... + * + * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction. + * With -DUSE_MMX, only MMX code is compiled. With -DNO_MMX, only non-MMX code + * is compiled. Without either option, runtime detection is enabled. Runtime + * detection should work on all modern cpus and the recomended algorithm (flip + * ID bit on eflags and then use the cpuid instruction) is used in many + * multimedia applications. Tested under win2k with gcc-2.95 and gas-2.12 + * distributed with cygwin3. Compiling with gcc-2.95 -c inffast.S -o + * inffast.obj generates a COFF object which can then be linked with MSVC++ + * compiled code. Tested under FreeBSD 4.7 with gcc-2.95. + * + * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and + * slower than compiler generated code). Adjusted cpuid check to use the MMX + * code only for Pentiums < P4 until I have more data on the P4. Speed + * improvment is only about 15% on the Athlon when compared with code generated + * with MSVC++. Not sure yet, but I think the P4 will also be slower using the + * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and + * have less latency than MMX ops. Added code to buffer the last 11 bytes of + * the input stream since the MMX code grabs bits in chunks of 32, which + * differs from the inffast.c algorithm. I don't think there would have been + * read overruns where a page boundary was crossed (a segfault), but there + * could have been overruns when next_in ends on unaligned memory (unintialized + * memory read). + * + * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX. I created a C + * version of the non-MMX code so that it doesn't depend on zstrm and zstate + * structure offsets which are hard coded in this file. This was last tested + * with zlib-1.2.0 which is currently in beta testing, newer versions of this + * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and + * http://www.charm.net/~christop/zlib/ + */ + + +/* + * if you have underscore linking problems (_inflate_fast undefined), try + * using -DGAS_COFF + */ +#if ! defined( GAS_COFF ) && ! defined( GAS_ELF ) + +#if defined( WIN32 ) || defined( __CYGWIN__ ) +#define GAS_COFF /* windows object format */ +#else +#define GAS_ELF +#endif + +#endif /* ! GAS_COFF && ! GAS_ELF */ + + +#if defined( GAS_COFF ) + +/* coff externals have underscores */ +#define inflate_fast _inflate_fast +#define inflate_fast_use_mmx _inflate_fast_use_mmx + +#endif /* GAS_COFF */ + + +.file "inffast.S" + +.globl inflate_fast + +.text +.align 4,0 +.L_invalid_literal_length_code_msg: +.string "invalid literal/length code" + +.align 4,0 +.L_invalid_distance_code_msg: +.string "invalid distance code" + +.align 4,0 +.L_invalid_distance_too_far_msg: +.string "invalid distance too far back" + +#if ! defined( NO_MMX ) +.align 4,0 +.L_mask: /* mask[N] = ( 1 << N ) - 1 */ +.long 0 +.long 1 +.long 3 +.long 7 +.long 15 +.long 31 +.long 63 +.long 127 +.long 255 +.long 511 +.long 1023 +.long 2047 +.long 4095 +.long 8191 +.long 16383 +.long 32767 +.long 65535 +.long 131071 +.long 262143 +.long 524287 +.long 1048575 +.long 2097151 +.long 4194303 +.long 8388607 +.long 16777215 +.long 33554431 +.long 67108863 +.long 134217727 +.long 268435455 +.long 536870911 +.long 1073741823 +.long 2147483647 +.long 4294967295 +#endif /* NO_MMX */ + +.text + +/* + * struct z_stream offsets, in zlib.h + */ +#define next_in_strm 0 /* strm->next_in */ +#define avail_in_strm 4 /* strm->avail_in */ +#define next_out_strm 12 /* strm->next_out */ +#define avail_out_strm 16 /* strm->avail_out */ +#define msg_strm 24 /* strm->msg */ +#define state_strm 28 /* strm->state */ + +/* + * struct inflate_state offsets, in inflate.h + */ +#define mode_state 0 /* state->mode */ +#define wsize_state 32 /* state->wsize */ +#define write_state 40 /* state->write */ +#define window_state 44 /* state->window */ +#define hold_state 48 /* state->hold */ +#define bits_state 52 /* state->bits */ +#define lencode_state 68 /* state->lencode */ +#define distcode_state 72 /* state->distcode */ +#define lenbits_state 76 /* state->lenbits */ +#define distbits_state 80 /* state->distbits */ + +/* + * inflate_fast's activation record + */ +#define local_var_size 64 /* how much local space for vars */ +#define strm_sp 88 /* first arg: z_stream * (local_var_size + 24) */ +#define start_sp 92 /* second arg: unsigned int (local_var_size + 28) */ + +/* + * offsets for local vars on stack + */ +#define out 60 /* unsigned char* */ +#define window 56 /* unsigned char* */ +#define wsize 52 /* unsigned int */ +#define write 48 /* unsigned int */ +#define in 44 /* unsigned char* */ +#define beg 40 /* unsigned char* */ +#define buf 28 /* char[ 12 ] */ +#define len 24 /* unsigned int */ +#define last 20 /* unsigned char* */ +#define end 16 /* unsigned char* */ +#define dcode 12 /* code* */ +#define lcode 8 /* code* */ +#define dmask 4 /* unsigned int */ +#define lmask 0 /* unsigned int */ + +/* + * typedef enum inflate_mode consts, in inflate.h + */ +#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */ +#define INFLATE_MODE_BAD 26 + + +#if ! defined( USE_MMX ) && ! defined( NO_MMX ) + +#define RUN_TIME_MMX + +#define CHECK_MMX 1 +#define DO_USE_MMX 2 +#define DONT_USE_MMX 3 + +.globl inflate_fast_use_mmx + +.data + +.align 4,0 +inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */ +.long CHECK_MMX + +#if defined( GAS_ELF ) +/* elf info */ +.type inflate_fast_use_mmx,@object +.size inflate_fast_use_mmx,4 +#endif + +#endif /* RUN_TIME_MMX */ + +#if defined( GAS_COFF ) +/* coff info: scl 2 = extern, type 32 = function */ +.def inflate_fast; .scl 2; .type 32; .endef +#endif + +.text + +.align 32,0x90 +inflate_fast: + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + pushf /* save eflags (strm_sp, state_sp assumes this is 32 bits) */ + subl $local_var_size, %esp + cld + +#define strm_r %esi +#define state_r %edi + + movl strm_sp(%esp), strm_r + movl state_strm(strm_r), state_r + + /* in = strm->next_in; + * out = strm->next_out; + * last = in + strm->avail_in - 11; + * beg = out - (start - strm->avail_out); + * end = out + (strm->avail_out - 257); + */ + movl avail_in_strm(strm_r), %edx + movl next_in_strm(strm_r), %eax + + addl %eax, %edx /* avail_in += next_in */ + subl $11, %edx /* avail_in -= 11 */ + + movl %eax, in(%esp) + movl %edx, last(%esp) + + movl start_sp(%esp), %ebp + movl avail_out_strm(strm_r), %ecx + movl next_out_strm(strm_r), %ebx + + subl %ecx, %ebp /* start -= avail_out */ + negl %ebp /* start = -start */ + addl %ebx, %ebp /* start += next_out */ + + subl $257, %ecx /* avail_out -= 257 */ + addl %ebx, %ecx /* avail_out += out */ + + movl %ebx, out(%esp) + movl %ebp, beg(%esp) + movl %ecx, end(%esp) + + /* wsize = state->wsize; + * write = state->write; + * window = state->window; + * hold = state->hold; + * bits = state->bits; + * lcode = state->lencode; + * dcode = state->distcode; + * lmask = ( 1 << state->lenbits ) - 1; + * dmask = ( 1 << state->distbits ) - 1; + */ + + movl lencode_state(state_r), %eax + movl distcode_state(state_r), %ecx + + movl %eax, lcode(%esp) + movl %ecx, dcode(%esp) + + movl $1, %eax + movl lenbits_state(state_r), %ecx + shll %cl, %eax + decl %eax + movl %eax, lmask(%esp) + + movl $1, %eax + movl distbits_state(state_r), %ecx + shll %cl, %eax + decl %eax + movl %eax, dmask(%esp) + + movl wsize_state(state_r), %eax + movl write_state(state_r), %ecx + movl window_state(state_r), %edx + + movl %eax, wsize(%esp) + movl %ecx, write(%esp) + movl %edx, window(%esp) + + movl hold_state(state_r), %ebp + movl bits_state(state_r), %ebx + +#undef strm_r +#undef state_r + +#define in_r %esi +#define from_r %esi +#define out_r %edi + + movl in(%esp), in_r + movl last(%esp), %ecx + cmpl in_r, %ecx + ja .L_align_long /* if in < last */ + + addl $11, %ecx /* ecx = &in[ avail_in ] */ + subl in_r, %ecx /* ecx = avail_in */ + movl $12, %eax + subl %ecx, %eax /* eax = 12 - avail_in */ + leal buf(%esp), %edi + rep movsb /* memcpy( buf, in, avail_in ) */ + movl %eax, %ecx + xorl %eax, %eax + rep stosb /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */ + leal buf(%esp), in_r /* in = buf */ + movl in_r, last(%esp) /* last = in, do just one iteration */ + jmp .L_is_aligned + + /* align in_r on long boundary */ +.L_align_long: + testl $3, in_r + jz .L_is_aligned + xorl %eax, %eax + movb (in_r), %al + incl in_r + movl %ebx, %ecx + addl $8, %ebx + shll %cl, %eax + orl %eax, %ebp + jmp .L_align_long + +.L_is_aligned: + movl out(%esp), out_r + +#if defined( NO_MMX ) + jmp .L_do_loop +#endif + +#if defined( USE_MMX ) + jmp .L_init_mmx +#endif + +/*** Runtime MMX check ***/ + +#if defined( RUN_TIME_MMX ) +.L_check_mmx: + cmpl $DO_USE_MMX, inflate_fast_use_mmx + je .L_init_mmx + ja .L_do_loop /* > 2 */ + + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushf + movl (%esp), %eax /* copy eflags to eax */ + xorl $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21) + * to see if cpu supports cpuid... + * ID bit method not supported by NexGen but + * bios may load a cpuid instruction and + * cpuid may be disabled on Cyrix 5-6x86 */ + popf + pushf + popl %edx /* copy new eflags to edx */ + xorl %eax, %edx /* test if ID bit is flipped */ + jz .L_dont_use_mmx /* not flipped if zero */ + xorl %eax, %eax + cpuid + cmpl $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */ + jne .L_dont_use_mmx + cmpl $0x6c65746e, %ecx + jne .L_dont_use_mmx + cmpl $0x49656e69, %edx + jne .L_dont_use_mmx + movl $1, %eax + cpuid /* get cpu features */ + shrl $8, %eax + andl $15, %eax + cmpl $6, %eax /* check for Pentium family, is 0xf for P4 */ + jne .L_dont_use_mmx + testl $0x800000, %edx /* test if MMX feature is set (bit 23) */ + jnz .L_use_mmx + jmp .L_dont_use_mmx +.L_use_mmx: + movl $DO_USE_MMX, inflate_fast_use_mmx + jmp .L_check_mmx_pop +.L_dont_use_mmx: + movl $DONT_USE_MMX, inflate_fast_use_mmx +.L_check_mmx_pop: + popl %edx + popl %ecx + popl %ebx + popl %eax + jmp .L_check_mmx +#endif + + +/*** Non-MMX code ***/ + +#if defined ( NO_MMX ) || defined( RUN_TIME_MMX ) + +#define hold_r %ebp +#define bits_r %bl +#define bitslong_r %ebx + +.align 32,0x90 +.L_while_test: + /* while (in < last && out < end) + */ + cmpl out_r, end(%esp) + jbe .L_break_loop /* if (out >= end) */ + + cmpl in_r, last(%esp) + jbe .L_break_loop + +.L_do_loop: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out + * + * do { + * if (bits < 15) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * this = lcode[hold & lmask] + */ + cmpb $15, bits_r + ja .L_get_length_code /* if (15 < bits) */ + + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + +.L_get_length_code: + movl lmask(%esp), %edx /* edx = lmask */ + movl lcode(%esp), %ecx /* ecx = lcode */ + andl hold_r, %edx /* edx &= hold */ + movl (%ecx,%edx,4), %eax /* eax = lcode[hold & lmask] */ + +.L_dolen: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out + * + * dolen: + * bits -= this.bits; + * hold >>= this.bits + */ + movb %ah, %cl /* cl = this.bits */ + subb %ah, bits_r /* bits -= this.bits */ + shrl %cl, hold_r /* hold >>= this.bits */ + + /* check if op is a literal + * if (op == 0) { + * PUP(out) = this.val; + * } + */ + testb %al, %al + jnz .L_test_for_length_base /* if (op != 0) 45.7% */ + + shrl $16, %eax /* output this.val char */ + stosb + jmp .L_while_test + +.L_test_for_length_base: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len + * + * else if (op & 16) { + * len = this.val + * op &= 15 + * if (op) { + * if (op > bits) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * len += hold & mask[op]; + * bits -= op; + * hold >>= op; + * } + */ +#define len_r %edx + movl %eax, len_r /* len = this */ + shrl $16, len_r /* len = this.val */ + movb %al, %cl + + testb $16, %al + jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */ + andb $15, %cl /* op &= 15 */ + jz .L_save_len /* if (!op) */ + cmpb %cl, bits_r + jae .L_add_bits_to_len /* if (op <= bits) */ + + movb %cl, %ch /* stash op in ch, freeing cl */ + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + movb %ch, %cl /* move op back to ecx */ + +.L_add_bits_to_len: + movl $1, %eax + shll %cl, %eax + decl %eax + subb %cl, bits_r + andl hold_r, %eax /* eax &= hold */ + shrl %cl, hold_r + addl %eax, len_r /* len += hold & mask[op] */ + +.L_save_len: + movl len_r, len(%esp) /* save len */ +#undef len_r + +.L_decode_distance: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * + * if (bits < 15) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * this = dcode[hold & dmask]; + * dodist: + * bits -= this.bits; + * hold >>= this.bits; + * op = this.op; + */ + + cmpb $15, bits_r + ja .L_get_distance_code /* if (15 < bits) */ + + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + +.L_get_distance_code: + movl dmask(%esp), %edx /* edx = dmask */ + movl dcode(%esp), %ecx /* ecx = dcode */ + andl hold_r, %edx /* edx &= hold */ + movl (%ecx,%edx,4), %eax /* eax = dcode[hold & dmask] */ + +#define dist_r %edx +.L_dodist: + movl %eax, dist_r /* dist = this */ + shrl $16, dist_r /* dist = this.val */ + movb %ah, %cl + subb %ah, bits_r /* bits -= this.bits */ + shrl %cl, hold_r /* hold >>= this.bits */ + + /* if (op & 16) { + * dist = this.val + * op &= 15 + * if (op > bits) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * dist += hold & mask[op]; + * bits -= op; + * hold >>= op; + */ + movb %al, %cl /* cl = this.op */ + + testb $16, %al /* if ((op & 16) == 0) */ + jz .L_test_for_second_level_dist + andb $15, %cl /* op &= 15 */ + jz .L_check_dist_one + cmpb %cl, bits_r + jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */ + + movb %cl, %ch /* stash op in ch, freeing cl */ + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + movb %ch, %cl /* move op back to ecx */ + +.L_add_bits_to_dist: + movl $1, %eax + shll %cl, %eax + decl %eax /* (1 << op) - 1 */ + subb %cl, bits_r + andl hold_r, %eax /* eax &= hold */ + shrl %cl, hold_r + addl %eax, dist_r /* dist += hold & ((1 << op) - 1) */ + jmp .L_check_window + +.L_check_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes + * + * nbytes = out - beg; + * if (dist <= nbytes) { + * from = out - dist; + * do { + * PUP(out) = PUP(from); + * } while (--len > 0) { + * } + */ + + movl in_r, in(%esp) /* save in so from can use it's reg */ + movl out_r, %eax + subl beg(%esp), %eax /* nbytes = out - beg */ + + cmpl dist_r, %eax + jb .L_clip_window /* if (dist > nbytes) 4.2% */ + + movl len(%esp), %ecx + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + + subl $3, %ecx + movb (from_r), %al + movb %al, (out_r) + movb 1(from_r), %al + movb 2(from_r), %dl + addl $3, from_r + movb %al, 1(out_r) + movb %dl, 2(out_r) + addl $3, out_r + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + jmp .L_while_test + +.align 16,0x90 +.L_check_dist_one: + cmpl $1, dist_r + jne .L_check_window + cmpl out_r, beg(%esp) + je .L_check_window + + decl out_r + movl len(%esp), %ecx + movb (out_r), %al + subl $3, %ecx + + movb %al, 1(out_r) + movb %al, 2(out_r) + movb %al, 3(out_r) + addl $4, out_r + rep stosb + + jmp .L_while_test + +.align 16,0x90 +.L_test_for_second_level_length: + /* else if ((op & 64) == 0) { + * this = lcode[this.val + (hold & mask[op])]; + * } + */ + testb $64, %al + jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */ + + movl $1, %eax + shll %cl, %eax + decl %eax + andl hold_r, %eax /* eax &= hold */ + addl %edx, %eax /* eax += this.val */ + movl lcode(%esp), %edx /* edx = lcode */ + movl (%edx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */ + jmp .L_dolen + +.align 16,0x90 +.L_test_for_second_level_dist: + /* else if ((op & 64) == 0) { + * this = dcode[this.val + (hold & mask[op])]; + * } + */ + testb $64, %al + jnz .L_invalid_distance_code /* if ((op & 64) != 0) */ + + movl $1, %eax + shll %cl, %eax + decl %eax + andl hold_r, %eax /* eax &= hold */ + addl %edx, %eax /* eax += this.val */ + movl dcode(%esp), %edx /* edx = dcode */ + movl (%edx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */ + jmp .L_dodist + +.align 16,0x90 +.L_clip_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes + * + * else { + * if (dist > wsize) { + * invalid distance + * } + * from = window; + * nbytes = dist - nbytes; + * if (write == 0) { + * from += wsize - nbytes; + */ +#define nbytes_r %ecx + movl %eax, nbytes_r + movl wsize(%esp), %eax /* prepare for dist compare */ + negl nbytes_r /* nbytes = -nbytes */ + movl window(%esp), from_r /* from = window */ + + cmpl dist_r, %eax + jb .L_invalid_distance_too_far /* if (dist > wsize) */ + + addl dist_r, nbytes_r /* nbytes = dist - nbytes */ + cmpl $0, write(%esp) + jne .L_wrap_around_window /* if (write != 0) */ + + subl nbytes_r, %eax + addl %eax, from_r /* from += wsize - nbytes */ + + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = len + * + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = out - dist; + * } + * } + */ +#define len_r %eax + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + +.L_wrap_around_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = write, %eax = len + * + * else if (write < nbytes) { + * from += wsize + write - nbytes; + * nbytes -= write; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = window; + * nbytes = write; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while(--nbytes); + * from = out - dist; + * } + * } + * } + */ +#define write_r %eax + movl write(%esp), write_r + cmpl write_r, nbytes_r + jbe .L_contiguous_in_window /* if (write >= nbytes) */ + + addl wsize(%esp), from_r + addl write_r, from_r + subl nbytes_r, from_r /* from += wsize + write - nbytes */ + subl write_r, nbytes_r /* nbytes -= write */ +#undef write_r + + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl window(%esp), from_r /* from = window */ + movl write(%esp), nbytes_r /* nbytes = write */ + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + +.L_contiguous_in_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = write, %eax = len + * + * else { + * from += write - nbytes; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = out - dist; + * } + * } + */ +#define write_r %eax + addl write_r, from_r + subl nbytes_r, from_r /* from += write - nbytes */ +#undef write_r + + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + +.L_do_copy1: + /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out + * %eax = len + * + * while (len > 0) { + * PUP(out) = PUP(from); + * len--; + * } + * } + * } while (in < last && out < end); + */ +#undef nbytes_r +#define in_r %esi + movl len_r, %ecx + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + jmp .L_while_test + +#undef len_r +#undef dist_r + +#endif /* NO_MMX || RUN_TIME_MMX */ + + +/*** MMX code ***/ + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +.align 32,0x90 +.L_init_mmx: + emms + +#undef bits_r +#undef bitslong_r +#define bitslong_r %ebp +#define hold_mm %mm0 + movd %ebp, hold_mm + movl %ebx, bitslong_r + +#define used_mm %mm1 +#define dmask2_mm %mm2 +#define lmask2_mm %mm3 +#define lmask_mm %mm4 +#define dmask_mm %mm5 +#define tmp_mm %mm6 + + movd lmask(%esp), lmask_mm + movq lmask_mm, lmask2_mm + movd dmask(%esp), dmask_mm + movq dmask_mm, dmask2_mm + pxor used_mm, used_mm + movl lcode(%esp), %ebx /* ebx = lcode */ + jmp .L_do_loop_mmx + +.align 32,0x90 +.L_while_test_mmx: + /* while (in < last && out < end) + */ + cmpl out_r, end(%esp) + jbe .L_break_loop /* if (out >= end) */ + + cmpl in_r, last(%esp) + jbe .L_break_loop + +.L_do_loop_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + + cmpl $32, bitslong_r + ja .L_get_length_code_mmx /* if (32 < bits) */ + + movd bitslong_r, tmp_mm + movd (in_r), %mm7 + addl $4, in_r + psllq tmp_mm, %mm7 + addl $32, bitslong_r + por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */ + +.L_get_length_code_mmx: + pand hold_mm, lmask_mm + movd lmask_mm, %eax + movq lmask2_mm, lmask_mm + movl (%ebx,%eax,4), %eax /* eax = lcode[hold & lmask] */ + +.L_dolen_mmx: + movzbl %ah, %ecx /* ecx = this.bits */ + movd %ecx, used_mm + subl %ecx, bitslong_r /* bits -= this.bits */ + + testb %al, %al + jnz .L_test_for_length_base_mmx /* if (op != 0) 45.7% */ + + shrl $16, %eax /* output this.val char */ + stosb + jmp .L_while_test_mmx + +.L_test_for_length_base_mmx: +#define len_r %edx + movl %eax, len_r /* len = this */ + shrl $16, len_r /* len = this.val */ + + testb $16, %al + jz .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */ + andl $15, %eax /* op &= 15 */ + jz .L_decode_distance_mmx /* if (!op) */ + + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd %eax, used_mm + movd hold_mm, %ecx + subl %eax, bitslong_r + andl .L_mask(,%eax,4), %ecx + addl %ecx, len_r /* len += hold & mask[op] */ + +.L_decode_distance_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + + cmpl $32, bitslong_r + ja .L_get_dist_code_mmx /* if (32 < bits) */ + + movd bitslong_r, tmp_mm + movd (in_r), %mm7 + addl $4, in_r + psllq tmp_mm, %mm7 + addl $32, bitslong_r + por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */ + +.L_get_dist_code_mmx: + movl dcode(%esp), %ebx /* ebx = dcode */ + pand hold_mm, dmask_mm + movd dmask_mm, %eax + movq dmask2_mm, dmask_mm + movl (%ebx,%eax,4), %eax /* eax = dcode[hold & lmask] */ + +.L_dodist_mmx: +#define dist_r %ebx + movzbl %ah, %ecx /* ecx = this.bits */ + movl %eax, dist_r + shrl $16, dist_r /* dist = this.val */ + subl %ecx, bitslong_r /* bits -= this.bits */ + movd %ecx, used_mm + + testb $16, %al /* if ((op & 16) == 0) */ + jz .L_test_for_second_level_dist_mmx + andl $15, %eax /* op &= 15 */ + jz .L_check_dist_one_mmx + +.L_add_bits_to_dist_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd %eax, used_mm /* save bit length of current op */ + movd hold_mm, %ecx /* get the next bits on input stream */ + subl %eax, bitslong_r /* bits -= op bits */ + andl .L_mask(,%eax,4), %ecx /* ecx = hold & mask[op] */ + addl %ecx, dist_r /* dist += hold & mask[op] */ + +.L_check_window_mmx: + movl in_r, in(%esp) /* save in so from can use it's reg */ + movl out_r, %eax + subl beg(%esp), %eax /* nbytes = out - beg */ + + cmpl dist_r, %eax + jb .L_clip_window_mmx /* if (dist > nbytes) 4.2% */ + + movl len_r, %ecx + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + + subl $3, %ecx + movb (from_r), %al + movb %al, (out_r) + movb 1(from_r), %al + movb 2(from_r), %dl + addl $3, from_r + movb %al, 1(out_r) + movb %dl, 2(out_r) + addl $3, out_r + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +.align 16,0x90 +.L_check_dist_one_mmx: + cmpl $1, dist_r + jne .L_check_window_mmx + cmpl out_r, beg(%esp) + je .L_check_window_mmx + + decl out_r + movl len_r, %ecx + movb (out_r), %al + subl $3, %ecx + + movb %al, 1(out_r) + movb %al, 2(out_r) + movb %al, 3(out_r) + addl $4, out_r + rep stosb + + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +.align 16,0x90 +.L_test_for_second_level_length_mmx: + testb $64, %al + jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */ + + andl $15, %eax + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ecx + andl .L_mask(,%eax,4), %ecx + addl len_r, %ecx + movl (%ebx,%ecx,4), %eax /* eax = lcode[hold & lmask] */ + jmp .L_dolen_mmx + +.align 16,0x90 +.L_test_for_second_level_dist_mmx: + testb $64, %al + jnz .L_invalid_distance_code /* if ((op & 64) != 0) */ + + andl $15, %eax + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ecx + andl .L_mask(,%eax,4), %ecx + movl dcode(%esp), %eax /* ecx = dcode */ + addl dist_r, %ecx + movl (%eax,%ecx,4), %eax /* eax = lcode[hold & lmask] */ + jmp .L_dodist_mmx + +.align 16,0x90 +.L_clip_window_mmx: +#define nbytes_r %ecx + movl %eax, nbytes_r + movl wsize(%esp), %eax /* prepare for dist compare */ + negl nbytes_r /* nbytes = -nbytes */ + movl window(%esp), from_r /* from = window */ + + cmpl dist_r, %eax + jb .L_invalid_distance_too_far /* if (dist > wsize) */ + + addl dist_r, nbytes_r /* nbytes = dist - nbytes */ + cmpl $0, write(%esp) + jne .L_wrap_around_window_mmx /* if (write != 0) */ + + subl nbytes_r, %eax + addl %eax, from_r /* from += wsize - nbytes */ + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + +.L_wrap_around_window_mmx: +#define write_r %eax + movl write(%esp), write_r + cmpl write_r, nbytes_r + jbe .L_contiguous_in_window_mmx /* if (write >= nbytes) */ + + addl wsize(%esp), from_r + addl write_r, from_r + subl nbytes_r, from_r /* from += wsize + write - nbytes */ + subl write_r, nbytes_r /* nbytes -= write */ +#undef write_r + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl window(%esp), from_r /* from = window */ + movl write(%esp), nbytes_r /* nbytes = write */ + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + +.L_contiguous_in_window_mmx: +#define write_r %eax + addl write_r, from_r + subl nbytes_r, from_r /* from += write - nbytes */ +#undef write_r + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + +.L_do_copy1_mmx: +#undef nbytes_r +#define in_r %esi + movl len_r, %ecx + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +#undef hold_r +#undef bitslong_r + +#endif /* USE_MMX || RUN_TIME_MMX */ + + +/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/ + +.L_invalid_distance_code: + /* else { + * strm->msg = "invalid distance code"; + * state->mode = BAD; + * } + */ + movl $.L_invalid_distance_code_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_test_for_end_of_block: + /* else if (op & 32) { + * state->mode = TYPE; + * break; + * } + */ + testb $32, %al + jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */ + + movl $0, %ecx + movl $INFLATE_MODE_TYPE, %edx + jmp .L_update_stream_state + +.L_invalid_literal_length_code: + /* else { + * strm->msg = "invalid literal/length code"; + * state->mode = BAD; + * } + */ + movl $.L_invalid_literal_length_code_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_invalid_distance_too_far: + /* strm->msg = "invalid distance too far back"; + * state->mode = BAD; + */ + movl in(%esp), in_r /* from_r has in's reg, put in back */ + movl $.L_invalid_distance_too_far_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_update_stream_state: + /* set strm->msg = %ecx, strm->state->mode = %edx */ + movl strm_sp(%esp), %eax + testl %ecx, %ecx /* if (msg != NULL) */ + jz .L_skip_msg + movl %ecx, msg_strm(%eax) /* strm->msg = msg */ +.L_skip_msg: + movl state_strm(%eax), %eax /* state = strm->state */ + movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */ + jmp .L_break_loop + +.align 32,0x90 +.L_break_loop: + +/* + * Regs: + * + * bits = %ebp when mmx, and in %ebx when non-mmx + * hold = %hold_mm when mmx, and in %ebp when non-mmx + * in = %esi + * out = %edi + */ + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +#if defined( RUN_TIME_MMX ) + + cmpl $DO_USE_MMX, inflate_fast_use_mmx + jne .L_update_next_in + +#endif /* RUN_TIME_MMX */ + + movl %ebp, %ebx + +.L_update_next_in: + +#endif + +#define strm_r %eax +#define state_r %edx + + /* len = bits >> 3; + * in -= len; + * bits -= len << 3; + * hold &= (1U << bits) - 1; + * state->hold = hold; + * state->bits = bits; + * strm->next_in = in; + * strm->next_out = out; + */ + movl strm_sp(%esp), strm_r + movl %ebx, %ecx + movl state_strm(strm_r), state_r + shrl $3, %ecx + subl %ecx, in_r + shll $3, %ecx + subl %ecx, %ebx + movl out_r, next_out_strm(strm_r) + movl %ebx, bits_state(state_r) + movl %ebx, %ecx + + leal buf(%esp), %ebx + cmpl %ebx, last(%esp) + jne .L_buf_not_used /* if buf != last */ + + subl %ebx, in_r /* in -= buf */ + movl next_in_strm(strm_r), %ebx + movl %ebx, last(%esp) /* last = strm->next_in */ + addl %ebx, in_r /* in += strm->next_in */ + movl avail_in_strm(strm_r), %ebx + subl $11, %ebx + addl %ebx, last(%esp) /* last = &strm->next_in[ avail_in - 11 ] */ + +.L_buf_not_used: + movl in_r, next_in_strm(strm_r) + + movl $1, %ebx + shll %cl, %ebx + decl %ebx + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +#if defined( RUN_TIME_MMX ) + + cmpl $DO_USE_MMX, inflate_fast_use_mmx + jne .L_update_hold + +#endif /* RUN_TIME_MMX */ + + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ebp + + emms + +.L_update_hold: + +#endif /* USE_MMX || RUN_TIME_MMX */ + + andl %ebx, %ebp + movl %ebp, hold_state(state_r) + +#define last_r %ebx + + /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */ + movl last(%esp), last_r + cmpl in_r, last_r + jbe .L_last_is_smaller /* if (in >= last) */ + + subl in_r, last_r /* last -= in */ + addl $11, last_r /* last += 11 */ + movl last_r, avail_in_strm(strm_r) + jmp .L_fixup_out +.L_last_is_smaller: + subl last_r, in_r /* in -= last */ + negl in_r /* in = -in */ + addl $11, in_r /* in += 11 */ + movl in_r, avail_in_strm(strm_r) + +#undef last_r +#define end_r %ebx + +.L_fixup_out: + /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/ + movl end(%esp), end_r + cmpl out_r, end_r + jbe .L_end_is_smaller /* if (out >= end) */ + + subl out_r, end_r /* end -= out */ + addl $257, end_r /* end += 257 */ + movl end_r, avail_out_strm(strm_r) + jmp .L_done +.L_end_is_smaller: + subl end_r, out_r /* out -= end */ + negl out_r /* out = -out */ + addl $257, out_r /* out += 257 */ + movl out_r, avail_out_strm(strm_r) + +#undef end_r +#undef strm_r +#undef state_r + +.L_done: + addl $local_var_size, %esp + popf + popl %ebx + popl %ebp + popl %esi + popl %edi + ret + +#if defined( GAS_ELF ) +/* elf info */ +.type inflate_fast,@function +.size inflate_fast,.-inflate_fast +#endif diff --git a/src/external/zlib-1.2.11/contrib/iostream/test.cpp b/src/external/zlib-1.2.11/contrib/iostream/test.cpp new file mode 100644 index 000000000..7d265b3b5 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream/test.cpp @@ -0,0 +1,24 @@ + +#include "zfstream.h" + +int main() { + + // Construct a stream object with this filebuffer. Anything sent + // to this stream will go to standard out. + gzofstream os( 1, ios::out ); + + // This text is getting compressed and sent to stdout. + // To prove this, run 'test | zcat'. + os << "Hello, Mommy" << endl; + + os << setcompressionlevel( Z_NO_COMPRESSION ); + os << "hello, hello, hi, ho!" << endl; + + setcompressionlevel( os, Z_DEFAULT_COMPRESSION ) + << "I'm compressing again" << endl; + + os.close(); + + return 0; + +} diff --git a/src/external/zlib-1.2.11/contrib/iostream/zfstream.cpp b/src/external/zlib-1.2.11/contrib/iostream/zfstream.cpp new file mode 100644 index 000000000..d0cd85faa --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream/zfstream.cpp @@ -0,0 +1,329 @@ + +#include "zfstream.h" + +gzfilebuf::gzfilebuf() : + file(NULL), + mode(0), + own_file_descriptor(0) +{ } + +gzfilebuf::~gzfilebuf() { + + sync(); + if ( own_file_descriptor ) + close(); + +} + +gzfilebuf *gzfilebuf::open( const char *name, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + // Put the end-of-string indicator + *p = '\0'; + + if ( (file = gzopen(name, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 1; + + return this; + +} + +gzfilebuf *gzfilebuf::attach( int file_descriptor, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + // Put the end-of-string indicator + *p = '\0'; + + if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 0; + + return this; + +} + +gzfilebuf *gzfilebuf::close() { + + if ( is_open() ) { + + sync(); + gzclose( file ); + file = NULL; + + } + + return this; + +} + +int gzfilebuf::setcompressionlevel( int comp_level ) { + + return gzsetparams(file, comp_level, -2); + +} + +int gzfilebuf::setcompressionstrategy( int comp_strategy ) { + + return gzsetparams(file, -2, comp_strategy); + +} + + +streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { + + return streampos(EOF); + +} + +int gzfilebuf::underflow() { + + // If the file hasn't been opened for reading, error. + if ( !is_open() || !(mode & ios::in) ) + return EOF; + + // if a buffer doesn't exists, allocate one. + if ( !base() ) { + + if ( (allocate()) == EOF ) + return EOF; + setp(0,0); + + } else { + + if ( in_avail() ) + return (unsigned char) *gptr(); + + if ( out_waiting() ) { + if ( flushbuf() == EOF ) + return EOF; + } + + } + + // Attempt to fill the buffer. + + int result = fillbuf(); + if ( result == EOF ) { + // disable get area + setg(0,0,0); + return EOF; + } + + return (unsigned char) *gptr(); + +} + +int gzfilebuf::overflow( int c ) { + + if ( !is_open() || !(mode & ios::out) ) + return EOF; + + if ( !base() ) { + if ( allocate() == EOF ) + return EOF; + setg(0,0,0); + } else { + if (in_avail()) { + return EOF; + } + if (out_waiting()) { + if (flushbuf() == EOF) + return EOF; + } + } + + int bl = blen(); + setp( base(), base() + bl); + + if ( c != EOF ) { + + *pptr() = c; + pbump(1); + + } + + return 0; + +} + +int gzfilebuf::sync() { + + if ( !is_open() ) + return EOF; + + if ( out_waiting() ) + return flushbuf(); + + return 0; + +} + +int gzfilebuf::flushbuf() { + + int n; + char *q; + + q = pbase(); + n = pptr() - q; + + if ( gzwrite( file, q, n) < n ) + return EOF; + + setp(0,0); + + return 0; + +} + +int gzfilebuf::fillbuf() { + + int required; + char *p; + + p = base(); + + required = blen(); + + int t = gzread( file, p, required ); + + if ( t <= 0) return EOF; + + setg( base(), base(), base()+t); + + return t; + +} + +gzfilestream_common::gzfilestream_common() : + ios( gzfilestream_common::rdbuf() ) +{ } + +gzfilestream_common::~gzfilestream_common() +{ } + +void gzfilestream_common::attach( int fd, int io_mode ) { + + if ( !buffer.attach( fd, io_mode) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::open( const char *name, int io_mode ) { + + if ( !buffer.open( name, io_mode ) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::close() { + + if ( !buffer.close() ) + clear( ios::failbit | ios::badbit ); + +} + +gzfilebuf *gzfilestream_common::rdbuf() +{ + return &buffer; +} + +gzifstream::gzifstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzifstream::gzifstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzifstream::gzifstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzifstream::~gzifstream() { } + +gzofstream::gzofstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzofstream::gzofstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzofstream::gzofstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzofstream::~gzofstream() { } diff --git a/src/external/zlib-1.2.11/contrib/iostream/zfstream.h b/src/external/zlib-1.2.11/contrib/iostream/zfstream.h new file mode 100644 index 000000000..ed79098a3 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream/zfstream.h @@ -0,0 +1,128 @@ + +#ifndef zfstream_h +#define zfstream_h + +#include +#include "zlib.h" + +class gzfilebuf : public streambuf { + +public: + + gzfilebuf( ); + virtual ~gzfilebuf(); + + gzfilebuf *open( const char *name, int io_mode ); + gzfilebuf *attach( int file_descriptor, int io_mode ); + gzfilebuf *close(); + + int setcompressionlevel( int comp_level ); + int setcompressionstrategy( int comp_strategy ); + + inline int is_open() const { return (file !=NULL); } + + virtual streampos seekoff( streamoff, ios::seek_dir, int ); + + virtual int sync(); + +protected: + + virtual int underflow(); + virtual int overflow( int = EOF ); + +private: + + gzFile file; + short mode; + short own_file_descriptor; + + int flushbuf(); + int fillbuf(); + +}; + +class gzfilestream_common : virtual public ios { + + friend class gzifstream; + friend class gzofstream; + friend gzofstream &setcompressionlevel( gzofstream &, int ); + friend gzofstream &setcompressionstrategy( gzofstream &, int ); + +public: + virtual ~gzfilestream_common(); + + void attach( int fd, int io_mode ); + void open( const char *name, int io_mode ); + void close(); + +protected: + gzfilestream_common(); + +private: + gzfilebuf *rdbuf(); + + gzfilebuf buffer; + +}; + +class gzifstream : public gzfilestream_common, public istream { + +public: + + gzifstream(); + gzifstream( const char *name, int io_mode = ios::in ); + gzifstream( int fd, int io_mode = ios::in ); + + virtual ~gzifstream(); + +}; + +class gzofstream : public gzfilestream_common, public ostream { + +public: + + gzofstream(); + gzofstream( const char *name, int io_mode = ios::out ); + gzofstream( int fd, int io_mode = ios::out ); + + virtual ~gzofstream(); + +}; + +template class gzomanip { + friend gzofstream &operator<<(gzofstream &, const gzomanip &); +public: + gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { } +private: + gzofstream &(*func)(gzofstream &, T); + T val; +}; + +template gzofstream &operator<<(gzofstream &s, const gzomanip &m) +{ + return (*m.func)(s, m.val); +} + +inline gzofstream &setcompressionlevel( gzofstream &s, int l ) +{ + (s.rdbuf())->setcompressionlevel(l); + return s; +} + +inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) +{ + (s.rdbuf())->setcompressionstrategy(l); + return s; +} + +inline gzomanip setcompressionlevel(int l) +{ + return gzomanip(&setcompressionlevel,l); +} + +inline gzomanip setcompressionstrategy(int l) +{ + return gzomanip(&setcompressionstrategy,l); +} + +#endif diff --git a/src/external/zlib-1.2.11/contrib/iostream2/zstream.h b/src/external/zlib-1.2.11/contrib/iostream2/zstream.h new file mode 100644 index 000000000..43d2332b7 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream2/zstream.h @@ -0,0 +1,307 @@ +/* + * + * Copyright (c) 1997 + * Christian Michelsen Research AS + * Advanced Computing + * Fantoftvegen 38, 5036 BERGEN, Norway + * http://www.cmr.no + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Christian Michelsen Research AS makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef ZSTREAM__H +#define ZSTREAM__H + +/* + * zstream.h - C++ interface to the 'zlib' general purpose compression library + * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $ + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(_WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +class zstringlen { +public: + zstringlen(class izstream&); + zstringlen(class ozstream&, const char*); + size_t value() const { return val.word; } +private: + struct Val { unsigned char byte; size_t word; } val; +}; + +// ----------------------------- izstream ----------------------------- + +class izstream +{ + public: + izstream() : m_fp(0) {} + izstream(FILE* fp) : m_fp(0) { open(fp); } + izstream(const char* name) : m_fp(0) { open(name); } + ~izstream() { close(); } + + /* Opens a gzip (.gz) file for reading. + * open() can be used to read a file which is not in gzip format; + * in this case read() will directly read from the file without + * decompression. errno can be checked to distinguish two error + * cases (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name) { + if (m_fp) close(); + m_fp = ::gzopen(name, "rb"); + } + + void open(FILE* fp) { + SET_BINARY_MODE(fp); + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), "rb"); + } + + /* Flushes all pending input if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + int r = ::gzclose(m_fp); + m_fp = 0; return r; + } + + /* Binary read the given number of bytes from the compressed file. + */ + int read(void* buf, size_t len) { + return ::gzread(m_fp, buf, len); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + private: + gzFile m_fp; +}; + +/* + * Binary read the given (array of) object(s) from the compressed file. + * If the input file was not in gzip format, read() copies the objects number + * of bytes into the buffer. + * returns the number of uncompressed bytes actually read + * (0 for end of file, -1 for error). + */ +template +inline int read(izstream& zs, T* x, Items items) { + return ::gzread(zs.fp(), x, items*sizeof(T)); +} + +/* + * Binary input with the '>' operator. + */ +template +inline izstream& operator>(izstream& zs, T& x) { + ::gzread(zs.fp(), &x, sizeof(T)); + return zs; +} + + +inline zstringlen::zstringlen(izstream& zs) { + zs > val.byte; + if (val.byte == 255) zs > val.word; + else val.word = val.byte; +} + +/* + * Read length of string + the string with the '>' operator. + */ +inline izstream& operator>(izstream& zs, char* x) { + zstringlen len(zs); + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return zs; +} + +inline char* read_string(izstream& zs) { + zstringlen len(zs); + char* x = new char[len.value()+1]; + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return x; +} + +// ----------------------------- ozstream ----------------------------- + +class ozstream +{ + public: + ozstream() : m_fp(0), m_os(0) { + } + ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(fp, level); + } + ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(name, level); + } + ~ozstream() { + close(); + } + + /* Opens a gzip (.gz) file for writing. + * The compression level parameter should be in 0..9 + * errno can be checked to distinguish two error cases + * (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name, int level = Z_DEFAULT_COMPRESSION) { + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzopen(name, mode); + } + + /* open from a FILE pointer. + */ + void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) { + SET_BINARY_MODE(fp); + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), mode); + } + + /* Flushes all pending output if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + if (m_os) { + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = 0; + } + int r = ::gzclose(m_fp); m_fp = 0; return r; + } + + /* Binary write the given number of bytes into the compressed file. + */ + int write(const void* buf, size_t len) { + return ::gzwrite(m_fp, (voidp) buf, len); + } + + /* Flushes all pending output into the compressed file. The parameter + * _flush is as in the deflate() function. The return value is the zlib + * error number (see function gzerror below). flush() returns Z_OK if + * the flush_ parameter is Z_FINISH and all output could be flushed. + * flush() should be called only when strictly necessary because it can + * degrade compression. + */ + int flush(int _flush) { + os_flush(); + return ::gzflush(m_fp, _flush); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + ostream& os() { + if (m_os == 0) m_os = new ostrstream; + return *m_os; + } + + void os_flush() { + if (m_os && m_os->pcount()>0) { + ostrstream* oss = new ostrstream; + oss->fill(m_os->fill()); + oss->flags(m_os->flags()); + oss->precision(m_os->precision()); + oss->width(m_os->width()); + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = oss; + } + } + + private: + gzFile m_fp; + ostrstream* m_os; +}; + +/* + * Binary write the given (array of) object(s) into the compressed file. + * returns the number of uncompressed bytes actually written + * (0 in case of error). + */ +template +inline int write(ozstream& zs, const T* x, Items items) { + return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T)); +} + +/* + * Binary output with the '<' operator. + */ +template +inline ozstream& operator<(ozstream& zs, const T& x) { + ::gzwrite(zs.fp(), (voidp) &x, sizeof(T)); + return zs; +} + +inline zstringlen::zstringlen(ozstream& zs, const char* x) { + val.byte = 255; val.word = ::strlen(x); + if (val.word < 255) zs < (val.byte = val.word); + else zs < val; +} + +/* + * Write length of string + the string with the '<' operator. + */ +inline ozstream& operator<(ozstream& zs, const char* x) { + zstringlen len(zs, x); + ::gzwrite(zs.fp(), (voidp) x, len.value()); + return zs; +} + +#ifdef _MSC_VER +inline ozstream& operator<(ozstream& zs, char* const& x) { + return zs < (const char*) x; +} +#endif + +/* + * Ascii write with the << operator; + */ +template +inline ostream& operator<<(ozstream& zs, const T& x) { + zs.os_flush(); + return zs.os() << x; +} + +#endif diff --git a/src/external/zlib-1.2.11/contrib/iostream2/zstream_test.cpp b/src/external/zlib-1.2.11/contrib/iostream2/zstream_test.cpp new file mode 100644 index 000000000..6273f62d6 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream2/zstream_test.cpp @@ -0,0 +1,25 @@ +#include "zstream.h" +#include +#include +#include + +void main() { + char h[256] = "Hello"; + char* g = "Goodbye"; + ozstream out("temp.gz"); + out < "This works well" < h < g; + out.close(); + + izstream in("temp.gz"); // read it back + char *x = read_string(in), *y = new char[256], z[256]; + in > y > z; + in.close(); + cout << x << endl << y << endl << z << endl; + + out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results + out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl; + out << z << endl << y << endl << x << endl; + out << 1.1234567890123456789 << endl; + + delete[] x; delete[] y; +} diff --git a/src/external/zlib-1.2.11/contrib/iostream3/README b/src/external/zlib-1.2.11/contrib/iostream3/README new file mode 100644 index 000000000..f7b319ab9 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream3/README @@ -0,0 +1,35 @@ +These classes provide a C++ stream interface to the zlib library. It allows you +to do things like: + + gzofstream outf("blah.gz"); + outf << "These go into the gzip file " << 123 << endl; + +It does this by deriving a specialized stream buffer for gzipped files, which is +the way Stroustrup would have done it. :-> + +The gzifstream and gzofstream classes were originally written by Kevin Ruland +and made available in the zlib contrib/iostream directory. The older version still +compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of +this version. + +The new classes are as standard-compliant as possible, closely following the +approach of the standard library's fstream classes. It compiles under gcc versions +3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard +library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs +from the previous one in the following respects: +- added showmanyc +- added setbuf, with support for unbuffered output via setbuf(0,0) +- a few bug fixes of stream behavior +- gzipped output file opened with default compression level instead of maximum level +- setcompressionlevel()/strategy() members replaced by single setcompression() + +The code is provided "as is", with the permission to use, copy, modify, distribute +and sell it for any purpose without fee. + +Ludwig Schwardt + + +DSP Lab +Electrical & Electronic Engineering Department +University of Stellenbosch +South Africa diff --git a/src/external/zlib-1.2.11/contrib/iostream3/TODO b/src/external/zlib-1.2.11/contrib/iostream3/TODO new file mode 100644 index 000000000..7032f97be --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream3/TODO @@ -0,0 +1,17 @@ +Possible upgrades to gzfilebuf: + +- The ability to do putback (e.g. putbackfail) + +- The ability to seek (zlib supports this, but could be slow/tricky) + +- Simultaneous read/write access (does it make sense?) + +- Support for ios_base::ate open mode + +- Locale support? + +- Check public interface to see which calls give problems + (due to dependence on library internals) + +- Override operator<<(ostream&, gzfilebuf*) to allow direct copying + of stream buffer to stream ( i.e. os << is.rdbuf(); ) diff --git a/src/external/zlib-1.2.11/contrib/iostream3/test.cc b/src/external/zlib-1.2.11/contrib/iostream3/test.cc new file mode 100644 index 000000000..94235334f --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream3/test.cc @@ -0,0 +1,50 @@ +/* + * Test program for gzifstream and gzofstream + * + * by Ludwig Schwardt + * original version by Kevin Ruland + */ + +#include "zfstream.h" +#include // for cout + +int main() { + + gzofstream outf; + gzifstream inf; + char buf[80]; + + outf.open("test1.txt.gz"); + outf << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + outf.close(); + std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n" + << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + + std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n"; + inf.open("test1.txt.gz"); + while (inf.getline(buf,80,'\n')) { + std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; + } + inf.close(); + + outf.rdbuf()->pubsetbuf(0,0); + outf.open("test2.txt.gz"); + outf << setcompression(Z_NO_COMPRESSION) + << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + outf.close(); + std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form"; + + std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n"; + inf.rdbuf()->pubsetbuf(0,0); + inf.open("test2.txt.gz"); + while (inf.getline(buf,80,'\n')) { + std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; + } + inf.close(); + + return 0; + +} diff --git a/src/external/zlib-1.2.11/contrib/iostream3/zfstream.cc b/src/external/zlib-1.2.11/contrib/iostream3/zfstream.cc new file mode 100644 index 000000000..94eb93344 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream3/zfstream.cc @@ -0,0 +1,479 @@ +/* + * A C++ I/O streams interface to the zlib gz* functions + * + * by Ludwig Schwardt + * original version by Kevin Ruland + * + * This version is standard-compliant and compatible with gcc 3.x. + */ + +#include "zfstream.h" +#include // for strcpy, strcat, strlen (mode strings) +#include // for BUFSIZ + +// Internal buffer sizes (default and "unbuffered" versions) +#define BIGBUFSIZE BUFSIZ +#define SMALLBUFSIZE 1 + +/*****************************************************************************/ + +// Default constructor +gzfilebuf::gzfilebuf() +: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false), + buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true) +{ + // No buffers to start with + this->disable_buffer(); +} + +// Destructor +gzfilebuf::~gzfilebuf() +{ + // Sync output buffer and close only if responsible for file + // (i.e. attached streams should be left open at this stage) + this->sync(); + if (own_fd) + this->close(); + // Make sure internal buffer is deallocated + this->disable_buffer(); +} + +// Set compression level and strategy +int +gzfilebuf::setcompression(int comp_level, + int comp_strategy) +{ + return gzsetparams(file, comp_level, comp_strategy); +} + +// Open gzipped file +gzfilebuf* +gzfilebuf::open(const char *name, + std::ios_base::openmode mode) +{ + // Fail if file already open + if (this->is_open()) + return NULL; + // Don't support simultaneous read/write access (yet) + if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) + return NULL; + + // Build mode string for gzopen and check it [27.8.1.3.2] + char char_mode[6] = "\0\0\0\0\0"; + if (!this->open_mode(mode, char_mode)) + return NULL; + + // Attempt to open file + if ((file = gzopen(name, char_mode)) == NULL) + return NULL; + + // On success, allocate internal buffer and set flags + this->enable_buffer(); + io_mode = mode; + own_fd = true; + return this; +} + +// Attach to gzipped file +gzfilebuf* +gzfilebuf::attach(int fd, + std::ios_base::openmode mode) +{ + // Fail if file already open + if (this->is_open()) + return NULL; + // Don't support simultaneous read/write access (yet) + if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) + return NULL; + + // Build mode string for gzdopen and check it [27.8.1.3.2] + char char_mode[6] = "\0\0\0\0\0"; + if (!this->open_mode(mode, char_mode)) + return NULL; + + // Attempt to attach to file + if ((file = gzdopen(fd, char_mode)) == NULL) + return NULL; + + // On success, allocate internal buffer and set flags + this->enable_buffer(); + io_mode = mode; + own_fd = false; + return this; +} + +// Close gzipped file +gzfilebuf* +gzfilebuf::close() +{ + // Fail immediately if no file is open + if (!this->is_open()) + return NULL; + // Assume success + gzfilebuf* retval = this; + // Attempt to sync and close gzipped file + if (this->sync() == -1) + retval = NULL; + if (gzclose(file) < 0) + retval = NULL; + // File is now gone anyway (postcondition [27.8.1.3.8]) + file = NULL; + own_fd = false; + // Destroy internal buffer if it exists + this->disable_buffer(); + return retval; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Convert int open mode to mode string +bool +gzfilebuf::open_mode(std::ios_base::openmode mode, + char* c_mode) const +{ + bool testb = mode & std::ios_base::binary; + bool testi = mode & std::ios_base::in; + bool testo = mode & std::ios_base::out; + bool testt = mode & std::ios_base::trunc; + bool testa = mode & std::ios_base::app; + + // Check for valid flag combinations - see [27.8.1.3.2] (Table 92) + // Original zfstream hardcoded the compression level to maximum here... + // Double the time for less than 1% size improvement seems + // excessive though - keeping it at the default level + // To change back, just append "9" to the next three mode strings + if (!testi && testo && !testt && !testa) + strcpy(c_mode, "w"); + if (!testi && testo && !testt && testa) + strcpy(c_mode, "a"); + if (!testi && testo && testt && !testa) + strcpy(c_mode, "w"); + if (testi && !testo && !testt && !testa) + strcpy(c_mode, "r"); + // No read/write mode yet +// if (testi && testo && !testt && !testa) +// strcpy(c_mode, "r+"); +// if (testi && testo && testt && !testa) +// strcpy(c_mode, "w+"); + + // Mode string should be empty for invalid combination of flags + if (strlen(c_mode) == 0) + return false; + if (testb) + strcat(c_mode, "b"); + return true; +} + +// Determine number of characters in internal get buffer +std::streamsize +gzfilebuf::showmanyc() +{ + // Calls to underflow will fail if file not opened for reading + if (!this->is_open() || !(io_mode & std::ios_base::in)) + return -1; + // Make sure get area is in use + if (this->gptr() && (this->gptr() < this->egptr())) + return std::streamsize(this->egptr() - this->gptr()); + else + return 0; +} + +// Fill get area from gzipped file +gzfilebuf::int_type +gzfilebuf::underflow() +{ + // If something is left in the get area by chance, return it + // (this shouldn't normally happen, as underflow is only supposed + // to be called when gptr >= egptr, but it serves as error check) + if (this->gptr() && (this->gptr() < this->egptr())) + return traits_type::to_int_type(*(this->gptr())); + + // If the file hasn't been opened for reading, produce error + if (!this->is_open() || !(io_mode & std::ios_base::in)) + return traits_type::eof(); + + // Attempt to fill internal buffer from gzipped file + // (buffer must be guaranteed to exist...) + int bytes_read = gzread(file, buffer, buffer_size); + // Indicates error or EOF + if (bytes_read <= 0) + { + // Reset get area + this->setg(buffer, buffer, buffer); + return traits_type::eof(); + } + // Make all bytes read from file available as get area + this->setg(buffer, buffer, buffer + bytes_read); + + // Return next character in get area + return traits_type::to_int_type(*(this->gptr())); +} + +// Write put area to gzipped file +gzfilebuf::int_type +gzfilebuf::overflow(int_type c) +{ + // Determine whether put area is in use + if (this->pbase()) + { + // Double-check pointer range + if (this->pptr() > this->epptr() || this->pptr() < this->pbase()) + return traits_type::eof(); + // Add extra character to buffer if not EOF + if (!traits_type::eq_int_type(c, traits_type::eof())) + { + *(this->pptr()) = traits_type::to_char_type(c); + this->pbump(1); + } + // Number of characters to write to file + int bytes_to_write = this->pptr() - this->pbase(); + // Overflow doesn't fail if nothing is to be written + if (bytes_to_write > 0) + { + // If the file hasn't been opened for writing, produce error + if (!this->is_open() || !(io_mode & std::ios_base::out)) + return traits_type::eof(); + // If gzipped file won't accept all bytes written to it, fail + if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write) + return traits_type::eof(); + // Reset next pointer to point to pbase on success + this->pbump(-bytes_to_write); + } + } + // Write extra character to file if not EOF + else if (!traits_type::eq_int_type(c, traits_type::eof())) + { + // If the file hasn't been opened for writing, produce error + if (!this->is_open() || !(io_mode & std::ios_base::out)) + return traits_type::eof(); + // Impromptu char buffer (allows "unbuffered" output) + char_type last_char = traits_type::to_char_type(c); + // If gzipped file won't accept this character, fail + if (gzwrite(file, &last_char, 1) != 1) + return traits_type::eof(); + } + + // If you got here, you have succeeded (even if c was EOF) + // The return value should therefore be non-EOF + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); + else + return c; +} + +// Assign new buffer +std::streambuf* +gzfilebuf::setbuf(char_type* p, + std::streamsize n) +{ + // First make sure stuff is sync'ed, for safety + if (this->sync() == -1) + return NULL; + // If buffering is turned off on purpose via setbuf(0,0), still allocate one... + // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at + // least a buffer of size 1 (very inefficient though, therefore make it bigger?) + // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems) + if (!p || !n) + { + // Replace existing buffer (if any) with small internal buffer + this->disable_buffer(); + buffer = NULL; + buffer_size = 0; + own_buffer = true; + this->enable_buffer(); + } + else + { + // Replace existing buffer (if any) with external buffer + this->disable_buffer(); + buffer = p; + buffer_size = n; + own_buffer = false; + this->enable_buffer(); + } + return this; +} + +// Write put area to gzipped file (i.e. ensures that put area is empty) +int +gzfilebuf::sync() +{ + return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Allocate internal buffer +void +gzfilebuf::enable_buffer() +{ + // If internal buffer required, allocate one + if (own_buffer && !buffer) + { + // Check for buffered vs. "unbuffered" + if (buffer_size > 0) + { + // Allocate internal buffer + buffer = new char_type[buffer_size]; + // Get area starts empty and will be expanded by underflow as need arises + this->setg(buffer, buffer, buffer); + // Setup entire internal buffer as put area. + // The one-past-end pointer actually points to the last element of the buffer, + // so that overflow(c) can safely add the extra character c to the sequence. + // These pointers remain in place for the duration of the buffer + this->setp(buffer, buffer + buffer_size - 1); + } + else + { + // Even in "unbuffered" case, (small?) get buffer is still required + buffer_size = SMALLBUFSIZE; + buffer = new char_type[buffer_size]; + this->setg(buffer, buffer, buffer); + // "Unbuffered" means no put buffer + this->setp(0, 0); + } + } + else + { + // If buffer already allocated, reset buffer pointers just to make sure no + // stale chars are lying around + this->setg(buffer, buffer, buffer); + this->setp(buffer, buffer + buffer_size - 1); + } +} + +// Destroy internal buffer +void +gzfilebuf::disable_buffer() +{ + // If internal buffer exists, deallocate it + if (own_buffer && buffer) + { + // Preserve unbuffered status by zeroing size + if (!this->pbase()) + buffer_size = 0; + delete[] buffer; + buffer = NULL; + this->setg(0, 0, 0); + this->setp(0, 0); + } + else + { + // Reset buffer pointers to initial state if external buffer exists + this->setg(buffer, buffer, buffer); + if (buffer) + this->setp(buffer, buffer + buffer_size - 1); + else + this->setp(0, 0); + } +} + +/*****************************************************************************/ + +// Default constructor initializes stream buffer +gzifstream::gzifstream() +: std::istream(NULL), sb() +{ this->init(&sb); } + +// Initialize stream buffer and open file +gzifstream::gzifstream(const char* name, + std::ios_base::openmode mode) +: std::istream(NULL), sb() +{ + this->init(&sb); + this->open(name, mode); +} + +// Initialize stream buffer and attach to file +gzifstream::gzifstream(int fd, + std::ios_base::openmode mode) +: std::istream(NULL), sb() +{ + this->init(&sb); + this->attach(fd, mode); +} + +// Open file and go into fail() state if unsuccessful +void +gzifstream::open(const char* name, + std::ios_base::openmode mode) +{ + if (!sb.open(name, mode | std::ios_base::in)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Attach to file and go into fail() state if unsuccessful +void +gzifstream::attach(int fd, + std::ios_base::openmode mode) +{ + if (!sb.attach(fd, mode | std::ios_base::in)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Close file +void +gzifstream::close() +{ + if (!sb.close()) + this->setstate(std::ios_base::failbit); +} + +/*****************************************************************************/ + +// Default constructor initializes stream buffer +gzofstream::gzofstream() +: std::ostream(NULL), sb() +{ this->init(&sb); } + +// Initialize stream buffer and open file +gzofstream::gzofstream(const char* name, + std::ios_base::openmode mode) +: std::ostream(NULL), sb() +{ + this->init(&sb); + this->open(name, mode); +} + +// Initialize stream buffer and attach to file +gzofstream::gzofstream(int fd, + std::ios_base::openmode mode) +: std::ostream(NULL), sb() +{ + this->init(&sb); + this->attach(fd, mode); +} + +// Open file and go into fail() state if unsuccessful +void +gzofstream::open(const char* name, + std::ios_base::openmode mode) +{ + if (!sb.open(name, mode | std::ios_base::out)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Attach to file and go into fail() state if unsuccessful +void +gzofstream::attach(int fd, + std::ios_base::openmode mode) +{ + if (!sb.attach(fd, mode | std::ios_base::out)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Close file +void +gzofstream::close() +{ + if (!sb.close()) + this->setstate(std::ios_base::failbit); +} diff --git a/src/external/zlib-1.2.11/contrib/iostream3/zfstream.h b/src/external/zlib-1.2.11/contrib/iostream3/zfstream.h new file mode 100644 index 000000000..8574479ae --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/iostream3/zfstream.h @@ -0,0 +1,466 @@ +/* + * A C++ I/O streams interface to the zlib gz* functions + * + * by Ludwig Schwardt + * original version by Kevin Ruland + * + * This version is standard-compliant and compatible with gcc 3.x. + */ + +#ifndef ZFSTREAM_H +#define ZFSTREAM_H + +#include // not iostream, since we don't need cin/cout +#include +#include "zlib.h" + +/*****************************************************************************/ + +/** + * @brief Gzipped file stream buffer class. + * + * This class implements basic_filebuf for gzipped files. It doesn't yet support + * seeking (allowed by zlib but slow/limited), putback and read/write access + * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard + * file streambuf. +*/ +class gzfilebuf : public std::streambuf +{ +public: + // Default constructor. + gzfilebuf(); + + // Destructor. + virtual + ~gzfilebuf(); + + /** + * @brief Set compression level and strategy on the fly. + * @param comp_level Compression level (see zlib.h for allowed values) + * @param comp_strategy Compression strategy (see zlib.h for allowed values) + * @return Z_OK on success, Z_STREAM_ERROR otherwise. + * + * Unfortunately, these parameters cannot be modified separately, as the + * previous zfstream version assumed. Since the strategy is seldom changed, + * it can default and setcompression(level) then becomes like the old + * setcompressionlevel(level). + */ + int + setcompression(int comp_level, + int comp_strategy = Z_DEFAULT_STRATEGY); + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() const { return (file != NULL); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + open(const char* name, + std::ios_base::openmode mode); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + attach(int fd, + std::ios_base::openmode mode); + + /** + * @brief Close gzipped file. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + close(); + +protected: + /** + * @brief Convert ios open mode int to mode string used by zlib. + * @return True if valid mode flag combination. + */ + bool + open_mode(std::ios_base::openmode mode, + char* c_mode) const; + + /** + * @brief Number of characters available in stream buffer. + * @return Number of characters. + * + * This indicates number of characters in get area of stream buffer. + * These characters can be read without accessing the gzipped file. + */ + virtual std::streamsize + showmanyc(); + + /** + * @brief Fill get area from gzipped file. + * @return First character in get area on success, EOF on error. + * + * This actually reads characters from gzipped file to stream + * buffer. Always buffered. + */ + virtual int_type + underflow(); + + /** + * @brief Write put area to gzipped file. + * @param c Extra character to add to buffer contents. + * @return Non-EOF on success, EOF on error. + * + * This actually writes characters in stream buffer to + * gzipped file. With unbuffered output this is done one + * character at a time. + */ + virtual int_type + overflow(int_type c = traits_type::eof()); + + /** + * @brief Installs external stream buffer. + * @param p Pointer to char buffer. + * @param n Size of external buffer. + * @return @c this on success, NULL on failure. + * + * Call setbuf(0,0) to enable unbuffered output. + */ + virtual std::streambuf* + setbuf(char_type* p, + std::streamsize n); + + /** + * @brief Flush stream buffer to file. + * @return 0 on success, -1 on error. + * + * This calls underflow(EOF) to do the job. + */ + virtual int + sync(); + +// +// Some future enhancements +// +// virtual int_type uflow(); +// virtual int_type pbackfail(int_type c = traits_type::eof()); +// virtual pos_type +// seekoff(off_type off, +// std::ios_base::seekdir way, +// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out); +// virtual pos_type +// seekpos(pos_type sp, +// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out); + +private: + /** + * @brief Allocate internal buffer. + * + * This function is safe to call multiple times. It will ensure + * that a proper internal buffer exists if it is required. If the + * buffer already exists or is external, the buffer pointers will be + * reset to their original state. + */ + void + enable_buffer(); + + /** + * @brief Destroy internal buffer. + * + * This function is safe to call multiple times. It will ensure + * that the internal buffer is deallocated if it exists. In any + * case, it will also reset the buffer pointers. + */ + void + disable_buffer(); + + /** + * Underlying file pointer. + */ + gzFile file; + + /** + * Mode in which file was opened. + */ + std::ios_base::openmode io_mode; + + /** + * @brief True if this object owns file descriptor. + * + * This makes the class responsible for closing the file + * upon destruction. + */ + bool own_fd; + + /** + * @brief Stream buffer. + * + * For simplicity this remains allocated on the free store for the + * entire life span of the gzfilebuf object, unless replaced by setbuf. + */ + char_type* buffer; + + /** + * @brief Stream buffer size. + * + * Defaults to system default buffer size (typically 8192 bytes). + * Modified by setbuf. + */ + std::streamsize buffer_size; + + /** + * @brief True if this object owns stream buffer. + * + * This makes the class responsible for deleting the buffer + * upon destruction. + */ + bool own_buffer; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file input stream class. + * + * This class implements ifstream for gzipped files. Seeking and putback + * is not supported yet. +*/ +class gzifstream : public std::istream +{ +public: + // Default constructor + gzifstream(); + + /** + * @brief Construct stream on gzipped file to be opened. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::in). + */ + explicit + gzifstream(const char* name, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Construct stream on already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::in). + */ + explicit + gzifstream(int fd, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * Obtain underlying stream buffer. + */ + gzfilebuf* + rdbuf() const + { return const_cast(&sb); } + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() { return sb.is_open(); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::in). + * + * Stream will be in state good() if file opens successfully; + * otherwise in state fail(). This differs from the behavior of + * ifstream, which never sets the state to good() and therefore + * won't allow you to reuse the stream for a second file unless + * you manually clear() the state. The choice is a matter of + * convenience. + */ + void + open(const char* name, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::in). + * + * Stream will be in state good() if attach succeeded; otherwise + * in state fail(). + */ + void + attach(int fd, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Close gzipped file. + * + * Stream will be in state fail() if close failed. + */ + void + close(); + +private: + /** + * Underlying stream buffer. + */ + gzfilebuf sb; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file output stream class. + * + * This class implements ofstream for gzipped files. Seeking and putback + * is not supported yet. +*/ +class gzofstream : public std::ostream +{ +public: + // Default constructor + gzofstream(); + + /** + * @brief Construct stream on gzipped file to be opened. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::out). + */ + explicit + gzofstream(const char* name, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Construct stream on already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::out). + */ + explicit + gzofstream(int fd, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * Obtain underlying stream buffer. + */ + gzfilebuf* + rdbuf() const + { return const_cast(&sb); } + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() { return sb.is_open(); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::out). + * + * Stream will be in state good() if file opens successfully; + * otherwise in state fail(). This differs from the behavior of + * ofstream, which never sets the state to good() and therefore + * won't allow you to reuse the stream for a second file unless + * you manually clear() the state. The choice is a matter of + * convenience. + */ + void + open(const char* name, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::out). + * + * Stream will be in state good() if attach succeeded; otherwise + * in state fail(). + */ + void + attach(int fd, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Close gzipped file. + * + * Stream will be in state fail() if close failed. + */ + void + close(); + +private: + /** + * Underlying stream buffer. + */ + gzfilebuf sb; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file output stream manipulator class. + * + * This class defines a two-argument manipulator for gzofstream. It is used + * as base for the setcompression(int,int) manipulator. +*/ +template + class gzomanip2 + { + public: + // Allows insertor to peek at internals + template + friend gzofstream& + operator<<(gzofstream&, + const gzomanip2&); + + // Constructor + gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2), + T1 v1, + T2 v2); + private: + // Underlying manipulator function + gzofstream& + (*func)(gzofstream&, T1, T2); + + // Arguments for manipulator function + T1 val1; + T2 val2; + }; + +/*****************************************************************************/ + +// Manipulator function thunks through to stream buffer +inline gzofstream& +setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY) +{ + (gzs.rdbuf())->setcompression(l, s); + return gzs; +} + +// Manipulator constructor stores arguments +template + inline + gzomanip2::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2), + T1 v1, + T2 v2) + : func(f), val1(v1), val2(v2) + { } + +// Insertor applies underlying manipulator function to stream +template + inline gzofstream& + operator<<(gzofstream& s, const gzomanip2& m) + { return (*m.func)(s, m.val1, m.val2); } + +// Insert this onto stream to simplify setting of compression level +inline gzomanip2 +setcompression(int l, int s = Z_DEFAULT_STRATEGY) +{ return gzomanip2(&setcompression, l, s); } + +#endif // ZFSTREAM_H diff --git a/src/external/zlib-1.2.11/contrib/masmx64/bld_ml64.bat b/src/external/zlib-1.2.11/contrib/masmx64/bld_ml64.bat new file mode 100644 index 000000000..f74bcef5b --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx64/bld_ml64.bat @@ -0,0 +1,2 @@ +ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +ml64.exe /Flgvmat64 /c /Zi gvmat64.asm diff --git a/src/external/zlib-1.2.11/contrib/masmx64/gvmat64.asm b/src/external/zlib-1.2.11/contrib/masmx64/gvmat64.asm new file mode 100644 index 000000000..c1817f1be --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx64/gvmat64.asm @@ -0,0 +1,553 @@ +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); /* current match */ + +; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64 +; (AMD64 on Athlon 64, Opteron, Phenom +; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7) +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software +; 3. This notice may not be removed or altered from any source distribution. +; +; +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for infozip Zip, I use option: +; ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm +; +; to compile this file for zLib, I use option: +; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm +; Be carrefull to adapt zlib1222add below to your version of zLib +; (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change +; value of zlib1222add later) +; +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK +; +; (you can get Windows WDK with ml64 for AMD64 from +; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price) +; + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ +.code +longest_match PROC + + +;LocalVarsSize equ 88 + LocalVarsSize equ 72 + +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp + + chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len + ; low word: s->wmask +;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10 +;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11 +;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w +;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx +;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13 +;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d +;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9 +IFDEF INFOZIP +ELSE + nicematch equ (rsp + 16 - LocalVarsSize) ; a good enough match size +ENDIF + +save_rdi equ rsp + 24 - LocalVarsSize +save_rsi equ rsp + 32 - LocalVarsSize +save_rbx equ rsp + 40 - LocalVarsSize +save_rbp equ rsp + 48 - LocalVarsSize +save_r12 equ rsp + 56 - LocalVarsSize +save_r13 equ rsp + 64 - LocalVarsSize +;save_r14 equ rsp + 72 - LocalVarsSize +;save_r15 equ rsp + 80 - LocalVarsSize + + +; summary of register usage +; scanend ebx +; scanendw bx +; chainlenwmask edx +; curmatch rsi +; curmatchd esi +; windowbestlen r8 +; scanalign r9 +; scanalignd r9d +; window r10 +; bestlen r11 +; bestlend r11d +; scanstart r12d +; scanstartw r12w +; scan r13 +; nicematch r14d +; limit r15 +; limitd r15d +; prev rcx + +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure + + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + +IFDEF INFOZIP + +_DATA SEGMENT +COMM window_size:DWORD +; WMask ; 7fff +COMM window:BYTE:010040H +COMM prev:WORD:08000H +; MatchLen : unused +; PrevMatch : unused +COMM strstart:DWORD +COMM match_start:DWORD +; Lookahead : ignore +COMM prev_length:DWORD ; PrevLen +COMM max_chain_length:DWORD +COMM good_match:DWORD +COMM nice_match:DWORD +prev_ad equ OFFSET prev +window_ad equ OFFSET window +nicematch equ nice_match +_DATA ENDS +WMask equ 07fffh + +ELSE + + IFNDEF zlib1222add + zlib1222add equ 8 + ENDIF +dsWSize equ 56+zlib1222add+(zlib1222add/2) +dsWMask equ 64+zlib1222add+(zlib1222add/2) +dsWindow equ 72+zlib1222add +dsPrev equ 88+zlib1222add +dsMatchLen equ 128+zlib1222add +dsPrevMatch equ 132+zlib1222add +dsStrStart equ 140+zlib1222add +dsMatchStart equ 144+zlib1222add +dsLookahead equ 148+zlib1222add +dsPrevLen equ 152+zlib1222add +dsMaxChainLen equ 156+zlib1222add +dsGoodMatch equ 172+zlib1222add +dsNiceMatch equ 176+zlib1222add + +window_size equ [ rcx + dsWSize] +WMask equ [ rcx + dsWMask] +window_ad equ [ rcx + dsWindow] +prev_ad equ [ rcx + dsPrev] +strstart equ [ rcx + dsStrStart] +match_start equ [ rcx + dsMatchStart] +Lookahead equ [ rcx + dsLookahead] ; 0ffffffffh on infozip +prev_length equ [ rcx + dsPrevLen] +max_chain_length equ [ rcx + dsMaxChainLen] +good_match equ [ rcx + dsGoodMatch] +nice_match equ [ rcx + dsNiceMatch] +ENDIF + +; parameter 1 in r8(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + + + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) + +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx + + mov [save_rdi],rdi + mov [save_rsi],rsi + mov [save_rbx],rbx + mov [save_rbp],rbp +IFDEF INFOZIP + mov r8d,ecx +ELSE + mov r8d,edx +ENDIF + mov [save_r12],r12 + mov [save_r13],r13 +; mov [save_r14],r14 +; mov [save_r15],r15 + + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +;;; on zlib only +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + +IFDEF INFOZIP + mov [chainlenwmask], ebx +; on infozip nice_match = [nice_match] +ELSE + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d +ENDIF + +;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; +IFDEF INFOZIP + mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1)) +ELSE + mov eax, window_size + sub eax, MIN_LOOKAHEAD +ENDIF + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +;;; int best_len = s->prev_length; + + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 + jmp LookupLoopIsZero + + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + jnz LookupLoop1 + + +;;; Store the current value of chainlen. + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + lea rsi,[r8+r10] + mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + jnz short LoopCmps + jmp short LenMaximum +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0000FFFFh + jnz LenLower + + test eax,0ffffffffh + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + jnz LenLower + +LenLower32: + shr eax,16 + add rdx,2 +LenLower: sub al, 1 + adc rdx, 0 +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// + + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + jge LeaveNow + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: +IFDEF INFOZIP + mov eax,r11d +ELSE + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d +ENDIF + +;;; Restore the stack and return from whence we came. + + + mov rsi,[save_rsi] + mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] +; mov r14,[save_r14] +; mov r15,[save_r15] + + + ret 0 +; please don't remove this string ! +; Your can freely use gvmat64 in any free or commercial app +; but it is far better don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 +longest_match ENDP + +match_init PROC + ret 0 +match_init ENDP + + +END diff --git a/src/external/zlib-1.2.11/contrib/masmx64/inffas8664.c b/src/external/zlib-1.2.11/contrib/masmx64/inffas8664.c new file mode 100644 index 000000000..aa861a333 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx64/inffas8664.c @@ -0,0 +1,186 @@ +/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding + * version for AMD64 on Windows using Microsoft C compiler + * + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant + * + * inffas8664.c call function inffas8664fnc in inffasx64.asm + * inffasx64.asm is automatically convert from AMD64 portion of inffas86.c + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + * + */ + +#include +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ + + + + typedef struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } type_ar; +#ifdef ASMINF + +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + type_ar ar; + void inffas8664fnc(struct inffast_ar * par); + + + +#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64)) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->wnext; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + + inffas8664fnc(&ar); + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = (unsigned long)ar.hold; + state->bits = ar.bits; + return; +} + +#endif diff --git a/src/external/zlib-1.2.11/contrib/masmx64/inffasx64.asm b/src/external/zlib-1.2.11/contrib/masmx64/inffasx64.asm new file mode 100644 index 000000000..41ec82392 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx64/inffasx64.asm @@ -0,0 +1,396 @@ +; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding +; version for AMD64 on Windows using Microsoft C compiler +; +; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c +; inffasx64.asm is called by inffas8664.c, which contain more info. + + +; to compile this file, I use option +; ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +; with Microsoft Macro Assembler (x64) for AMD64 +; + +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK +; +; (you can get Windows WDK with ml64 for AMD64 from +; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price) +; + + +.code +inffas8664fnc PROC + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch. + + + mov [rsp-8],rsi + mov [rsp-16],rdi + mov [rsp-24],r12 + mov [rsp-32],r13 + mov [rsp-40],r14 + mov [rsp-48],r15 + mov [rsp-56],rbx + + mov rax,rcx + + mov [rax+8], rbp ; /* save regs rbp and rsp */ + mov [rax], rsp + + mov rsp, rax ; /* make rsp point to &ar */ + + mov rsi, [rsp+16] ; /* rsi = in */ + mov rdi, [rsp+32] ; /* rdi = out */ + mov r9, [rsp+24] ; /* r9 = last */ + mov r10, [rsp+48] ; /* r10 = end */ + mov rbp, [rsp+64] ; /* rbp = lcode */ + mov r11, [rsp+72] ; /* r11 = dcode */ + mov rdx, [rsp+80] ; /* rdx = hold */ + mov ebx, [rsp+88] ; /* ebx = bits */ + mov r12d, [rsp+100] ; /* r12d = lmask */ + mov r13d, [rsp+104] ; /* r13d = dmask */ + ; /* r14d = len */ + ; /* r15d = dist */ + + + cld + cmp r10, rdi + je L_one_time ; /* if only one decode left */ + cmp r9, rsi + + jne L_do_loop + + +L_one_time: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code_one_time + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + jmp L_get_length_code_one_time + +ALIGN 4 +L_while_test: + cmp r10, rdi + jbe L_break_loop + cmp r9, rsi + jbe L_break_loop + +L_do_loop: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_length_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + mov r8, r12 ; /* r8 = lmask */ + shr eax, 16 ; /* output this.val char */ + stosb + +L_get_length_code_one_time: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + shr eax, 16 ; /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov r14d, eax ; /* len = this */ + shr r14d, 16 ; /* len = this.val */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */ + and cl, 15 ; /* op &= 15 */ + jz L_decode_distance ; /* if (!op) */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r14d, eax ; /* len += hold & mask[op] */ + +L_decode_distance: + mov r8, r13 ; /* r8 = dmask */ + cmp bl, 32 + ja L_get_distance_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_distance_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */ + +L_dodist: + mov r15d, eax ; /* dist = this */ + shr r15d, 16 ; /* dist = this.val */ + mov cl, ah + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + mov cl, al ; /* cl = this.op */ + + test al, 16 ; /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 ; /* op &= 15 */ + jz L_check_dist_one + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax ; /* (1 << op) - 1 */ + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r15d, eax ; /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov r8, rsi ; /* save in so from can use it's reg */ + mov rax, rdi + sub rax, [rsp+40] ; /* nbytes = out - beg */ + + cmp eax, r15d + jb L_clip_window ; /* if (dist > nbytes) 4.2% */ + + mov ecx, r14d ; /* ecx = len */ + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two ; /* if len % 2 == 0 */ + + rep movsw + mov al, [rsi] + mov [rdi], al + inc rdi + + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +L_copy_two: + rep movsw + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp r15d, 1 ; /* if dist 1, is a memset */ + jne L_check_window + cmp [rsp+40], rdi ; /* if out == beg, outside window */ + je L_check_window + + mov ecx, r14d ; /* ecx = len */ + mov al, [rdi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [rdi], al + inc rdi + +L_set_two: + rep stosw + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r14d ; /* eax += len */ + mov eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r15d ; /* eax += dist */ + mov eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax ; /* ecx = nbytes */ + mov eax, [rsp+92] ; /* eax = wsize, prepare for dist cmp */ + neg ecx ; /* nbytes = -nbytes */ + + cmp eax, r15d + jb L_invalid_distance_too_far ; /* if (dist > wsize) */ + + add ecx, r15d ; /* nbytes = dist - nbytes */ + cmp dword ptr [rsp+96], 0 + jne L_wrap_around_window ; /* if (write != 0) */ + + mov rsi, [rsp+56] ; /* from = window */ + sub eax, ecx ; /* eax -= nbytes */ + add rsi, rax ; /* from += wsize - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp r14d, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* eax -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = &out[ -dist ] */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [rsp+96] ; /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window ; /* if (write >= nbytes) */ + + mov esi, [rsp+92] ; /* from = wsize */ + add rsi, [rsp+56] ; /* from += window */ + add rsi, rax ; /* from += write */ + sub rsi, rcx ; /* from -= nbytes */ + sub ecx, eax ; /* nbytes -= write */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, [rsp+56] ; /* from = window */ + mov ecx, [rsp+96] ; /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + mov rsi, [rsp+56] ; /* rsi = window */ + add rsi, rax + sub rsi, rcx ; /* from += write - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy ; /* if (nbytes >= len) */ + +ALIGN 4 +L_do_copy: + mov ecx, eax ; /* ecx = len */ + rep movsb + + mov rsi, r8 ; /* move in back to %esi, toss from */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [rsp+116], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [rsp+116], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [rsp+116], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov dword ptr [rsp+116], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [rsp+116], 0 + +L_break_loop_with_status: +; /* put in, out, bits, and hold back into ar and pop esp */ + mov [rsp+16], rsi ; /* in */ + mov [rsp+32], rdi ; /* out */ + mov [rsp+88], ebx ; /* bits */ + mov [rsp+80], rdx ; /* hold */ + + mov rax, [rsp] ; /* restore rbp and rsp */ + mov rbp, [rsp+8] + mov rsp, rax + + + + mov rsi,[rsp-8] + mov rdi,[rsp-16] + mov r12,[rsp-24] + mov r13,[rsp-32] + mov r14,[rsp-40] + mov r15,[rsp-48] + mov rbx,[rsp-56] + + ret 0 +; : +; : "m" (ar) +; : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", +; "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" +; ); + +inffas8664fnc ENDP +;_TEXT ENDS +END diff --git a/src/external/zlib-1.2.11/contrib/masmx64/readme.txt b/src/external/zlib-1.2.11/contrib/masmx64/readme.txt new file mode 100644 index 000000000..652571c7a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx64/readme.txt @@ -0,0 +1,31 @@ +Summary +------- +This directory contains ASM implementations of the functions +longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t), +for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits. + +gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits + assembly optimized version from Jean-loup Gailly original longest_match function + +inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing + original function from Mark Adler + +Use instructions +---------------- +Assemble the .asm files using MASM and put the object files into the zlib source +directory. You can also get object files here: + + http://www.winimage.com/zLibDll/zlib124_masm_obj.zip + +define ASMV and ASMINF in your project. Include inffas8664.c in your source tree, +and inffasx64.obj and gvmat64.obj as object to link. + + +Build instructions +------------------ +run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe) + +ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK + +You can get Windows 2003 server DDK with ml64 and cl for AMD64 from + http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price) diff --git a/src/external/zlib-1.2.11/contrib/masmx86/bld_ml32.bat b/src/external/zlib-1.2.11/contrib/masmx86/bld_ml32.bat new file mode 100644 index 000000000..fcf5755e4 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx86/bld_ml32.bat @@ -0,0 +1,2 @@ +ml /coff /Zi /c /Flmatch686.lst match686.asm +ml /coff /Zi /c /Flinffas32.lst inffas32.asm diff --git a/src/external/zlib-1.2.11/contrib/masmx86/inffas32.asm b/src/external/zlib-1.2.11/contrib/masmx86/inffas32.asm new file mode 100644 index 000000000..cb37a81e4 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx86/inffas32.asm @@ -0,0 +1,1080 @@ +;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding +; * +; * inffas32.asm is derivated from inffas86.c, with translation of assembly code +; * +; * Copyright (C) 1995-2003 Mark Adler +; * For conditions of distribution and use, see copyright notice in zlib.h +; * +; * Copyright (C) 2003 Chris Anderson +; * Please use the copyright conditions above. +; * +; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from +; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at +; * the moment. I have successfully compiled and tested this code with gcc2.96, +; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S +; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX +; * enabled. I will attempt to merge the MMX code into this version. Newer +; * versions of this and inffast.S can be found at +; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ +; * +; * 2005 : modification by Gilles Vollant +; */ +; For Visual C++ 4.x and higher and ML 6.x and higher +; ml.exe is in directory \MASM611C of Win95 DDK +; ml.exe is also distributed in http://www.masm32.com/masmdl.htm +; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/ +; +; +; compile with command line option +; ml /coff /Zi /c /Flinffas32.lst inffas32.asm + +; if you define NO_GZIP (see inflate.h), compile with +; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm + + +; zlib122sup is 0 fort zlib 1.2.2.1 and lower +; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head +; in inflate_state in inflate.h) +zlib1222sup equ 8 + + +IFDEF GUNZIP + INFLATE_MODE_TYPE equ 11 + INFLATE_MODE_BAD equ 26 +ELSE + IFNDEF NO_GUNZIP + INFLATE_MODE_TYPE equ 11 + INFLATE_MODE_BAD equ 26 + ELSE + INFLATE_MODE_TYPE equ 3 + INFLATE_MODE_BAD equ 17 + ENDIF +ENDIF + + +; 75 "inffast.S" +;FILE "inffast.S" + +;;;GLOBAL _inflate_fast + +;;;SECTION .text + + + + .586p + .mmx + + name inflate_fast_x86 + .MODEL FLAT + +_DATA segment +inflate_fast_use_mmx: + dd 1 + + +_TEXT segment + + + +ALIGN 4 + db 'Fast decoding Code from Chris Anderson' + db 0 + +ALIGN 4 +invalid_literal_length_code_msg: + db 'invalid literal/length code' + db 0 + +ALIGN 4 +invalid_distance_code_msg: + db 'invalid distance code' + db 0 + +ALIGN 4 +invalid_distance_too_far_msg: + db 'invalid distance too far back' + db 0 + + +ALIGN 4 +inflate_fast_mask: +dd 0 +dd 1 +dd 3 +dd 7 +dd 15 +dd 31 +dd 63 +dd 127 +dd 255 +dd 511 +dd 1023 +dd 2047 +dd 4095 +dd 8191 +dd 16383 +dd 32767 +dd 65535 +dd 131071 +dd 262143 +dd 524287 +dd 1048575 +dd 2097151 +dd 4194303 +dd 8388607 +dd 16777215 +dd 33554431 +dd 67108863 +dd 134217727 +dd 268435455 +dd 536870911 +dd 1073741823 +dd 2147483647 +dd 4294967295 + + +mode_state equ 0 ;/* state->mode */ +wsize_state equ (32+zlib1222sup) ;/* state->wsize */ +write_state equ (36+4+zlib1222sup) ;/* state->write */ +window_state equ (40+4+zlib1222sup) ;/* state->window */ +hold_state equ (44+4+zlib1222sup) ;/* state->hold */ +bits_state equ (48+4+zlib1222sup) ;/* state->bits */ +lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */ +distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */ +lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */ +distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */ + + +;;SECTION .text +; 205 "inffast.S" +;GLOBAL inflate_fast_use_mmx + +;SECTION .data + + +; GLOBAL inflate_fast_use_mmx:object +;.size inflate_fast_use_mmx, 4 +; 226 "inffast.S" +;SECTION .text + +ALIGN 4 +_inflate_fast proc near +.FPO (16, 4, 0, 0, 1, 0) + push edi + push esi + push ebp + push ebx + pushfd + sub esp,64 + cld + + + + + mov esi, [esp+88] + mov edi, [esi+28] + + + + + + + + mov edx, [esi+4] + mov eax, [esi+0] + + add edx,eax + sub edx,11 + + mov [esp+44],eax + mov [esp+20],edx + + mov ebp, [esp+92] + mov ecx, [esi+16] + mov ebx, [esi+12] + + sub ebp,ecx + neg ebp + add ebp,ebx + + sub ecx,257 + add ecx,ebx + + mov [esp+60],ebx + mov [esp+40],ebp + mov [esp+16],ecx +; 285 "inffast.S" + mov eax, [edi+lencode_state] + mov ecx, [edi+distcode_state] + + mov [esp+8],eax + mov [esp+12],ecx + + mov eax,1 + mov ecx, [edi+lenbits_state] + shl eax,cl + dec eax + mov [esp+0],eax + + mov eax,1 + mov ecx, [edi+distbits_state] + shl eax,cl + dec eax + mov [esp+4],eax + + mov eax, [edi+wsize_state] + mov ecx, [edi+write_state] + mov edx, [edi+window_state] + + mov [esp+52],eax + mov [esp+48],ecx + mov [esp+56],edx + + mov ebp, [edi+hold_state] + mov ebx, [edi+bits_state] +; 321 "inffast.S" + mov esi, [esp+44] + mov ecx, [esp+20] + cmp ecx,esi + ja L_align_long + + add ecx,11 + sub ecx,esi + mov eax,12 + sub eax,ecx + lea edi, [esp+28] + rep movsb + mov ecx,eax + xor eax,eax + rep stosb + lea esi, [esp+28] + mov [esp+20],esi + jmp L_is_aligned + + +L_align_long: + test esi,3 + jz L_is_aligned + xor eax,eax + mov al, [esi] + inc esi + mov ecx,ebx + add ebx,8 + shl eax,cl + or ebp,eax + jmp L_align_long + +L_is_aligned: + mov edi, [esp+60] +; 366 "inffast.S" +L_check_mmx: + cmp dword ptr [inflate_fast_use_mmx],2 + je L_init_mmx + ja L_do_loop + + push eax + push ebx + push ecx + push edx + pushfd + mov eax, [esp] + xor dword ptr [esp],0200000h + + + + + popfd + pushfd + pop edx + xor edx,eax + jz L_dont_use_mmx + xor eax,eax + cpuid + cmp ebx,0756e6547h + jne L_dont_use_mmx + cmp ecx,06c65746eh + jne L_dont_use_mmx + cmp edx,049656e69h + jne L_dont_use_mmx + mov eax,1 + cpuid + shr eax,8 + and eax,15 + cmp eax,6 + jne L_dont_use_mmx + test edx,0800000h + jnz L_use_mmx + jmp L_dont_use_mmx +L_use_mmx: + mov dword ptr [inflate_fast_use_mmx],2 + jmp L_check_mmx_pop +L_dont_use_mmx: + mov dword ptr [inflate_fast_use_mmx],3 +L_check_mmx_pop: + pop edx + pop ecx + pop ebx + pop eax + jmp L_check_mmx +; 426 "inffast.S" +ALIGN 4 +L_do_loop: +; 437 "inffast.S" + cmp bl,15 + ja L_get_length_code + + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + +L_get_length_code: + mov edx, [esp+0] + mov ecx, [esp+8] + and edx,ebp + mov eax, [ecx+edx*4] + +L_dolen: + + + + + + + mov cl,ah + sub bl,ah + shr ebp,cl + + + + + + + test al,al + jnz L_test_for_length_base + + shr eax,16 + stosb + +L_while_test: + + + cmp [esp+16],edi + jbe L_break_loop + + cmp [esp+20],esi + ja L_do_loop + jmp L_break_loop + +L_test_for_length_base: +; 502 "inffast.S" + mov edx,eax + shr edx,16 + mov cl,al + + test al,16 + jz L_test_for_second_level_length + and cl,15 + jz L_save_len + cmp bl,cl + jae L_add_bits_to_len + + mov ch,cl + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + mov cl,ch + +L_add_bits_to_len: + mov eax,1 + shl eax,cl + dec eax + sub bl,cl + and eax,ebp + shr ebp,cl + add edx,eax + +L_save_len: + mov [esp+24],edx + + +L_decode_distance: +; 549 "inffast.S" + cmp bl,15 + ja L_get_distance_code + + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + +L_get_distance_code: + mov edx, [esp+4] + mov ecx, [esp+12] + and edx,ebp + mov eax, [ecx+edx*4] + + +L_dodist: + mov edx,eax + shr edx,16 + mov cl,ah + sub bl,ah + shr ebp,cl +; 584 "inffast.S" + mov cl,al + + test al,16 + jz L_test_for_second_level_dist + and cl,15 + jz L_check_dist_one + cmp bl,cl + jae L_add_bits_to_dist + + mov ch,cl + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + mov cl,ch + +L_add_bits_to_dist: + mov eax,1 + shl eax,cl + dec eax + sub bl,cl + and eax,ebp + shr ebp,cl + add edx,eax + jmp L_check_window + +L_check_window: +; 625 "inffast.S" + mov [esp+44],esi + mov eax,edi + sub eax, [esp+40] + + cmp eax,edx + jb L_clip_window + + mov ecx, [esp+24] + mov esi,edi + sub esi,edx + + sub ecx,3 + mov al, [esi] + mov [edi],al + mov al, [esi+1] + mov dl, [esi+2] + add esi,3 + mov [edi+1],al + mov [edi+2],dl + add edi,3 + rep movsb + + mov esi, [esp+44] + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp edx,1 + jne L_check_window + cmp [esp+40],edi + je L_check_window + + dec edi + mov ecx, [esp+24] + mov al, [edi] + sub ecx,3 + + mov [edi+1],al + mov [edi+2],al + mov [edi+3],al + add edi,4 + rep stosb + + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + + + + + test al,64 + jnz L_test_for_end_of_block + + mov eax,1 + shl eax,cl + dec eax + and eax,ebp + add eax,edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + + + + + test al,64 + jnz L_invalid_distance_code + + mov eax,1 + shl eax,cl + dec eax + and eax,ebp + add eax,edx + mov edx, [esp+12] + mov eax, [edx+eax*4] + jmp L_dodist + +ALIGN 4 +L_clip_window: +; 721 "inffast.S" + mov ecx,eax + mov eax, [esp+52] + neg ecx + mov esi, [esp+56] + + cmp eax,edx + jb L_invalid_distance_too_far + + add ecx,edx + cmp dword ptr [esp+48],0 + jne L_wrap_around_window + + sub eax,ecx + add esi,eax +; 749 "inffast.S" + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + +L_wrap_around_window: +; 793 "inffast.S" + mov eax, [esp+48] + cmp ecx,eax + jbe L_contiguous_in_window + + add esi, [esp+52] + add esi,eax + sub esi,ecx + sub ecx,eax + + + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi, [esp+56] + mov ecx, [esp+48] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + +L_contiguous_in_window: +; 836 "inffast.S" + add esi,eax + sub esi,ecx + + + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + +L_do_copy1: +; 862 "inffast.S" + mov ecx,eax + rep movsb + + mov esi, [esp+44] + jmp L_while_test +; 878 "inffast.S" +ALIGN 4 +L_init_mmx: + emms + + + + + + movd mm0,ebp + mov ebp,ebx +; 896 "inffast.S" + movd mm4,dword ptr [esp+0] + movq mm3,mm4 + movd mm5,dword ptr [esp+4] + movq mm2,mm5 + pxor mm1,mm1 + mov ebx, [esp+8] + jmp L_do_loop_mmx + +ALIGN 4 +L_do_loop_mmx: + psrlq mm0,mm1 + + cmp ebp,32 + ja L_get_length_code_mmx + + movd mm6,ebp + movd mm7,dword ptr [esi] + add esi,4 + psllq mm7,mm6 + add ebp,32 + por mm0,mm7 + +L_get_length_code_mmx: + pand mm4,mm0 + movd eax,mm4 + movq mm4,mm3 + mov eax, [ebx+eax*4] + +L_dolen_mmx: + movzx ecx,ah + movd mm1,ecx + sub ebp,ecx + + test al,al + jnz L_test_for_length_base_mmx + + shr eax,16 + stosb + +L_while_test_mmx: + + + cmp [esp+16],edi + jbe L_break_loop + + cmp [esp+20],esi + ja L_do_loop_mmx + jmp L_break_loop + +L_test_for_length_base_mmx: + + mov edx,eax + shr edx,16 + + test al,16 + jz L_test_for_second_level_length_mmx + and eax,15 + jz L_decode_distance_mmx + + psrlq mm0,mm1 + movd mm1,eax + movd ecx,mm0 + sub ebp,eax + and ecx, [inflate_fast_mask+eax*4] + add edx,ecx + +L_decode_distance_mmx: + psrlq mm0,mm1 + + cmp ebp,32 + ja L_get_dist_code_mmx + + movd mm6,ebp + movd mm7,dword ptr [esi] + add esi,4 + psllq mm7,mm6 + add ebp,32 + por mm0,mm7 + +L_get_dist_code_mmx: + mov ebx, [esp+12] + pand mm5,mm0 + movd eax,mm5 + movq mm5,mm2 + mov eax, [ebx+eax*4] + +L_dodist_mmx: + + movzx ecx,ah + mov ebx,eax + shr ebx,16 + sub ebp,ecx + movd mm1,ecx + + test al,16 + jz L_test_for_second_level_dist_mmx + and eax,15 + jz L_check_dist_one_mmx + +L_add_bits_to_dist_mmx: + psrlq mm0,mm1 + movd mm1,eax + movd ecx,mm0 + sub ebp,eax + and ecx, [inflate_fast_mask+eax*4] + add ebx,ecx + +L_check_window_mmx: + mov [esp+44],esi + mov eax,edi + sub eax, [esp+40] + + cmp eax,ebx + jb L_clip_window_mmx + + mov ecx,edx + mov esi,edi + sub esi,ebx + + sub ecx,3 + mov al, [esi] + mov [edi],al + mov al, [esi+1] + mov dl, [esi+2] + add esi,3 + mov [edi+1],al + mov [edi+2],dl + add edi,3 + rep movsb + + mov esi, [esp+44] + mov ebx, [esp+8] + jmp L_while_test_mmx + +ALIGN 4 +L_check_dist_one_mmx: + cmp ebx,1 + jne L_check_window_mmx + cmp [esp+40],edi + je L_check_window_mmx + + dec edi + mov ecx,edx + mov al, [edi] + sub ecx,3 + + mov [edi+1],al + mov [edi+2],al + mov [edi+3],al + add edi,4 + rep stosb + + mov ebx, [esp+8] + jmp L_while_test_mmx + +ALIGN 4 +L_test_for_second_level_length_mmx: + test al,64 + jnz L_test_for_end_of_block + + and eax,15 + psrlq mm0,mm1 + movd ecx,mm0 + and ecx, [inflate_fast_mask+eax*4] + add ecx,edx + mov eax, [ebx+ecx*4] + jmp L_dolen_mmx + +ALIGN 4 +L_test_for_second_level_dist_mmx: + test al,64 + jnz L_invalid_distance_code + + and eax,15 + psrlq mm0,mm1 + movd ecx,mm0 + and ecx, [inflate_fast_mask+eax*4] + mov eax, [esp+12] + add ecx,ebx + mov eax, [eax+ecx*4] + jmp L_dodist_mmx + +ALIGN 4 +L_clip_window_mmx: + + mov ecx,eax + mov eax, [esp+52] + neg ecx + mov esi, [esp+56] + + cmp eax,ebx + jb L_invalid_distance_too_far + + add ecx,ebx + cmp dword ptr [esp+48],0 + jne L_wrap_around_window_mmx + + sub eax,ecx + add esi,eax + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + +L_wrap_around_window_mmx: + + mov eax, [esp+48] + cmp ecx,eax + jbe L_contiguous_in_window_mmx + + add esi, [esp+52] + add esi,eax + sub esi,ecx + sub ecx,eax + + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi, [esp+56] + mov ecx, [esp+48] + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + +L_contiguous_in_window_mmx: + + add esi,eax + sub esi,ecx + + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + +L_do_copy1_mmx: + + + mov ecx,edx + rep movsb + + mov esi, [esp+44] + mov ebx, [esp+8] + jmp L_while_test_mmx +; 1174 "inffast.S" +L_invalid_distance_code: + + + + + + mov ecx, invalid_distance_code_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_test_for_end_of_block: + + + + + + test al,32 + jz L_invalid_literal_length_code + + mov ecx,0 + mov edx,INFLATE_MODE_TYPE + jmp L_update_stream_state + +L_invalid_literal_length_code: + + + + + + mov ecx, invalid_literal_length_code_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_invalid_distance_too_far: + + + + mov esi, [esp+44] + mov ecx, invalid_distance_too_far_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_update_stream_state: + + mov eax, [esp+88] + test ecx,ecx + jz L_skip_msg + mov [eax+24],ecx +L_skip_msg: + mov eax, [eax+28] + mov [eax+mode_state],edx + jmp L_break_loop + +ALIGN 4 +L_break_loop: +; 1243 "inffast.S" + cmp dword ptr [inflate_fast_use_mmx],2 + jne L_update_next_in + + + + mov ebx,ebp + +L_update_next_in: +; 1266 "inffast.S" + mov eax, [esp+88] + mov ecx,ebx + mov edx, [eax+28] + shr ecx,3 + sub esi,ecx + shl ecx,3 + sub ebx,ecx + mov [eax+12],edi + mov [edx+bits_state],ebx + mov ecx,ebx + + lea ebx, [esp+28] + cmp [esp+20],ebx + jne L_buf_not_used + + sub esi,ebx + mov ebx, [eax+0] + mov [esp+20],ebx + add esi,ebx + mov ebx, [eax+4] + sub ebx,11 + add [esp+20],ebx + +L_buf_not_used: + mov [eax+0],esi + + mov ebx,1 + shl ebx,cl + dec ebx + + + + + + cmp dword ptr [inflate_fast_use_mmx],2 + jne L_update_hold + + + + psrlq mm0,mm1 + movd ebp,mm0 + + emms + +L_update_hold: + + + + and ebp,ebx + mov [edx+hold_state],ebp + + + + + mov ebx, [esp+20] + cmp ebx,esi + jbe L_last_is_smaller + + sub ebx,esi + add ebx,11 + mov [eax+4],ebx + jmp L_fixup_out +L_last_is_smaller: + sub esi,ebx + neg esi + add esi,11 + mov [eax+4],esi + + + + +L_fixup_out: + + mov ebx, [esp+16] + cmp ebx,edi + jbe L_end_is_smaller + + sub ebx,edi + add ebx,257 + mov [eax+16],ebx + jmp L_done +L_end_is_smaller: + sub edi,ebx + neg edi + add edi,257 + mov [eax+16],edi + + + + + +L_done: + add esp,64 + popfd + pop ebx + pop ebp + pop esi + pop edi + ret +_inflate_fast endp + +_TEXT ends +end diff --git a/src/external/zlib-1.2.11/contrib/masmx86/match686.asm b/src/external/zlib-1.2.11/contrib/masmx86/match686.asm new file mode 100644 index 000000000..69e0eed01 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx86/match686.asm @@ -0,0 +1,479 @@ +; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86 +; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; File written by Gilles Vollant, by converting match686.S from Brian Raiter +; for MASM. This is as assembly version of longest_match +; from Jean-loup Gailly in deflate.c +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; For Visual C++ 4.x and higher and ML 6.x and higher +; ml.exe is distributed in +; http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 +; +; this file contain two implementation of longest_match +; +; this longest_match was written by Brian raiter (1998), optimized for Pentium Pro +; (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom) +; +; for using an assembly version of longest_match, you need define ASMV in project +; +; compile the asm file running +; ml /coff /Zi /c /Flmatch686.lst match686.asm +; and do not include match686.obj in your project +; +; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for +; Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor +; with autoselect (with cpu detection code) +; if you want support the old pentium optimization, you can still use these version +; +; this file is not optimized for old pentium, but it compatible with all x86 32 bits +; processor (starting 80386) +; +; +; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2 + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ + + NbStack equ 76 + cur_match equ dword ptr[esp+NbStack-0] + str_s equ dword ptr[esp+NbStack-4] +; 5 dword on top (ret,ebp,esi,edi,ebx) + adrret equ dword ptr[esp+NbStack-8] + pushebp equ dword ptr[esp+NbStack-12] + pushedi equ dword ptr[esp+NbStack-16] + pushesi equ dword ptr[esp+NbStack-20] + pushebx equ dword ptr[esp+NbStack-24] + + chain_length equ dword ptr [esp+NbStack-28] + limit equ dword ptr [esp+NbStack-32] + best_len equ dword ptr [esp+NbStack-36] + window equ dword ptr [esp+NbStack-40] + prev equ dword ptr [esp+NbStack-44] + scan_start equ word ptr [esp+NbStack-48] + wmask equ dword ptr [esp+NbStack-52] + match_start_ptr equ dword ptr [esp+NbStack-56] + nice_match equ dword ptr [esp+NbStack-60] + scan equ dword ptr [esp+NbStack-64] + + windowlen equ dword ptr [esp+NbStack-68] + match_start equ dword ptr [esp+NbStack-72] + strend equ dword ptr [esp+NbStack-76] + NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + zlib1222add equ 8 + +; Note : these value are good with a 8 bytes boundary pack structure + dep_chain_length equ 74h+zlib1222add + dep_window equ 30h+zlib1222add + dep_strstart equ 64h+zlib1222add + dep_prev_length equ 70h+zlib1222add + dep_nice_match equ 88h+zlib1222add + dep_w_size equ 24h+zlib1222add + dep_prev equ 38h+zlib1222add + dep_w_mask equ 2ch+zlib1222add + dep_good_match equ 84h+zlib1222add + dep_match_start equ 68h+zlib1222add + dep_lookahead equ 6ch+zlib1222add + + +_TEXT segment + +IFDEF NOUNDERLINE + public longest_match + public match_init +ELSE + public _longest_match + public _match_init +ENDIF + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) +MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) + + +;;; stack frame offsets + +chainlenwmask equ esp + 0 ; high word: current chain len + ; low word: s->wmask +window equ esp + 4 ; local copy of s->window +windowbestlen equ esp + 8 ; s->window + bestlen +scanstart equ esp + 16 ; first two bytes of string +scanend equ esp + 12 ; last two bytes of string +scanalign equ esp + 20 ; dword-misalignment of string +nicematch equ esp + 24 ; a good enough match size +bestlen equ esp + 28 ; size of best match so far +scan equ esp + 32 ; ptr to string wanting match + +LocalVarsSize equ 36 +; saved ebx byte esp + 36 +; saved edi byte esp + 40 +; saved esi byte esp + 44 +; saved ebp byte esp + 48 +; return address byte esp + 52 +deflatestate equ esp + 56 ; the function arguments +curmatch equ esp + 60 + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +dsWSize equ 36+zlib1222add +dsWMask equ 44+zlib1222add +dsWindow equ 48+zlib1222add +dsPrev equ 56+zlib1222add +dsMatchLen equ 88+zlib1222add +dsPrevMatch equ 92+zlib1222add +dsStrStart equ 100+zlib1222add +dsMatchStart equ 104+zlib1222add +dsLookahead equ 108+zlib1222add +dsPrevLen equ 112+zlib1222add +dsMaxChainLen equ 116+zlib1222add +dsGoodMatch equ 132+zlib1222add +dsNiceMatch equ 136+zlib1222add + + +;;; match686.asm -- Pentium-Pro-optimized version of longest_match() +;;; Written for zlib 1.1.2 +;;; Copyright (C) 1998 Brian Raiter +;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html +;;; +;; +;; This software is provided 'as-is', without any express or implied +;; warranty. In no event will the authors be held liable for any damages +;; arising from the use of this software. +;; +;; Permission is granted to anyone to use this software for any purpose, +;; including commercial applications, and to alter it and redistribute it +;; freely, subject to the following restrictions: +;; +;; 1. The origin of this software must not be misrepresented; you must not +;; claim that you wrote the original software. If you use this software +;; in a product, an acknowledgment in the product documentation would be +;; appreciated but is not required. +;; 2. Altered source versions must be plainly marked as such, and must not be +;; misrepresented as being the original software +;; 3. This notice may not be removed or altered from any source distribution. +;; + +;GLOBAL _longest_match, _match_init + + +;SECTION .text + +;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) + +;_longest_match: + IFDEF NOUNDERLINE + longest_match proc near + ELSE + _longest_match proc near + ENDIF +.FPO (9, 4, 0, 0, 1, 0) + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + push ebp + push edi + push esi + push ebx + sub esp, LocalVarsSize + +;;; Retrieve the function arguments. ecx will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + + mov edx, [deflatestate] + mov ecx, [curmatch] + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov eax, [edx + dsPrevLen] + mov ebx, [edx + dsGoodMatch] + cmp eax, ebx + mov eax, [edx + dsWMask] + mov ebx, [edx + dsMaxChainLen] + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + mov [chainlenwmask], ebx + +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + mov eax, [edx + dsNiceMatch] + mov ebx, [edx + dsLookahead] + cmp ebx, eax + jl LookaheadLess + mov ebx, eax +LookaheadLess: mov [nicematch], ebx + +;;; register Bytef *scan = s->window + s->strstart; + + mov esi, [edx + dsWindow] + mov [window], esi + mov ebp, [edx + dsStrStart] + lea edi, [esi + ebp] + mov [scan], edi + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov eax, edi + neg eax + and eax, 3 + mov [scanalign], eax + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + mov eax, [edx + dsWSize] + sub eax, MIN_LOOKAHEAD + sub ebp, eax + jg LimitPositive + xor ebp, ebp +LimitPositive: + +;;; int best_len = s->prev_length; + + mov eax, [edx + dsPrevLen] + mov [bestlen], eax + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + add esi, eax + mov [windowbestlen], esi + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx ebx, word ptr [edi] + mov [scanstart], ebx + movzx ebx, word ptr [edi + eax - 1] + mov [scanend], ebx + mov edi, [edx + dsPrev] + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + jmp short LoopEntry + +align 4 + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; ecx = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and ecx, edx + movzx ecx, word ptr [edi + ecx*2] + cmp ecx, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow +LoopEntry: movzx eax, word ptr [esi + ecx - 1] + cmp eax, ebx + jnz LookupLoop + mov eax, [window] + movzx eax, word ptr [eax + ecx] + cmp eax, [scanstart] + jnz LookupLoop + +;;; Store the current value of chainlen. + + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + mov esi, [window] + mov edi, [scan] + add esi, ecx + mov eax, [scanalign] + mov edx, 0fffffef8h; -(MAX_MATCH_8) + lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] + lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust edx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (esi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + +LoopCmps: + mov eax, [esi + edx] + xor eax, [edi + edx] + jnz LeaveLoopCmps + mov eax, [esi + edx + 4] + xor eax, [edi + edx + 4] + jnz LeaveLoopCmps4 + add edx, 8 + jnz LoopCmps + jmp short LenMaximum +LeaveLoopCmps4: add edx, 4 +LeaveLoopCmps: test eax, 0000FFFFh + jnz LenLower + add edx, 2 + shr eax, 16 +LenLower: sub al, 1 + adc edx, 0 + +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea eax, [edi + edx] + mov edi, [scan] + sub eax, edi + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. + + mov edx, [deflatestate] + mov ebx, [bestlen] + cmp eax, ebx + jg LongerMatch + mov esi, [windowbestlen] + mov edi, [edx + dsPrev] + mov ebx, [scanend] + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: mov ebx, [nicematch] + mov [bestlen], eax + mov [edx + dsMatchStart], ecx + cmp eax, ebx + jge LeaveNow + mov esi, [window] + add esi, eax + mov [windowbestlen], esi + movzx ebx, word ptr [edi + eax - 1] + mov edi, [edx + dsPrev] + mov [scanend], ebx + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: mov edx, [deflatestate] + mov dword ptr [bestlen], MAX_MATCH + mov [edx + dsMatchStart], ecx + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: + mov edx, [deflatestate] + mov ebx, [bestlen] + mov eax, [edx + dsLookahead] + cmp ebx, eax + jg LookaheadRet + mov eax, ebx +LookaheadRet: + +;;; Restore the stack and return from whence we came. + + add esp, LocalVarsSize + pop ebx + pop esi + pop edi + pop ebp + + ret +; please don't remove this string ! +; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah + + + IFDEF NOUNDERLINE + longest_match endp + ELSE + _longest_match endp + ENDIF + + IFDEF NOUNDERLINE + match_init proc near + ret + match_init endp + ELSE + _match_init proc near + ret + _match_init endp + ENDIF + + +_TEXT ends +end diff --git a/src/external/zlib-1.2.11/contrib/masmx86/readme.txt b/src/external/zlib-1.2.11/contrib/masmx86/readme.txt new file mode 100644 index 000000000..3f8888679 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/masmx86/readme.txt @@ -0,0 +1,27 @@ + +Summary +------- +This directory contains ASM implementations of the functions +longest_match() and inflate_fast(). + + +Use instructions +---------------- +Assemble using MASM, and copy the object files into the zlib source +directory, then run the appropriate makefile, as suggested below. You can +donwload MASM from here: + + http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 + +You can also get objects files here: + + http://www.winimage.com/zLibDll/zlib124_masm_obj.zip + +Build instructions +------------------ +* With Microsoft C and MASM: +nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" + +* With Borland C and TASM: +make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" OBJPA="+match686c.obj+match686.obj+inffas32.obj" + diff --git a/src/external/zlib-1.2.11/contrib/minizip/Makefile b/src/external/zlib-1.2.11/contrib/minizip/Makefile new file mode 100644 index 000000000..84eaad20d --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/Makefile @@ -0,0 +1,25 @@ +CC=cc +CFLAGS=-O -I../.. + +UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a +ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a + +.c.o: + $(CC) -c $(CFLAGS) $*.c + +all: miniunz minizip + +miniunz: $(UNZ_OBJS) + $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) + +minizip: $(ZIP_OBJS) + $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) + +test: miniunz minizip + ./minizip test readme.txt + ./miniunz -l test.zip + mv readme.txt readme.old + ./miniunz test.zip + +clean: + /bin/rm -f *.o *~ minizip miniunz diff --git a/src/external/zlib-1.2.11/contrib/minizip/Makefile.am b/src/external/zlib-1.2.11/contrib/minizip/Makefile.am new file mode 100644 index 000000000..d343011eb --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/Makefile.am @@ -0,0 +1,45 @@ +lib_LTLIBRARIES = libminizip.la + +if COND_DEMOS +bin_PROGRAMS = miniunzip minizip +endif + +zlib_top_srcdir = $(top_srcdir)/../.. +zlib_top_builddir = $(top_builddir)/../.. + +AM_CPPFLAGS = -I$(zlib_top_srcdir) +AM_LDFLAGS = -L$(zlib_top_builddir) + +if WIN32 +iowin32_src = iowin32.c +iowin32_h = iowin32.h +endif + +libminizip_la_SOURCES = \ + ioapi.c \ + mztools.c \ + unzip.c \ + zip.c \ + ${iowin32_src} + +libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz + +minizip_includedir = $(includedir)/minizip +minizip_include_HEADERS = \ + crypt.h \ + ioapi.h \ + mztools.h \ + unzip.h \ + zip.h \ + ${iowin32_h} + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = minizip.pc + +EXTRA_PROGRAMS = miniunzip minizip + +miniunzip_SOURCES = miniunz.c +miniunzip_LDADD = libminizip.la + +minizip_SOURCES = minizip.c +minizip_LDADD = libminizip.la -lz diff --git a/src/external/zlib-1.2.11/contrib/minizip/MiniZip64_Changes.txt b/src/external/zlib-1.2.11/contrib/minizip/MiniZip64_Changes.txt new file mode 100644 index 000000000..13a1bd91a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/MiniZip64_Changes.txt @@ -0,0 +1,6 @@ + +MiniZip 1.1 was derrived from MiniZip at version 1.01f + +Change in 1.0 (Okt 2009) + - **TODO - Add history** + diff --git a/src/external/zlib-1.2.11/contrib/minizip/MiniZip64_info.txt b/src/external/zlib-1.2.11/contrib/minizip/MiniZip64_info.txt new file mode 100644 index 000000000..57d715242 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/MiniZip64_info.txt @@ -0,0 +1,74 @@ +MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson + +Introduction +--------------------- +MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html ) + +When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0. +All possible work was done for compatibility. + + +Background +--------------------- +When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 +support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ ) + +That was used as a starting point. And after that ZIP64 support was added to zip.c +some refactoring and code cleanup was also done. + + +Changed from MiniZip 1.0 to MiniZip 1.1 +--------------------------------------- +* Added ZIP64 support for unzip ( by Even Rouault ) +* Added ZIP64 support for zip ( by Mathias Svensson ) +* Reverted some changed that Even Rouault did. +* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users. +* Added unzip patch for BZIP Compression method (patch create by Daniel Borca) +* Added BZIP Compress method for zip +* Did some refactoring and code cleanup + + +Credits + + Gilles Vollant - Original MiniZip author + Even Rouault - ZIP64 unzip Support + Daniel Borca - BZip Compression method support in unzip + Mathias Svensson - ZIP64 zip support + Mathias Svensson - BZip Compression method support in zip + + Resources + + ZipLayout http://result42.com/projects/ZipFileLayout + Command line tool for Windows that shows the layout and information of the headers in a zip archive. + Used when debugging and validating the creation of zip files using MiniZip64 + + + ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT + Zip File specification + + +Notes. + * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined. + +License +---------------------------------------------------------- + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +---------------------------------------------------------- + diff --git a/src/external/zlib-1.2.11/contrib/minizip/configure.ac b/src/external/zlib-1.2.11/contrib/minizip/configure.ac new file mode 100644 index 000000000..5b1197097 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/configure.ac @@ -0,0 +1,32 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_INIT([minizip], [1.2.11], [bugzilla.redhat.com]) +AC_CONFIG_SRCDIR([minizip.c]) +AM_INIT_AUTOMAKE([foreign]) +LT_INIT + +AC_MSG_CHECKING([whether to build example programs]) +AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs])) +AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes]) +if test "$enable_demos" = yes +then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +case "${host}" in + *-mingw* | mingw*) + WIN32="yes" + ;; + *) + ;; +esac +AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) + + +AC_SUBST([HAVE_UNISTD_H], [0]) +AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], []) +AC_CONFIG_FILES([Makefile minizip.pc]) +AC_OUTPUT diff --git a/src/external/zlib-1.2.11/contrib/minizip/crypt.h b/src/external/zlib-1.2.11/contrib/minizip/crypt.h new file mode 100644 index 000000000..1e9e8200b --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const z_crc_t* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/src/external/zlib-1.2.11/contrib/minizip/ioapi.c b/src/external/zlib-1.2.11/contrib/minizip/ioapi.c new file mode 100644 index 000000000..7f5c191b2 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/ioapi.c @@ -0,0 +1,247 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(IOAPI_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/src/external/zlib-1.2.11/contrib/minizip/ioapi.h b/src/external/zlib-1.2.11/contrib/minizip/ioapi.h new file mode 100644 index 000000000..8dcbdb06e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/ioapi.h @@ -0,0 +1,208 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#define MAXU32 0xffffffff + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/external/zlib-1.2.11/contrib/minizip/iowin32.c b/src/external/zlib-1.2.11/contrib/minizip/iowin32.c new file mode 100644 index 000000000..274f39eb1 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/iowin32.c @@ -0,0 +1,462 @@ +/* iowin32.c -- IO base function header for compress/uncompress .zip + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#include + +#include "zlib.h" +#include "ioapi.h" +#include "iowin32.h" + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE (0xFFFFFFFF) +#endif + +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + + +// see Include/shared/winapifamily.h in the Windows Kit +#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API))) +#if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP) +#define IOWIN32_USING_WINRT_API 1 +#endif +#endif + +voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode)); +uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream)); +long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream)); +int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream)); + +typedef struct +{ + HANDLE hf; + int error; +} WIN32FILE_IOWIN; + + +static void win32_translate_open_mode(int mode, + DWORD* lpdwDesiredAccess, + DWORD* lpdwCreationDisposition, + DWORD* lpdwShareMode, + DWORD* lpdwFlagsAndAttributes) +{ + *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0; + + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + { + *lpdwDesiredAccess = GENERIC_READ; + *lpdwCreationDisposition = OPEN_EXISTING; + *lpdwShareMode = FILE_SHARE_READ; + } + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + { + *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + *lpdwCreationDisposition = OPEN_EXISTING; + } + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + { + *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + *lpdwCreationDisposition = CREATE_ALWAYS; + } +} + +static voidpf win32_build_iowin(HANDLE hFile) +{ + voidpf ret=NULL; + + if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) + { + WIN32FILE_IOWIN w32fiow; + w32fiow.hf = hFile; + w32fiow.error = 0; + ret = malloc(sizeof(WIN32FILE_IOWIN)); + + if (ret==NULL) + CloseHandle(hFile); + else + *((WIN32FILE_IOWIN*)ret) = w32fiow; + } + return ret; +} + +voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API +#ifdef UNICODE + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + { + WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; + MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); + hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); + } +#endif +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API + if ((filename!=NULL) && (dwDesiredAccess != 0)) + { + WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; + MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); + hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); + } +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL); +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API +#ifdef UNICODE + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + { + WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; + MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); + hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); + } +#endif +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size) +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile != NULL) + { + if (!ReadFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + } + + return ret; +} + + +uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size) +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile != NULL) + { + if (!WriteFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + } + + return ret; +} + +static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod) +{ +#ifdef IOWIN32_USING_WINRT_API + return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod); +#else + LONG lHigh = pos.HighPart; + DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod); + BOOL fOk = TRUE; + if (dwNewPos == 0xFFFFFFFF) + if (GetLastError() != NO_ERROR) + fOk = FALSE; + if ((newPos != NULL) && (fOk)) + { + newPos->LowPart = dwNewPos; + newPos->HighPart = lHigh; + } + return fOk; +#endif +} + +long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream) +{ + long ret=-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + LARGE_INTEGER pos; + pos.QuadPart = 0; + + if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=(long)pos.LowPart; + } + return ret; +} + +ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret= (ZPOS64_T)-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream)->hf; + + if (hFile) + { + LARGE_INTEGER pos; + pos.QuadPart = 0; + + if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = (ZPOS64_T)-1; + } + else + ret=pos.QuadPart; + } + return ret; +} + + +long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin) +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + + long ret=-1; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile != NULL) + { + LARGE_INTEGER pos; + pos.QuadPart = offset; + if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin) +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + long ret=-1; + + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream)->hf; + + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile) + { + LARGE_INTEGER pos; + pos.QuadPart = offset; + if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream) +{ + int ret=-1; + + if (stream!=NULL) + { + HANDLE hFile; + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + CloseHandle(hFile); + ret=0; + } + free(stream); + } + return ret; +} + +int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream) +{ + int ret=-1; + if (stream!=NULL) + { + ret = ((WIN32FILE_IOWIN*)stream) -> error; + } + return ret; +} + +void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = win32_open_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell_file = win32_tell_file_func; + pzlib_filefunc_def->zseek_file = win32_seek_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + + +void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + + +void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/src/external/zlib-1.2.11/contrib/minizip/iowin32.h b/src/external/zlib-1.2.11/contrib/minizip/iowin32.h new file mode 100644 index 000000000..0ca0969a7 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/iowin32.h @@ -0,0 +1,28 @@ +/* iowin32.h -- IO base function header for compress/uncompress .zip + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); +void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def)); + +#ifdef __cplusplus +} +#endif diff --git a/src/external/zlib-1.2.11/contrib/minizip/make_vms.com b/src/external/zlib-1.2.11/contrib/minizip/make_vms.com new file mode 100644 index 000000000..9ac13a98f --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/make_vms.com @@ -0,0 +1,25 @@ +$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig +$ open/write zdef vmsdefs.h +$ copy sys$input: zdef +$ deck +#define unix +#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from +#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator +#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord +#define Write_EndOfCentralDirectoryRecord Write_EoDRecord +$ eod +$ close zdef +$ copy vmsdefs.h,ioapi.h_orig ioapi.h +$ cc/include=[--]/prefix=all ioapi.c +$ cc/include=[--]/prefix=all miniunz.c +$ cc/include=[--]/prefix=all unzip.c +$ cc/include=[--]/prefix=all minizip.c +$ cc/include=[--]/prefix=all zip.c +$ link miniunz,unzip,ioapi,[--]libz.olb/lib +$ link minizip,zip,ioapi,[--]libz.olb/lib +$ mcr []minizip test minizip_info.txt +$ mcr []miniunz -l test.zip +$ rename minizip_info.txt; minizip_info.txt_old +$ mcr []miniunz test.zip +$ delete test.zip;* +$exit diff --git a/src/external/zlib-1.2.11/contrib/minizip/miniunz.c b/src/external/zlib-1.2.11/contrib/minizip/miniunz.c new file mode 100644 index 000000000..3d65401be --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/miniunz.c @@ -0,0 +1,660 @@ +/* + miniunz.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +*/ + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#ifdef __APPLE__ +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +#endif + + +#include "unzip.h" + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) +#define MAXFILENAME (256) + +#ifdef _WIN32 +#define USEWIN32IOAPI +#include "iowin32.h" +#endif +/* + mini unzip, demo of unzip package + + usage : + Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] + + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT + if it exists +*/ + + +/* change_file_date : change the date/time of a file + filename : the filename of the file where date/time must be modified + dosdate : the new date at the MSDos format (4 bytes) + tmu_date : the SAME new date at the tm_unz format */ +void change_file_date(filename,dosdate,tmu_date) + const char *filename; + uLong dosdate; + tm_unz tmu_date; +{ +#ifdef _WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + + hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING,0,NULL); + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); + CloseHandle(hFile); +#else +#ifdef unix || __APPLE__ + struct utimbuf ut; + struct tm newdate; + newdate.tm_sec = tmu_date.tm_sec; + newdate.tm_min=tmu_date.tm_min; + newdate.tm_hour=tmu_date.tm_hour; + newdate.tm_mday=tmu_date.tm_mday; + newdate.tm_mon=tmu_date.tm_mon; + if (tmu_date.tm_year > 1900) + newdate.tm_year=tmu_date.tm_year - 1900; + else + newdate.tm_year=tmu_date.tm_year ; + newdate.tm_isdst=-1; + + ut.actime=ut.modtime=mktime(&newdate); + utime(filename,&ut); +#endif +#endif +} + + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#ifdef _WIN32 + ret = _mkdir(dirname); +#elif unix + ret = mkdir (dirname,0775); +#elif __APPLE__ + ret = mkdir (dirname,0775); +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = (int)strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + if (buffer==NULL) + { + printf("Error allocating memory\n"); + return UNZ_INTERNALERROR; + } + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +void do_banner() +{ + printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); +} + +void do_help() +{ + printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ + " -e Extract without pathname (junk paths)\n" \ + " -x Extract with pathname\n" \ + " -v list files\n" \ + " -l list files\n" \ + " -d directory to extract into\n" \ + " -o overwrite files without prompting\n" \ + " -p extract crypted file using password\n\n"); +} + +void Display64BitsSize(ZPOS64_T n, int size_char) +{ + /* to avoid compatibility problem , we do here the conversion */ + char number[21]; + int offset=19; + int pos_string = 19; + number[20]=0; + for (;;) { + number[offset]=(char)((n%10)+'0'); + if (number[offset] != '0') + pos_string=offset; + n/=10; + if (offset==0) + break; + offset--; + } + { + int size_display_string = 19-pos_string; + while (size_char > size_display_string) + { + size_char--; + printf(" "); + } + } + + printf("%s",&number[pos_string]); +} + +int do_list(uf) + unzFile uf; +{ + uLong i; + unz_global_info64 gi; + int err; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); + printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); + for (i=0;i0) + ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size); + + /* display a '*' if the file is crypted */ + if ((file_info.flag & 1) != 0) + charCrypt='*'; + + if (file_info.compression_method==0) + string_method="Stored"; + else + if (file_info.compression_method==Z_DEFLATED) + { + uInt iLevel=(uInt)((file_info.flag & 0x6)/2); + if (iLevel==0) + string_method="Defl:N"; + else if (iLevel==1) + string_method="Defl:X"; + else if ((iLevel==2) || (iLevel==3)) + string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ + } + else + if (file_info.compression_method==Z_BZIP2ED) + { + string_method="BZip2 "; + } + else + string_method="Unkn. "; + + Display64BitsSize(file_info.uncompressed_size,7); + printf(" %6s%c",string_method,charCrypt); + Display64BitsSize(file_info.compressed_size,7); + printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", + ratio, + (uLong)file_info.tmu_date.tm_mon + 1, + (uLong)file_info.tmu_date.tm_mday, + (uLong)file_info.tmu_date.tm_year % 100, + (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, + (uLong)file_info.crc,filename_inzip); + if ((i+1)='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + } + + if (rep == 'N') + skip = 1; + + if (rep == 'A') + *popt_overwrite=1; + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=FOPEN_FUNC(write_filename,"wb"); + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && ((*popt_extract_without_path)==0) && + (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + makedir(write_filename); + *(filename_withoutpath-1)=c; + fout=FOPEN_FUNC(write_filename,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + printf(" extracting: %s\n",write_filename); + + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + if (fout) + fclose(fout); + + if (err==0) + change_file_date(write_filename,file_info.dosDate, + file_info.tmu_date); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int do_extract(uf,opt_extract_without_path,opt_overwrite,password) + unzFile uf; + int opt_extract_without_path; + int opt_overwrite; + const char* password; +{ + uLong i; + unz_global_info64 gi; + int err; + FILE* fout=NULL; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + + for (i=0;i insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +miniunzip - uncompress and examine ZIP archives +.SH SYNOPSIS +.B miniunzip +.RI [ -exvlo ] +zipfile [ files_to_extract ] [-d tempdir] +.SH DESCRIPTION +.B minizip +is a simple tool which allows the extraction of compressed file +archives in the ZIP format used by the MS-DOS utility PKZIP. It was +written as a demonstration of the +.IR zlib (3) +library and therefore lack many of the features of the +.IR unzip (1) +program. +.SH OPTIONS +A number of options are supported. With the exception of +.BI \-d\ tempdir +these must be supplied before any +other arguments and are: +.TP +.BI \-l\ ,\ \-\-v +List the files in the archive without extracting them. +.TP +.B \-o +Overwrite files without prompting for confirmation. +.TP +.B \-x +Extract files (default). +.PP +The +.I zipfile +argument is the name of the archive to process. The next argument can be used +to specify a single file to extract from the archive. + +Lastly, the following option can be specified at the end of the command-line: +.TP +.BI \-d\ tempdir +Extract the archive in the directory +.I tempdir +rather than the current directory. +.SH SEE ALSO +.BR minizip (1), +.BR zlib (3), +.BR unzip (1). +.SH AUTHOR +This program was written by Gilles Vollant. This manual page was +written by Mark Brown . The -d tempdir option +was added by Dirk Eddelbuettel . diff --git a/src/external/zlib-1.2.11/contrib/minizip/minizip.1 b/src/external/zlib-1.2.11/contrib/minizip/minizip.1 new file mode 100644 index 000000000..1154484c1 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/minizip.1 @@ -0,0 +1,46 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH minizip 1 "May 2, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +minizip - create ZIP archives +.SH SYNOPSIS +.B minizip +.RI [ -o ] +zipfile [ " files" ... ] +.SH DESCRIPTION +.B minizip +is a simple tool which allows the creation of compressed file archives +in the ZIP format used by the MS-DOS utility PKZIP. It was written as +a demonstration of the +.IR zlib (3) +library and therefore lack many of the features of the +.IR zip (1) +program. +.SH OPTIONS +The first argument supplied is the name of the ZIP archive to create or +.RI -o +in which case it is ignored and the second argument treated as the +name of the ZIP file. If the ZIP file already exists it will be +overwritten. +.PP +Subsequent arguments specify a list of files to place in the ZIP +archive. If none are specified then an empty archive will be created. +.SH SEE ALSO +.BR miniunzip (1), +.BR zlib (3), +.BR zip (1). +.SH AUTHOR +This program was written by Gilles Vollant. This manual page was +written by Mark Brown . + diff --git a/src/external/zlib-1.2.11/contrib/minizip/minizip.c b/src/external/zlib-1.2.11/contrib/minizip/minizip.c new file mode 100644 index 000000000..4288962ec --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/minizip.c @@ -0,0 +1,520 @@ +/* + minizip.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +*/ + + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#ifdef __APPLE__ +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +# include +# include +#endif + +#include "zip.h" + +#ifdef _WIN32 + #define USEWIN32IOAPI + #include "iowin32.h" +#endif + + + +#define WRITEBUFFERSIZE (16384) +#define MAXFILENAME (256) + +#ifdef _WIN32 +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret = 0; + { + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATAA ff32; + + hFind = FindFirstFileA(f,&ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + ret = 1; + } + } + return ret; +} +#else +#ifdef unix || __APPLE__ +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret=0; + struct stat s; /* results of stat() */ + struct tm* filedate; + time_t tm_t=0; + + if (strcmp(f,"-")!=0) + { + char name[MAXFILENAME+1]; + int len = strlen(f); + if (len > MAXFILENAME) + len = MAXFILENAME; + + strncpy(name, f,MAXFILENAME-1); + /* strncpy doesnt append the trailing NULL, of the string is too long. */ + name[ MAXFILENAME ] = '\0'; + + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (stat(name,&s)==0) + { + tm_t = s.st_mtime; + ret = 1; + } + } + filedate = localtime(&tm_t); + + tmzip->tm_sec = filedate->tm_sec; + tmzip->tm_min = filedate->tm_min; + tmzip->tm_hour = filedate->tm_hour; + tmzip->tm_mday = filedate->tm_mday; + tmzip->tm_mon = filedate->tm_mon ; + tmzip->tm_year = filedate->tm_year; + + return ret; +} +#else +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + return 0; +} +#endif +#endif + + + + +int check_exist_file(filename) + const char* filename; +{ + FILE* ftestexist; + int ret = 1; + ftestexist = FOPEN_FUNC(filename,"rb"); + if (ftestexist==NULL) + ret = 0; + else + fclose(ftestexist); + return ret; +} + +void do_banner() +{ + printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n"); + printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n"); +} + +void do_help() +{ + printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ + " -o Overwrite existing file.zip\n" \ + " -a Append to existing file.zip\n" \ + " -0 Store only\n" \ + " -1 Compress faster\n" \ + " -9 Compress better\n\n" \ + " -j exclude path. store only the file name.\n\n"); +} + +/* calculate the CRC32 of a file, + because to encrypt a file, we need known the CRC32 of the file before */ +int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) +{ + unsigned long calculate_crc=0; + int err=ZIP_OK; + FILE * fin = FOPEN_FUNC(filenameinzip,"rb"); + + unsigned long size_read = 0; + unsigned long total_read = 0; + if (fin==NULL) + { + err = ZIP_ERRNO; + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + calculate_crc = crc32(calculate_crc,buf,size_read); + total_read += size_read; + + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + *result_crc=calculate_crc; + printf("file %s crc %lx\n", filenameinzip, calculate_crc); + return err; +} + +int isLargeFile(const char* filename) +{ + int largeFile = 0; + ZPOS64_T pos = 0; + FILE* pFile = FOPEN_FUNC(filename, "rb"); + + if(pFile != NULL) + { + int n = FSEEKO_FUNC(pFile, 0, SEEK_END); + pos = FTELLO_FUNC(pFile); + + printf("File : %s is %lld bytes\n", filename, pos); + + if(pos >= 0xffffffff) + largeFile = 1; + + fclose(pFile); + } + + return largeFile; +} + +int main(argc,argv) + int argc; + char *argv[]; +{ + int i; + int opt_overwrite=0; + int opt_compress_level=Z_DEFAULT_COMPRESSION; + int opt_exclude_path=0; + int zipfilenamearg = 0; + char filename_try[MAXFILENAME+16]; + int zipok; + int err=0; + int size_buf=0; + void* buf=NULL; + const char* password=NULL; + + + do_banner(); + if (argc==1) + { + do_help(); + return 0; + } + else + { + for (i=1;i='0') && (c<='9')) + opt_compress_level = c-'0'; + if ((c=='j') || (c=='J')) + opt_exclude_path = 1; + + if (((c=='p') || (c=='P')) && (i+1='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + if (rep=='N') + zipok = 0; + if (rep=='A') + opt_overwrite = 2; + } + } + + if (zipok==1) + { + zipFile zf; + int errclose; +# ifdef USEWIN32IOAPI + zlib_filefunc64_def ffunc; + fill_win32_filefunc64A(&ffunc); + zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); +# else + zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0); +# endif + + if (zf == NULL) + { + printf("error opening %s\n",filename_try); + err= ZIP_ERRNO; + } + else + printf("creating %s\n",filename_try); + + for (i=zipfilenamearg+1;(i='0') || (argv[i][1]<='9'))) && + (strlen(argv[i]) == 2))) + { + FILE * fin; + int size_read; + const char* filenameinzip = argv[i]; + const char *savefilenameinzip; + zip_fileinfo zi; + unsigned long crcFile=0; + int zip64 = 0; + + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; + zi.dosDate = 0; + zi.internal_fa = 0; + zi.external_fa = 0; + filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); + +/* + err = zipOpenNewFileInZip(zf,filenameinzip,&zi, + NULL,0,NULL,0,NULL / * comment * /, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level); +*/ + if ((password != NULL) && (err==ZIP_OK)) + err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); + + zip64 = isLargeFile(filenameinzip); + + /* The path name saved, should not include a leading slash. */ + /*if it did, windows/xp and dynazip couldn't read the zip file. */ + savefilenameinzip = filenameinzip; + while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) + { + savefilenameinzip++; + } + + /*should the zip file contain any path at all?*/ + if( opt_exclude_path ) + { + const char *tmpptr; + const char *lastslash = 0; + for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) + { + if( *tmpptr == '\\' || *tmpptr == '/') + { + lastslash = tmpptr; + } + } + if( lastslash != NULL ) + { + savefilenameinzip = lastslash+1; // base filename follows last slash. + } + } + + /**/ + err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, + NULL,0,NULL,0,NULL /* comment*/, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level,0, + /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + password,crcFile, zip64); + + if (err != ZIP_OK) + printf("error in opening %s in zipfile\n",filenameinzip); + else + { + fin = FOPEN_FUNC(filenameinzip,"rb"); + if (fin==NULL) + { + err=ZIP_ERRNO; + printf("error in opening %s for reading\n",filenameinzip); + } + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + { + err = zipWriteInFileInZip (zf,buf,size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } + } + } + errclose = zipClose(zf,NULL); + if (errclose != ZIP_OK) + printf("error in closing %s\n",filename_try); + } + else + { + do_help(); + } + + free(buf); + return 0; +} diff --git a/src/external/zlib-1.2.11/contrib/minizip/minizip.pc.in b/src/external/zlib-1.2.11/contrib/minizip/minizip.pc.in new file mode 100644 index 000000000..69b5b7fdc --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/minizip.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/minizip + +Name: minizip +Description: Minizip zip file manipulation library +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lminizip +Libs.private: -lz +Cflags: -I${includedir} diff --git a/src/external/zlib-1.2.11/contrib/minizip/mztools.c b/src/external/zlib-1.2.11/contrib/minizip/mztools.c new file mode 100644 index 000000000..96891c2e0 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/mztools.c @@ -0,0 +1,291 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[1024]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fnsize < sizeof(filename)) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (extsize < sizeof(extra)) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/src/external/zlib-1.2.11/contrib/minizip/mztools.h b/src/external/zlib-1.2.11/contrib/minizip/mztools.h new file mode 100644 index 000000000..a49a426ec --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/mztools.h @@ -0,0 +1,37 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +#ifndef _zip_tools_H +#define _zip_tools_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#include "unzip.h" + +/* Repair a ZIP file (missing central directory) + file: file to recover + fileOut: output file after recovery + fileOutTmp: temporary file name used for recovery +*/ +extern int ZEXPORT unzRepair(const char* file, + const char* fileOut, + const char* fileOutTmp, + uLong* nRecovered, + uLong* bytesRecovered); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/src/external/zlib-1.2.11/contrib/minizip/unzip.c b/src/external/zlib-1.2.11/contrib/minizip/unzip.c new file mode 100644 index 000000000..bcfb9416e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been successfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == MAXU32) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/src/external/zlib-1.2.11/contrib/minizip/unzip.h b/src/external/zlib-1.2.11/contrib/minizip/unzip.h new file mode 100644 index 000000000..2104e3915 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzCloseCurrentFile before call unzClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/src/external/zlib-1.2.11/contrib/minizip/zip.c b/src/external/zlib-1.2.11/contrib/minizip/zip.c new file mode 100644 index 000000000..44e88a9cb --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/zip.c @@ -0,0 +1,2007 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignment */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writing_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writing_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writing_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + (crcForCrypting); + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if (level==2) + zi->ci.flag |= 4; + if (level==1) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + else + err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; + if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/src/external/zlib-1.2.11/contrib/minizip/zip.h b/src/external/zlib-1.2.11/contrib/minizip/zip.h new file mode 100644 index 000000000..8aaebb623 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/minizip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/src/external/zlib-1.2.11/contrib/pascal/example.pas b/src/external/zlib-1.2.11/contrib/pascal/example.pas new file mode 100644 index 000000000..5518b36a7 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/pascal/example.pas @@ -0,0 +1,599 @@ +(* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Pascal translation + * Copyright (C) 1998 by Jacques Nomssi Nzali. + * For conditions of distribution and use, see copyright notice in readme.txt + * + * Adaptation to the zlibpas interface + * Copyright (C) 2003 by Cosmin Truta. + * For conditions of distribution and use, see copyright notice in readme.txt + *) + +program example; + +{$DEFINE TEST_COMPRESS} +{DO NOT $DEFINE TEST_GZIO} +{$DEFINE TEST_DEFLATE} +{$DEFINE TEST_INFLATE} +{$DEFINE TEST_FLUSH} +{$DEFINE TEST_SYNC} +{$DEFINE TEST_DICT} + +uses SysUtils, zlibpas; + +const TESTFILE = 'foo.gz'; + +(* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + *) +const hello: PChar = 'hello, hello!'; + +const dictionary: PChar = 'hello'; + +var dictId: LongInt; (* Adler32 value of the dictionary *) + +procedure CHECK_ERR(err: Integer; msg: String); +begin + if err <> Z_OK then + begin + WriteLn(msg, ' error: ', err); + Halt(1); + end; +end; + +procedure EXIT_ERR(const msg: String); +begin + WriteLn('Error: ', msg); + Halt(1); +end; + +(* =========================================================================== + * Test compress and uncompress + *) +{$IFDEF TEST_COMPRESS} +procedure test_compress(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + len: LongInt; +begin + len := StrLen(hello)+1; + + err := compress(compr, comprLen, hello, len); + CHECK_ERR(err, 'compress'); + + StrCopy(PChar(uncompr), 'garbage'); + + err := uncompress(uncompr, uncomprLen, compr, comprLen); + CHECK_ERR(err, 'uncompress'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad uncompress') + else + WriteLn('uncompress(): ', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test read/write of .gz files + *) +{$IFDEF TEST_GZIO} +procedure test_gzio(const fname: PChar; (* compressed file name *) + uncompr: Pointer; + uncomprLen: LongInt); +var err: Integer; + len: Integer; + zfile: gzFile; + pos: LongInt; +begin + len := StrLen(hello)+1; + + zfile := gzopen(fname, 'wb'); + if zfile = NIL then + begin + WriteLn('gzopen error'); + Halt(1); + end; + gzputc(zfile, 'h'); + if gzputs(zfile, 'ello') <> 4 then + begin + WriteLn('gzputs err: ', gzerror(zfile, err)); + Halt(1); + end; + {$IFDEF GZ_FORMAT_STRING} + if gzprintf(zfile, ', %s!', 'hello') <> 8 then + begin + WriteLn('gzprintf err: ', gzerror(zfile, err)); + Halt(1); + end; + {$ELSE} + if gzputs(zfile, ', hello!') <> 8 then + begin + WriteLn('gzputs err: ', gzerror(zfile, err)); + Halt(1); + end; + {$ENDIF} + gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *) + gzclose(zfile); + + zfile := gzopen(fname, 'rb'); + if zfile = NIL then + begin + WriteLn('gzopen error'); + Halt(1); + end; + + StrCopy(PChar(uncompr), 'garbage'); + + if gzread(zfile, uncompr, uncomprLen) <> len then + begin + WriteLn('gzread err: ', gzerror(zfile, err)); + Halt(1); + end; + if StrComp(PChar(uncompr), hello) <> 0 then + begin + WriteLn('bad gzread: ', PChar(uncompr)); + Halt(1); + end + else + WriteLn('gzread(): ', PChar(uncompr)); + + pos := gzseek(zfile, -8, SEEK_CUR); + if (pos <> 6) or (gztell(zfile) <> pos) then + begin + WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile)); + Halt(1); + end; + + if gzgetc(zfile) <> ' ' then + begin + WriteLn('gzgetc error'); + Halt(1); + end; + + if gzungetc(' ', zfile) <> ' ' then + begin + WriteLn('gzungetc error'); + Halt(1); + end; + + gzgets(zfile, PChar(uncompr), uncomprLen); + uncomprLen := StrLen(PChar(uncompr)); + if uncomprLen <> 7 then (* " hello!" *) + begin + WriteLn('gzgets err after gzseek: ', gzerror(zfile, err)); + Halt(1); + end; + if StrComp(PChar(uncompr), hello + 6) <> 0 then + begin + WriteLn('bad gzgets after gzseek'); + Halt(1); + end + else + WriteLn('gzgets() after gzseek: ', PChar(uncompr)); + + gzclose(zfile); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with small buffers + *) +{$IFDEF TEST_DEFLATE} +procedure test_deflate(compr: Pointer; comprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; + len: LongInt; +begin + len := StrLen(hello)+1; + + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_in := hello; + c_stream.next_out := compr; + + while (c_stream.total_in <> len) and + (c_stream.total_out < comprLen) do + begin + c_stream.avail_out := 1; { force small buffers } + c_stream.avail_in := 1; + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + end; + + (* Finish the stream, still forcing small buffers: *) + while TRUE do + begin + c_stream.avail_out := 1; + err := deflate(c_stream, Z_FINISH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'deflate'); + end; + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with small buffers + *) +{$IFDEF TEST_INFLATE} +procedure test_inflate(compr: Pointer; comprLen : LongInt; + uncompr: Pointer; uncomprLen : LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := 0; + d_stream.next_out := uncompr; + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + while (d_stream.total_out < uncomprLen) and + (d_stream.total_in < comprLen) do + begin + d_stream.avail_out := 1; (* force small buffers *) + d_stream.avail_in := 1; + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'inflate'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad inflate') + else + WriteLn('inflate(): ', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with large buffers and dynamic change of compression level + *) +{$IFDEF TEST_DEFLATE} +procedure test_large_deflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; +begin + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_BEST_SPEED); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_out := compr; + c_stream.avail_out := Integer(comprLen); + + (* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + *) + c_stream.next_in := uncompr; + c_stream.avail_in := Integer(uncomprLen); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + if c_stream.avail_in <> 0 then + EXIT_ERR('deflate not greedy'); + + (* Feed in already compressed data and switch to no compression: *) + deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in := compr; + c_stream.avail_in := Integer(comprLen div 2); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + + (* Switch back to compressing mode: *) + deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in := uncompr; + c_stream.avail_in := Integer(uncomprLen); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + EXIT_ERR('deflate should report Z_STREAM_END'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with large buffers + *) +{$IFDEF TEST_INFLATE} +procedure test_large_inflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := Integer(comprLen); + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + while TRUE do + begin + d_stream.next_out := uncompr; (* discard the output *) + d_stream.avail_out := Integer(uncomprLen); + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'large inflate'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then + begin + WriteLn('bad large inflate: ', d_stream.total_out); + Halt(1); + end + else + WriteLn('large_inflate(): OK'); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with full flush + *) +{$IFDEF TEST_FLUSH} +procedure test_flush(compr: Pointer; var comprLen : LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; + len: Integer; +begin + len := StrLen(hello)+1; + + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_in := hello; + c_stream.next_out := compr; + c_stream.avail_in := 3; + c_stream.avail_out := Integer(comprLen); + err := deflate(c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, 'deflate'); + + Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *) + c_stream.avail_in := len - 3; + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + CHECK_ERR(err, 'deflate'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); + + comprLen := c_stream.total_out; +end; +{$ENDIF} + +(* =========================================================================== + * Test inflateSync() + *) +{$IFDEF TEST_SYNC} +procedure test_sync(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen : LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := 2; (* just read the zlib header *) + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + d_stream.next_out := uncompr; + d_stream.avail_out := Integer(uncomprLen); + + inflate(d_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'inflate'); + + d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *) + err := inflateSync(d_stream); (* but skip the damaged part *) + CHECK_ERR(err, 'inflateSync'); + + err := inflate(d_stream, Z_FINISH); + if err <> Z_DATA_ERROR then + EXIT_ERR('inflate should report DATA_ERROR'); + (* Because of incorrect adler32 *) + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + WriteLn('after inflateSync(): hel', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with preset dictionary + *) +{$IFDEF TEST_DICT} +procedure test_dict_deflate(compr: Pointer; comprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; +begin + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary)); + CHECK_ERR(err, 'deflateSetDictionary'); + + dictId := c_stream.adler; + c_stream.next_out := compr; + c_stream.avail_out := Integer(comprLen); + + c_stream.next_in := hello; + c_stream.avail_in := StrLen(hello)+1; + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + EXIT_ERR('deflate should report Z_STREAM_END'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with a preset dictionary + *) +{$IFDEF TEST_DICT} +procedure test_dict_inflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := Integer(comprLen); + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + d_stream.next_out := uncompr; + d_stream.avail_out := Integer(uncomprLen); + + while TRUE do + begin + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + if err = Z_NEED_DICT then + begin + if d_stream.adler <> dictId then + EXIT_ERR('unexpected dictionary'); + err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary)); + end; + CHECK_ERR(err, 'inflate with dict'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad inflate with dict') + else + WriteLn('inflate with dictionary: ', PChar(uncompr)); +end; +{$ENDIF} + +var compr, uncompr: Pointer; + comprLen, uncomprLen: LongInt; + +begin + if zlibVersion^ <> ZLIB_VERSION[1] then + EXIT_ERR('Incompatible zlib version'); + + WriteLn('zlib version: ', zlibVersion); + WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags])); + + comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *) + uncomprLen := comprLen; + GetMem(compr, comprLen); + GetMem(uncompr, uncomprLen); + if (compr = NIL) or (uncompr = NIL) then + EXIT_ERR('Out of memory'); + (* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + *) + FillChar(compr^, comprLen, 0); + FillChar(uncompr^, uncomprLen, 0); + + {$IFDEF TEST_COMPRESS} + WriteLn('** Testing compress'); + test_compress(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_GZIO} + WriteLn('** Testing gzio'); + if ParamCount >= 1 then + test_gzio(ParamStr(1), uncompr, uncomprLen) + else + test_gzio(TESTFILE, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_DEFLATE} + WriteLn('** Testing deflate with small buffers'); + test_deflate(compr, comprLen); + {$ENDIF} + {$IFDEF TEST_INFLATE} + WriteLn('** Testing inflate with small buffers'); + test_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_DEFLATE} + WriteLn('** Testing deflate with large buffers'); + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + {$IFDEF TEST_INFLATE} + WriteLn('** Testing inflate with large buffers'); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_FLUSH} + WriteLn('** Testing deflate with full flush'); + test_flush(compr, comprLen); + {$ENDIF} + {$IFDEF TEST_SYNC} + WriteLn('** Testing inflateSync'); + test_sync(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + comprLen := uncomprLen; + + {$IFDEF TEST_DICT} + WriteLn('** Testing deflate and inflate with preset dictionary'); + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + FreeMem(compr, comprLen); + FreeMem(uncompr, uncomprLen); +end. diff --git a/src/external/zlib-1.2.11/contrib/pascal/readme.txt b/src/external/zlib-1.2.11/contrib/pascal/readme.txt new file mode 100644 index 000000000..60e87c8a3 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/pascal/readme.txt @@ -0,0 +1,76 @@ + +This directory contains a Pascal (Delphi, Kylix) interface to the +zlib data compression library. + + +Directory listing +================= + +zlibd32.mak makefile for Borland C++ +example.pas usage example of zlib +zlibpas.pas the Pascal interface to zlib +readme.txt this file + + +Compatibility notes +=================== + +- Although the name "zlib" would have been more normal for the + zlibpas unit, this name is already taken by Borland's ZLib unit. + This is somehow unfortunate, because that unit is not a genuine + interface to the full-fledged zlib functionality, but a suite of + class wrappers around zlib streams. Other essential features, + such as checksums, are missing. + It would have been more appropriate for that unit to have a name + like "ZStreams", or something similar. + +- The C and zlib-supplied types int, uInt, long, uLong, etc. are + translated directly into Pascal types of similar sizes (Integer, + LongInt, etc.), to avoid namespace pollution. In particular, + there is no conversion of unsigned int into a Pascal unsigned + integer. The Word type is non-portable and has the same size + (16 bits) both in a 16-bit and in a 32-bit environment, unlike + Integer. Even if there is a 32-bit Cardinal type, there is no + real need for unsigned int in zlib under a 32-bit environment. + +- Except for the callbacks, the zlib function interfaces are + assuming the calling convention normally used in Pascal + (__pascal for DOS and Windows16, __fastcall for Windows32). + Since the cdecl keyword is used, the old Turbo Pascal does + not work with this interface. + +- The gz* function interfaces are not translated, to avoid + interfacing problems with the C runtime library. Besides, + gzprintf(gzFile file, const char *format, ...) + cannot be translated into Pascal. + + +Legal issues +============ + +The zlibpas interface is: + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler. + Copyright (C) 1998 by Bob Dellaca. + Copyright (C) 2003 by Cosmin Truta. + +The example program is: + Copyright (C) 1995-2003 by Jean-loup Gailly. + Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali. + Copyright (C) 2003 by Cosmin Truta. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + diff --git a/src/external/zlib-1.2.11/contrib/pascal/zlibd32.mak b/src/external/zlib-1.2.11/contrib/pascal/zlibd32.mak new file mode 100644 index 000000000..9bb00b7cc --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/pascal/zlibd32.mak @@ -0,0 +1,99 @@ +# Makefile for zlib +# For use with Delphi and C++ Builder under Win32 +# Updated for zlib 1.2.x by Cosmin Truta + +# ------------ Borland C++ ------------ + +# This project uses the Delphi (fastcall/register) calling convention: +LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl + +CC = bcc32 +LD = bcc32 +AR = tlib +# do not use "-pr" in CFLAGS +CFLAGS = -a -d -k- -O2 $(LOC) +LDFLAGS = + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.tds + -del zlib.bak + -del foo.gz + diff --git a/src/external/zlib-1.2.11/contrib/pascal/zlibpas.pas b/src/external/zlib-1.2.11/contrib/pascal/zlibpas.pas new file mode 100644 index 000000000..a0dff11b5 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/pascal/zlibpas.pas @@ -0,0 +1,276 @@ +(* zlibpas -- Pascal interface to the zlib data compression library + * + * Copyright (C) 2003 Cosmin Truta. + * Derived from original sources by Bob Dellaca. + * For conditions of distribution and use, see copyright notice in readme.txt + *) + +unit zlibpas; + +interface + +const + ZLIB_VERSION = '1.2.11'; + ZLIB_VERNUM = $12a0; + +type + alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; + cdecl; + free_func = procedure(opaque, address: Pointer); + cdecl; + + in_func = function(opaque: Pointer; var buf: PByte): Integer; + cdecl; + out_func = function(opaque: Pointer; buf: PByte; size: Integer): Integer; + cdecl; + + z_streamp = ^z_stream; + z_stream = packed record + next_in: PChar; (* next input byte *) + avail_in: Integer; (* number of bytes available at next_in *) + total_in: LongInt; (* total nb of input bytes read so far *) + + next_out: PChar; (* next output byte should be put there *) + avail_out: Integer; (* remaining free space at next_out *) + total_out: LongInt; (* total nb of bytes output so far *) + + msg: PChar; (* last error message, NULL if no error *) + state: Pointer; (* not visible by applications *) + + zalloc: alloc_func; (* used to allocate the internal state *) + zfree: free_func; (* used to free the internal state *) + opaque: Pointer; (* private data object passed to zalloc and zfree *) + + data_type: Integer; (* best guess about the data type: ascii or binary *) + adler: LongInt; (* adler32 value of the uncompressed data *) + reserved: LongInt; (* reserved for future use *) + end; + + gz_headerp = ^gz_header; + gz_header = packed record + text: Integer; (* true if compressed data believed to be text *) + time: LongInt; (* modification time *) + xflags: Integer; (* extra flags (not used when writing a gzip file) *) + os: Integer; (* operating system *) + extra: PChar; (* pointer to extra field or Z_NULL if none *) + extra_len: Integer; (* extra field length (valid if extra != Z_NULL) *) + extra_max: Integer; (* space at extra (only when reading header) *) + name: PChar; (* pointer to zero-terminated file name or Z_NULL *) + name_max: Integer; (* space at name (only when reading header) *) + comment: PChar; (* pointer to zero-terminated comment or Z_NULL *) + comm_max: Integer; (* space at comment (only when reading header) *) + hcrc: Integer; (* true if there was or will be a header crc *) + done: Integer; (* true when done reading gzip header *) + end; + +(* constants *) +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + Z_BLOCK = 5; + Z_TREES = 6; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = -1; + Z_STREAM_ERROR = -2; + Z_DATA_ERROR = -3; + Z_MEM_ERROR = -4; + Z_BUF_ERROR = -5; + Z_VERSION_ERROR = -6; + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = -1; + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_FIXED = 4; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_TEXT = 1; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + +(* basic functions *) +function zlibVersion: PChar; +function deflateInit(var strm: z_stream; level: Integer): Integer; +function deflate(var strm: z_stream; flush: Integer): Integer; +function deflateEnd(var strm: z_stream): Integer; +function inflateInit(var strm: z_stream): Integer; +function inflate(var strm: z_stream; flush: Integer): Integer; +function inflateEnd(var strm: z_stream): Integer; + +(* advanced functions *) +function deflateInit2(var strm: z_stream; level, method, windowBits, + memLevel, strategy: Integer): Integer; +function deflateSetDictionary(var strm: z_stream; const dictionary: PChar; + dictLength: Integer): Integer; +function deflateCopy(var dest, source: z_stream): Integer; +function deflateReset(var strm: z_stream): Integer; +function deflateParams(var strm: z_stream; level, strategy: Integer): Integer; +function deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer; +function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt; +function deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer; +function deflatePrime(var strm: z_stream; bits, value: Integer): Integer; +function deflateSetHeader(var strm: z_stream; head: gz_header): Integer; +function inflateInit2(var strm: z_stream; windowBits: Integer): Integer; +function inflateSetDictionary(var strm: z_stream; const dictionary: PChar; + dictLength: Integer): Integer; +function inflateSync(var strm: z_stream): Integer; +function inflateCopy(var dest, source: z_stream): Integer; +function inflateReset(var strm: z_stream): Integer; +function inflateReset2(var strm: z_stream; windowBits: Integer): Integer; +function inflatePrime(var strm: z_stream; bits, value: Integer): Integer; +function inflateMark(var strm: z_stream): LongInt; +function inflateGetHeader(var strm: z_stream; var head: gz_header): Integer; +function inflateBackInit(var strm: z_stream; + windowBits: Integer; window: PChar): Integer; +function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; + out_fn: out_func; out_desc: Pointer): Integer; +function inflateBackEnd(var strm: z_stream): Integer; +function zlibCompileFlags: LongInt; + +(* utility functions *) +function compress(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt): Integer; +function compress2(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt; + level: Integer): Integer; +function compressBound(sourceLen: LongInt): LongInt; +function uncompress(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt): Integer; + +(* checksum functions *) +function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt; +function adler32_combine(adler1, adler2, len2: LongInt): LongInt; +function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt; +function crc32_combine(crc1, crc2, len2: LongInt): LongInt; + +(* various hacks, don't look :) *) +function deflateInit_(var strm: z_stream; level: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateInit_(var strm: z_stream; const version: PChar; + stream_size: Integer): Integer; +function deflateInit2_(var strm: z_stream; + level, method, windowBits, memLevel, strategy: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateInit2_(var strm: z_stream; windowBits: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateBackInit_(var strm: z_stream; + windowBits: Integer; window: PChar; + const version: PChar; stream_size: Integer): Integer; + + +implementation + +{$L adler32.obj} +{$L compress.obj} +{$L crc32.obj} +{$L deflate.obj} +{$L infback.obj} +{$L inffast.obj} +{$L inflate.obj} +{$L inftrees.obj} +{$L trees.obj} +{$L uncompr.obj} +{$L zutil.obj} + +function adler32; external; +function adler32_combine; external; +function compress; external; +function compress2; external; +function compressBound; external; +function crc32; external; +function crc32_combine; external; +function deflate; external; +function deflateBound; external; +function deflateCopy; external; +function deflateEnd; external; +function deflateInit_; external; +function deflateInit2_; external; +function deflateParams; external; +function deflatePending; external; +function deflatePrime; external; +function deflateReset; external; +function deflateSetDictionary; external; +function deflateSetHeader; external; +function deflateTune; external; +function inflate; external; +function inflateBack; external; +function inflateBackEnd; external; +function inflateBackInit_; external; +function inflateCopy; external; +function inflateEnd; external; +function inflateGetHeader; external; +function inflateInit_; external; +function inflateInit2_; external; +function inflateMark; external; +function inflatePrime; external; +function inflateReset; external; +function inflateReset2; external; +function inflateSetDictionary; external; +function inflateSync; external; +function uncompress; external; +function zlibCompileFlags; external; +function zlibVersion; external; + +function deflateInit(var strm: z_stream; level: Integer): Integer; +begin + Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel, + strategy: Integer): Integer; +begin + Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(var strm: z_stream): Integer; +begin + Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2(var strm: z_stream; windowBits: Integer): Integer; +begin + Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateBackInit(var strm: z_stream; + windowBits: Integer; window: PChar): Integer; +begin + Result := inflateBackInit_(strm, windowBits, window, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function _malloc(Size: Integer): Pointer; cdecl; +begin + GetMem(Result, Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + +end. diff --git a/src/external/zlib-1.2.11/contrib/puff/Makefile b/src/external/zlib-1.2.11/contrib/puff/Makefile new file mode 100644 index 000000000..0e2594c80 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/puff/Makefile @@ -0,0 +1,42 @@ +CFLAGS=-O + +puff: puff.o pufftest.o + +puff.o: puff.h + +pufftest.o: puff.h + +test: puff + puff zeros.raw + +puft: puff.c puff.h pufftest.o + cc -fprofile-arcs -ftest-coverage -o puft puff.c pufftest.o + +# puff full coverage test (should say 100%) +cov: puft + @rm -f *.gcov *.gcda + @puft -w zeros.raw 2>&1 | cat > /dev/null + @echo '04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '00 00 00 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 254 + @echo '00 01 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '01 01 00 fe ff 0a' | xxd -r -p | puft -f 2>&1 | cat > /dev/null + @echo '02 7e ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246 + @echo '02' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '04 80 49 92 24 49 92 24 71 ff ff 93 11 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 249 + @echo '04 c0 81 08 00 00 00 00 20 7f eb 0b 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246 + @echo '0b 00 00' | xxd -r -p | puft -f 2>&1 | cat > /dev/null + @echo '1a 07' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246 + @echo '0c c0 81 00 00 00 00 00 90 ff 6b 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 245 + @puft -f zeros.raw 2>&1 | cat > /dev/null + @echo 'fc 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 253 + @echo '04 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 252 + @echo '04 00 24 49' | xxd -r -p | puft 2> /dev/null || test $$? -eq 251 + @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 84' | xxd -r -p | puft 2> /dev/null || test $$? -eq 248 + @echo '04 00 24 e9 ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 250 + @echo '04 00 24 e9 ff 6d' | xxd -r -p | puft 2> /dev/null || test $$? -eq 247 + @gcov -n puff.c + +clean: + rm -f puff puft *.o *.gc* diff --git a/src/external/zlib-1.2.11/contrib/puff/README b/src/external/zlib-1.2.11/contrib/puff/README new file mode 100644 index 000000000..bbc4cb595 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/puff/README @@ -0,0 +1,63 @@ +Puff -- A Simple Inflate +3 Mar 2003 +Mark Adler +madler@alumni.caltech.edu + +What this is -- + +puff.c provides the routine puff() to decompress the deflate data format. It +does so more slowly than zlib, but the code is about one-fifth the size of the +inflate code in zlib, and written to be very easy to read. + +Why I wrote this -- + +puff.c was written to document the deflate format unambiguously, by virtue of +being working C code. It is meant to supplement RFC 1951, which formally +describes the deflate format. I have received many questions on details of the +deflate format, and I hope that reading this code will answer those questions. +puff.c is heavily commented with details of the deflate format, especially +those little nooks and cranies of the format that might not be obvious from a +specification. + +puff.c may also be useful in applications where code size or memory usage is a +very limited resource, and speed is not as important. + +How to use it -- + +Well, most likely you should just be reading puff.c and using zlib for actual +applications, but if you must ... + +Include puff.h in your code, which provides this prototype: + +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen); /* amount of input available */ + +Then you can call puff() to decompress a deflate stream that is in memory in +its entirety at source, to a sufficiently sized block of memory for the +decompressed data at dest. puff() is the only external symbol in puff.c The +only C library functions that puff.c needs are setjmp() and longjmp(), which +are used to simplify error checking in the code to improve readabilty. puff.c +does no memory allocation, and uses less than 2K bytes off of the stack. + +If destlen is not enough space for the uncompressed data, then inflate will +return an error without writing more than destlen bytes. Note that this means +that in order to decompress the deflate data successfully, you need to know +the size of the uncompressed data ahead of time. + +If needed, puff() can determine the size of the uncompressed data with no +output space. This is done by passing dest equal to (unsigned char *)0. Then +the initial value of *destlen is ignored and *destlen is set to the length of +the uncompressed data. So if the size of the uncompressed data is not known, +then two passes of puff() can be used--first to determine the size, and second +to do the actual inflation after allocating the appropriate memory. Not +pretty, but it works. (This is one of the reasons you should be using zlib.) + +The deflate format is self-terminating. If the deflate stream does not end +in *sourcelen bytes, puff() will return an error without reading at or past +endsource. + +On return, *sourcelen is updated to the amount of input data consumed, and +*destlen is updated to the size of the uncompressed data. See the comments +in puff.c for the possible return codes for puff(). diff --git a/src/external/zlib-1.2.11/contrib/puff/puff.c b/src/external/zlib-1.2.11/contrib/puff/puff.c new file mode 100644 index 000000000..c6c90d714 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/puff/puff.c @@ -0,0 +1,840 @@ +/* + * puff.c + * Copyright (C) 2002-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in puff.h + * version 2.3, 21 Jan 2013 + * + * puff.c is a simple inflate written to be an unambiguous way to specify the + * deflate format. It is not written for speed but rather simplicity. As a + * side benefit, this code might actually be useful when small code is more + * important than speed, such as bootstrap applications. For typical deflate + * data, zlib's inflate() is about four times as fast as puff(). zlib's + * inflate compiles to around 20K on my machine, whereas puff.c compiles to + * around 4K on my machine (a PowerPC using GNU cc). If the faster decode() + * function here is used, then puff() is only twice as slow as zlib's + * inflate(). + * + * All dynamically allocated memory comes from the stack. The stack required + * is less than 2K bytes. This code is compatible with 16-bit int's and + * assumes that long's are at least 32 bits. puff.c uses the short data type, + * assumed to be 16 bits, for arrays in order to conserve memory. The code + * works whether integers are stored big endian or little endian. + * + * In the comments below are "Format notes" that describe the inflate process + * and document some of the less obvious aspects of the format. This source + * code is meant to supplement RFC 1951, which formally describes the deflate + * format: + * + * http://www.zlib.org/rfc-deflate.html + */ + +/* + * Change history: + * + * 1.0 10 Feb 2002 - First version + * 1.1 17 Feb 2002 - Clarifications of some comments and notes + * - Update puff() dest and source pointers on negative + * errors to facilitate debugging deflators + * - Remove longest from struct huffman -- not needed + * - Simplify offs[] index in construct() + * - Add input size and checking, using longjmp() to + * maintain easy readability + * - Use short data type for large arrays + * - Use pointers instead of long to specify source and + * destination sizes to avoid arbitrary 4 GB limits + * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!), + * but leave simple version for readabilty + * - Make sure invalid distances detected if pointers + * are 16 bits + * - Fix fixed codes table error + * - Provide a scanning mode for determining size of + * uncompressed data + * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly] + * - Add a puff.h file for the interface + * - Add braces in puff() for else do [Gailly] + * - Use indexes instead of pointers for readability + * 1.4 31 Mar 2002 - Simplify construct() code set check + * - Fix some comments + * - Add FIXLCODES #define + * 1.5 6 Apr 2002 - Minor comment fixes + * 1.6 7 Aug 2002 - Minor format changes + * 1.7 3 Mar 2003 - Added test code for distribution + * - Added zlib-like license + * 1.8 9 Jan 2004 - Added some comments on no distance codes case + * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland] + * - Catch missing end-of-block symbol error + * 2.0 25 Jul 2008 - Add #define to permit distance too far back + * - Add option in TEST code for puff to write the data + * - Add option in TEST code to skip input bytes + * - Allow TEST code to read from piped stdin + * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers + * - Avoid unsigned comparisons for even happier compilers + * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer] + * - Add const where appropriate [Oberhumer] + * - Split if's and ?'s for coverage testing + * - Break out test code to separate file + * - Move NIL to puff.h + * - Allow incomplete code only if single code length is 1 + * - Add full code coverage test to Makefile + * 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks + */ + +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "puff.h" /* prototype for puff() */ + +#define local static /* for local function definitions */ + +/* + * Maximums for allocations and loops. It is not useful to change these -- + * they are fixed by the deflate format. + */ +#define MAXBITS 15 /* maximum bits in a code */ +#define MAXLCODES 286 /* maximum number of literal/length codes */ +#define MAXDCODES 30 /* maximum number of distance codes */ +#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */ +#define FIXLCODES 288 /* number of fixed literal/length codes */ + +/* input and output state */ +struct state { + /* output state */ + unsigned char *out; /* output buffer */ + unsigned long outlen; /* available space at out */ + unsigned long outcnt; /* bytes written to out so far */ + + /* input state */ + const unsigned char *in; /* input buffer */ + unsigned long inlen; /* available input at in */ + unsigned long incnt; /* bytes read so far */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + long val; /* bit accumulator (can use up to 20 bits) */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->incnt == s->inlen) + longjmp(s->env, 1); /* out of input */ + val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */ + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = (int)(val >> need); + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return (int)(val & ((1L << need) - 1)); +} + +/* + * Process a stored block. + * + * Format notes: + * + * - After the two-bit stored block type (00), the stored block length and + * stored bytes are byte-aligned for fast copying. Therefore any leftover + * bits in the byte that has the last bit of the type, as many as seven, are + * discarded. The value of the discarded bits are not defined and should not + * be checked against any expectation. + * + * - The second inverted copy of the stored block length does not have to be + * checked, but it's probably a good idea to do so anyway. + * + * - A stored block can have zero length. This is sometimes used to byte-align + * subsets of the compressed data for random access or partial recovery. + */ +local int stored(struct state *s) +{ + unsigned len; /* length of stored block */ + + /* discard leftover bits from current byte (assumes s->bitcnt < 8) */ + s->bitbuf = 0; + s->bitcnt = 0; + + /* get length and check against its one's complement */ + if (s->incnt + 4 > s->inlen) + return 2; /* not enough input */ + len = s->in[s->incnt++]; + len |= s->in[s->incnt++] << 8; + if (s->in[s->incnt++] != (~len & 0xff) || + s->in[s->incnt++] != ((~len >> 8) & 0xff)) + return -2; /* didn't match complement! */ + + /* copy len bytes from in to out */ + if (s->incnt + len > s->inlen) + return 2; /* not enough input */ + if (s->out != NIL) { + if (s->outcnt + len > s->outlen) + return 1; /* not enough output space */ + while (len--) + s->out[s->outcnt++] = s->in[s->incnt++]; + } + else { /* just scanning */ + s->outcnt += len; + s->incnt += len; + } + + /* done with a valid stored block */ + return 0; +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -10 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. A table-based decoding + * scheme (as used in zlib) does not need to do this reversal. + * + * - The first code for the shortest length is all zeros. Subsequent codes of + * the same length are simply integer increments of the previous code. When + * moving up a length, a zero bit is appended to the code. For a complete + * code, the last code of the longest length will be all ones. + * + * - Incomplete codes are handled by this decoder, since they are permitted + * in the deflate format. See the format notes for fixed() and dynamic(). + */ +#ifdef SLOW +local int decode(struct state *s, const struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + + code = first = index = 0; + for (len = 1; len <= MAXBITS; len++) { + code |= bits(s, 1); /* get next bit */ + count = h->count[len]; + if (code - count < first) /* if length len, return symbol */ + return h->symbol[index + (code - first)]; + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + } + return -10; /* ran out of codes */ +} + +/* + * A faster version of decode() for real applications of this code. It's not + * as readable, but it makes puff() twice as fast. And it only makes the code + * a few percent larger. + */ +#else /* !SLOW */ +local int decode(struct state *s, const struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= bitbuf & 1; + bitbuf >>= 1; + count = *next++; + if (code - count < first) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) + break; + if (s->incnt == s->inlen) + longjmp(s->env, 1); /* out of input */ + bitbuf = s->in[s->incnt++]; + if (left > 8) + left = 8; + } + return -10; /* ran out of codes */ +} +#endif /* SLOW */ + +/* + * Given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + * + * Not used by decode(), but used for error checking, h->count[0] is the number + * of the n symbols not in the code. So n - h->count[0] is the number of + * codes. This is useful for checking for incomplete codes that have more than + * one symbol, which is an error in a dynamic block. + * + * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS + * This is assured by the construction of the length arrays in dynamic() and + * fixed() and is not verified by construct(). + * + * Format notes: + * + * - Permitted and expected examples of incomplete codes are one of the fixed + * codes and any code with a single symbol which in deflate is coded as one + * bit instead of zero bits. See the format notes for fixed() and dynamic(). + * + * - Within a given code length, the symbols are kept in ascending order for + * the code bits definition. + */ +local int construct(struct huffman *h, const short *length, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) + return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode literal/length and distance codes until an end-of-block code. + * + * Format notes: + * + * - Compressed data that is after the block type if fixed or after the code + * description if dynamic is a combination of literals and length/distance + * pairs terminated by and end-of-block code. Literals are simply Huffman + * coded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - Literals, lengths, and the end-of-block code are combined into a single + * code of up to 286 symbols. They are 256 literals (0..255), 29 length + * symbols (257..285), and the end-of-block symbol (256). + * + * - There are 256 possible lengths (3..258), and so 29 symbols are not enough + * to represent all of those. Lengths 3..10 and 258 are in fact represented + * by just a length symbol. Lengths 11..257 are represented as a symbol and + * some number of extra bits that are added as an integer to the base length + * of the length symbol. The number of extra bits is determined by the base + * length symbol. These are in the static arrays below, lens[] for the base + * lengths and lext[] for the corresponding number of extra bits. + * + * - The reason that 258 gets its own symbol is that the longest length is used + * often in highly redundant files. Note that 258 can also be coded as the + * base value 227 plus the maximum extra value of 31. While a good deflate + * should never do this, it is not an error, and should be decoded properly. + * + * - If a length is decoded, including its extra bits if any, then it is + * followed a distance code. There are up to 30 distance symbols. Again + * there are many more possible distances (1..32768), so extra bits are added + * to a base value represented by the symbol. The distances 1..4 get their + * own symbol, but the rest require extra bits. The base distances and + * corresponding number of extra bits are below in the static arrays dist[] + * and dext[]. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 258 + * simply copies the last byte 258 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. You should not use memcpy() since its behavior is not + * defined for overlapped arrays. You should not use memmove() or bcopy() + * since though their behavior -is- defined for overlapping arrays, it is + * defined to do the wrong thing in this case. + */ +local int codes(struct state *s, + const struct huffman *lencode, + const struct huffman *distcode) +{ + int symbol; /* decoded symbol */ + int len; /* length for copy */ + unsigned dist; /* distance for copy */ + static const short lens[29] = { /* Size base for length codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; + static const short lext[29] = { /* Extra bits for length codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; + static const short dists[30] = { /* Offset base for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; + static const short dext[30] = { /* Extra bits for distance codes 0..29 */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + /* decode literals and length/distance pairs */ + do { + symbol = decode(s, lencode); + if (symbol < 0) + return symbol; /* invalid symbol */ + if (symbol < 256) { /* literal: symbol is the byte */ + /* write out the literal */ + if (s->out != NIL) { + if (s->outcnt == s->outlen) + return 1; + s->out[s->outcnt] = symbol; + } + s->outcnt++; + } + else if (symbol > 256) { /* length */ + /* get and compute length */ + symbol -= 257; + if (symbol >= 29) + return -10; /* invalid fixed code */ + len = lens[symbol] + bits(s, lext[symbol]); + + /* get and check distance */ + symbol = decode(s, distcode); + if (symbol < 0) + return symbol; /* invalid symbol */ + dist = dists[symbol] + bits(s, dext[symbol]); +#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (dist > s->outcnt) + return -11; /* distance too far back */ +#endif + + /* copy length bytes from distance bytes back */ + if (s->out != NIL) { + if (s->outcnt + len > s->outlen) + return 1; + while (len--) { + s->out[s->outcnt] = +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + dist > s->outcnt ? + 0 : +#endif + s->out[s->outcnt - dist]; + s->outcnt++; + } + } + else + s->outcnt += len; + } + } while (symbol != 256); /* end of block symbol */ + + /* done with a valid fixed or dynamic block */ + return 0; +} + +/* + * Process a fixed codes block. + * + * Format notes: + * + * - This block type can be useful for compressing small amounts of data for + * which the size of the code descriptions in a dynamic block exceeds the + * benefit of custom codes for that block. For fixed codes, no bits are + * spent on code descriptions. Instead the code lengths for literal/length + * codes and distance codes are fixed. The specific lengths for each symbol + * can be seen in the "for" loops below. + * + * - The literal/length code is complete, but has two symbols that are invalid + * and should result in an error if received. This cannot be implemented + * simply as an incomplete code since those two symbols are in the "middle" + * of the code. They are eight bits long and the longest literal/length\ + * code is nine bits. Therefore the code must be constructed with those + * symbols, and the invalid symbols must be detected after decoding. + * + * - The fixed distance codes also have two invalid symbols that should result + * in an error if received. Since all of the distance codes are the same + * length, this can be implemented as an incomplete code. Then the invalid + * codes are detected while decoding. + */ +local int fixed(struct state *s) +{ + static int virgin = 1; + static short lencnt[MAXBITS+1], lensym[FIXLCODES]; + static short distcnt[MAXBITS+1], distsym[MAXDCODES]; + static struct huffman lencode, distcode; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + int symbol; + short lengths[FIXLCODES]; + + /* construct lencode and distcode */ + lencode.count = lencnt; + lencode.symbol = lensym; + distcode.count = distcnt; + distcode.symbol = distsym; + + /* literal/length table */ + for (symbol = 0; symbol < 144; symbol++) + lengths[symbol] = 8; + for (; symbol < 256; symbol++) + lengths[symbol] = 9; + for (; symbol < 280; symbol++) + lengths[symbol] = 7; + for (; symbol < FIXLCODES; symbol++) + lengths[symbol] = 8; + construct(&lencode, lengths, FIXLCODES); + + /* distance table */ + for (symbol = 0; symbol < MAXDCODES; symbol++) + lengths[symbol] = 5; + construct(&distcode, lengths, MAXDCODES); + + /* do this just once */ + virgin = 0; + } + + /* decode data until end-of-block code */ + return codes(s, &lencode, &distcode); +} + +/* + * Process a dynamic codes block. + * + * Format notes: + * + * - A dynamic block starts with a description of the literal/length and + * distance codes for that block. New dynamic blocks allow the compressor to + * rapidly adapt to changing data with new codes optimized for that data. + * + * - The codes used by the deflate format are "canonical", which means that + * the actual bits of the codes are generated in an unambiguous way simply + * from the number of bits in each code. Therefore the code descriptions + * are simply a list of code lengths for each symbol. + * + * - The code lengths are stored in order for the symbols, so lengths are + * provided for each of the literal/length symbols, and for each of the + * distance symbols. + * + * - If a symbol is not used in the block, this is represented by a zero as + * as the code length. This does not mean a zero-length code, but rather + * that no code should be created for this symbol. There is no way in the + * deflate format to represent a zero-length code. + * + * - The maximum number of bits in a code is 15, so the possible lengths for + * any code are 1..15. + * + * - The fact that a length of zero is not permitted for a code has an + * interesting consequence. Normally if only one symbol is used for a given + * code, then in fact that code could be represented with zero bits. However + * in deflate, that code has to be at least one bit. So for example, if + * only a single distance base symbol appears in a block, then it will be + * represented by a single code of length one, in particular one 0 bit. This + * is an incomplete code, since if a 1 bit is received, it has no meaning, + * and should result in an error. So incomplete distance codes of one symbol + * should be permitted, and the receipt of invalid codes should be handled. + * + * - It is also possible to have a single literal/length code, but that code + * must be the end-of-block code, since every dynamic block has one. This + * is not the most efficient way to create an empty block (an empty fixed + * block is fewer bits), but it is allowed by the format. So incomplete + * literal/length codes of one symbol should also be permitted. + * + * - If there are only literal codes and no lengths, then there are no distance + * codes. This is represented by one distance code with zero bits. + * + * - The list of up to 286 length/literal lengths and up to 30 distance lengths + * are themselves compressed using Huffman codes and run-length encoding. In + * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means + * that length, and the symbols 16, 17, and 18 are run-length instructions. + * Each of 16, 17, and 18 are follwed by extra bits to define the length of + * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10 + * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols + * are common, hence the special coding for zero lengths. + * + * - The symbols for 0..18 are Huffman coded, and so that code must be + * described first. This is simply a sequence of up to 19 three-bit values + * representing no code (0) or the code length for that symbol (1..7). + * + * - A dynamic block starts with three fixed-size counts from which is computed + * the number of literal/length code lengths, the number of distance code + * lengths, and the number of code length code lengths (ok, you come up with + * a better name!) in the code descriptions. For the literal/length and + * distance codes, lengths after those provided are considered zero, i.e. no + * code. The code length code lengths are received in a permuted order (see + * the order[] array below) to make a short code length code length list more + * likely. As it turns out, very short and very long codes are less likely + * to be seen in a dynamic code description, hence what may appear initially + * to be a peculiar ordering. + * + * - Given the number of literal/length code lengths (nlen) and distance code + * lengths (ndist), then they are treated as one long list of nlen + ndist + * code lengths. Therefore run-length coding can and often does cross the + * boundary between the two sets of lengths. + * + * - So to summarize, the code description at the start of a dynamic block is + * three counts for the number of code lengths for the literal/length codes, + * the distance codes, and the code length codes. This is followed by the + * code length code lengths, three bits each. This is used to construct the + * code length code which is used to read the remainder of the lengths. Then + * the literal/length code lengths and distance lengths are read as a single + * set of lengths using the code length codes. Codes are constructed from + * the resulting two sets of lengths, and then finally you can start + * decoding actual compressed data in the block. + * + * - For reference, a "typical" size for the code description in a dynamic + * block is around 80 bytes. + */ +local int dynamic(struct state *s) +{ + int nlen, ndist, ncode; /* number of lengths in descriptor */ + int index; /* index of lengths[] */ + int err; /* construct() return value */ + short lengths[MAXCODES]; /* descriptor code lengths */ + short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */ + short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */ + struct huffman lencode, distcode; /* length and distance codes */ + static const short order[19] = /* permutation of code length codes */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* construct lencode and distcode */ + lencode.count = lencnt; + lencode.symbol = lensym; + distcode.count = distcnt; + distcode.symbol = distsym; + + /* get number of lengths in each table, check lengths */ + nlen = bits(s, 5) + 257; + ndist = bits(s, 5) + 1; + ncode = bits(s, 4) + 4; + if (nlen > MAXLCODES || ndist > MAXDCODES) + return -3; /* bad counts */ + + /* read code length code lengths (really), missing lengths are zero */ + for (index = 0; index < ncode; index++) + lengths[order[index]] = bits(s, 3); + for (; index < 19; index++) + lengths[order[index]] = 0; + + /* build huffman table for code lengths codes (use lencode temporarily) */ + err = construct(&lencode, lengths, 19); + if (err != 0) /* require complete code set here */ + return -4; + + /* read length/literal and distance code length tables */ + index = 0; + while (index < nlen + ndist) { + int symbol; /* decoded value */ + int len; /* last length to repeat */ + + symbol = decode(s, &lencode); + if (symbol < 0) + return symbol; /* invalid symbol */ + if (symbol < 16) /* length in 0..15 */ + lengths[index++] = symbol; + else { /* repeat instruction */ + len = 0; /* assume repeating zeros */ + if (symbol == 16) { /* repeat last length 3..6 times */ + if (index == 0) + return -5; /* no last length! */ + len = lengths[index - 1]; /* last length */ + symbol = 3 + bits(s, 2); + } + else if (symbol == 17) /* repeat zero 3..10 times */ + symbol = 3 + bits(s, 3); + else /* == 18, repeat zero 11..138 times */ + symbol = 11 + bits(s, 7); + if (index + symbol > nlen + ndist) + return -6; /* too many lengths! */ + while (symbol--) /* repeat last or zero symbol times */ + lengths[index++] = len; + } + } + + /* check for end-of-block code -- there better be one! */ + if (lengths[256] == 0) + return -9; + + /* build huffman table for literal/length codes */ + err = construct(&lencode, lengths, nlen); + if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1])) + return -7; /* incomplete code ok only for single length 1 code */ + + /* build huffman table for distance codes */ + err = construct(&distcode, lengths + nlen, ndist); + if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1])) + return -8; /* incomplete code ok only for single length 1 code */ + + /* decode data until end-of-block code */ + return codes(s, &lencode, &distcode); +} + +/* + * Inflate source to dest. On return, destlen and sourcelen are updated to the + * size of the uncompressed data and the size of the deflate data respectively. + * On success, the return value of puff() is zero. If there is an error in the + * source data, i.e. it is not in the deflate format, then a negative value is + * returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. In that case, destlen and + * sourcelen are not updated to facilitate retrying from the beginning with the + * provision of more input data or more output space. In the case of invalid + * inflate data (a negative error), the dest and source pointers are updated to + * facilitate the debugging of deflators. + * + * puff() also has a mode to determine the size of the uncompressed output with + * no output written. For this dest must be (unsigned char *)0. In this case, + * the input value of *destlen is ignored, and on return *destlen is set to the + * size of the uncompressed output. + * + * The return codes are: + * + * 2: available inflate data did not terminate + * 1: output space exhausted before completing inflate + * 0: successful inflate + * -1: invalid block type (type == 3) + * -2: stored block length did not match one's complement + * -3: dynamic block code description: too many length or distance codes + * -4: dynamic block code description: code lengths codes incomplete + * -5: dynamic block code description: repeat lengths with no first length + * -6: dynamic block code description: repeat more than specified lengths + * -7: dynamic block code description: invalid literal/length code lengths + * -8: dynamic block code description: invalid distance code lengths + * -9: dynamic block code description: missing end-of-block code + * -10: invalid literal/length or distance code in fixed or dynamic block + * -11: distance is too far back in fixed or dynamic block + * + * Format notes: + * + * - Three bits are read for each block to determine the kind of block and + * whether or not it is the last block. Then the block is decoded and the + * process repeated if it was not the last block. + * + * - The leftover bits in the last byte of the deflate data after the last + * block (if it was a fixed or dynamic block) are undefined and have no + * expected values to check. + */ +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + const unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen) /* amount of input available */ +{ + struct state s; /* input/output state */ + int last, type; /* block information */ + int err; /* return value */ + + /* initialize output state */ + s.out = dest; + s.outlen = *destlen; /* ignored if dest is NIL */ + s.outcnt = 0; + + /* initialize input state */ + s.in = source; + s.inlen = *sourcelen; + s.incnt = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp() */ + err = 2; /* then skip do-loop, return error */ + else { + /* process blocks until last block or error */ + do { + last = bits(&s, 1); /* one if last block */ + type = bits(&s, 2); /* block type 0..3 */ + err = type == 0 ? + stored(&s) : + (type == 1 ? + fixed(&s) : + (type == 2 ? + dynamic(&s) : + -1)); /* type == 3, invalid */ + if (err != 0) + break; /* return with error */ + } while (!last); + } + + /* update the lengths and return */ + if (err <= 0) { + *destlen = s.outcnt; + *sourcelen = s.incnt; + } + return err; +} diff --git a/src/external/zlib-1.2.11/contrib/puff/puff.h b/src/external/zlib-1.2.11/contrib/puff/puff.h new file mode 100644 index 000000000..e23a24543 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/puff/puff.h @@ -0,0 +1,35 @@ +/* puff.h + Copyright (C) 2002-2013 Mark Adler, all rights reserved + version 2.3, 21 Jan 2013 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * See puff.c for purpose and usage. + */ +#ifndef NIL +# define NIL ((unsigned char *)0) /* for no output option */ +#endif + +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + const unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen); /* amount of input available */ diff --git a/src/external/zlib-1.2.11/contrib/puff/pufftest.c b/src/external/zlib-1.2.11/contrib/puff/pufftest.c new file mode 100644 index 000000000..776481488 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/puff/pufftest.c @@ -0,0 +1,165 @@ +/* + * pufftest.c + * Copyright (C) 2002-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in puff.h + * version 2.3, 21 Jan 2013 + */ + +/* Example of how to use puff(). + + Usage: puff [-w] [-f] [-nnn] file + ... | puff [-w] [-f] [-nnn] + + where file is the input file with deflate data, nnn is the number of bytes + of input to skip before inflating (e.g. to skip a zlib or gzip header), and + -w is used to write the decompressed data to stdout. -f is for coverage + testing, and causes pufftest to fail with not enough output space (-f does + a write like -w, so -w is not required). */ + +#include +#include +#include "puff.h" + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define local static + +/* Return size times approximately the cube root of 2, keeping the result as 1, + 3, or 5 times a power of 2 -- the result is always > size, until the result + is the maximum value of an unsigned long, where it remains. This is useful + to keep reallocations less than ~33% over the actual data. */ +local size_t bythirds(size_t size) +{ + int n; + size_t m; + + m = size; + for (n = 0; m; n++) + m >>= 1; + if (n < 3) + return size + 1; + n -= 3; + m = size >> n; + m += m == 6 ? 2 : 1; + m <<= n; + return m > size ? m : (size_t)(-1); +} + +/* Read the input file *name, or stdin if name is NULL, into allocated memory. + Reallocate to larger buffers until the entire file is read in. Return a + pointer to the allocated data, or NULL if there was a memory allocation + failure. *len is the number of bytes of data read from the input file (even + if load() returns NULL). If the input file was empty or could not be opened + or read, *len is zero. */ +local void *load(const char *name, size_t *len) +{ + size_t size; + void *buf, *swap; + FILE *in; + + *len = 0; + buf = malloc(size = 4096); + if (buf == NULL) + return NULL; + in = name == NULL ? stdin : fopen(name, "rb"); + if (in != NULL) { + for (;;) { + *len += fread((char *)buf + *len, 1, size - *len, in); + if (*len < size) break; + size = bythirds(size); + if (size == *len || (swap = realloc(buf, size)) == NULL) { + free(buf); + buf = NULL; + break; + } + buf = swap; + } + fclose(in); + } + return buf; +} + +int main(int argc, char **argv) +{ + int ret, put = 0, fail = 0; + unsigned skip = 0; + char *arg, *name = NULL; + unsigned char *source = NULL, *dest; + size_t len = 0; + unsigned long sourcelen, destlen; + + /* process arguments */ + while (arg = *++argv, --argc) + if (arg[0] == '-') { + if (arg[1] == 'w' && arg[2] == 0) + put = 1; + else if (arg[1] == 'f' && arg[2] == 0) + fail = 1, put = 1; + else if (arg[1] >= '0' && arg[1] <= '9') + skip = (unsigned)atoi(arg + 1); + else { + fprintf(stderr, "invalid option %s\n", arg); + return 3; + } + } + else if (name != NULL) { + fprintf(stderr, "only one file name allowed\n"); + return 3; + } + else + name = arg; + source = load(name, &len); + if (source == NULL) { + fprintf(stderr, "memory allocation failure\n"); + return 4; + } + if (len == 0) { + fprintf(stderr, "could not read %s, or it was empty\n", + name == NULL ? "" : name); + free(source); + return 3; + } + if (skip >= len) { + fprintf(stderr, "skip request of %d leaves no input\n", skip); + free(source); + return 3; + } + + /* test inflate data with offset skip */ + len -= skip; + sourcelen = (unsigned long)len; + ret = puff(NIL, &destlen, source + skip, &sourcelen); + if (ret) + fprintf(stderr, "puff() failed with return code %d\n", ret); + else { + fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen); + if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n", + len - sourcelen); + } + + /* if requested, inflate again and write decompressd data to stdout */ + if (put && ret == 0) { + if (fail) + destlen >>= 1; + dest = malloc(destlen); + if (dest == NULL) { + fprintf(stderr, "memory allocation failure\n"); + free(source); + return 4; + } + puff(dest, &destlen, source + skip, &sourcelen); + SET_BINARY_MODE(stdout); + fwrite(dest, 1, destlen, stdout); + free(dest); + } + + /* clean up */ + free(source); + return ret; +} diff --git a/src/external/zlib-1.2.11/contrib/puff/zeros.raw b/src/external/zlib-1.2.11/contrib/puff/zeros.raw new file mode 100644 index 000000000..0a90e76b3 Binary files /dev/null and b/src/external/zlib-1.2.11/contrib/puff/zeros.raw differ diff --git a/src/external/zlib-1.2.11/contrib/testzlib/testzlib.c b/src/external/zlib-1.2.11/contrib/testzlib/testzlib.c new file mode 100644 index 000000000..8626c92ad --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/testzlib/testzlib.c @@ -0,0 +1,275 @@ +#include +#include +#include + +#include "zlib.h" + + +void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B) +{ + R->HighPart = A.HighPart - B.HighPart; + if (A.LowPart >= B.LowPart) + R->LowPart = A.LowPart - B.LowPart; + else + { + R->LowPart = A.LowPart - B.LowPart; + R->HighPart --; + } +} + +#ifdef _M_X64 +// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc +unsigned __int64 __rdtsc(void); +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ + // printf("rdtsc = %I64x\n",__rdtsc()); + pbeginTime64->QuadPart=__rdtsc(); +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER LIres; + unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart)); + LIres.QuadPart=res; + // printf("rdtsc = %I64x\n",__rdtsc()); + return LIres; +} +#else +#ifdef _M_IX86 +void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) +{ + DWORD dwEdx,dwEax; + _asm + { + rdtsc + mov dwEax,eax + mov dwEdx,edx + } + pbeginTime64->LowPart=dwEax; + pbeginTime64->HighPart=dwEdx; +} + +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ + myGetRDTSC32(pbeginTime64); +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER LIres,endTime64; + myGetRDTSC32(&endTime64); + + LIres.LowPart=LIres.HighPart=0; + MyDoMinus64(&LIres,endTime64,beginTime64); + return LIres; +} +#else +void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) +{ +} + +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER lr; + lr.QuadPart=0; + return lr; +} +#endif +#endif + +void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf) +{ + if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64))) + { + pbeginTime64->LowPart = GetTickCount(); + pbeginTime64->HighPart = 0; + } +} + +DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER endTime64,ticksPerSecond,ticks; + DWORDLONG ticksShifted,tickSecShifted; + DWORD dwLog=16+0; + DWORD dwRet; + if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64))) + dwRet = (GetTickCount() - beginTime64.LowPart)*1; + else + { + MyDoMinus64(&ticks,endTime64,beginTime64); + QueryPerformanceFrequency(&ticksPerSecond); + + + { + ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog); + tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog); + + } + + dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted)); + dwRet *=1; + } + return dwRet; +} + +int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr) +{ + FILE* stream; + unsigned char* ptr; + int retVal=1; + stream=fopen(filename, "rb"); + if (stream==NULL) + return 0; + + fseek(stream,0,SEEK_END); + + *plFileSize=ftell(stream); + fseek(stream,0,SEEK_SET); + ptr=malloc((*plFileSize)+1); + if (ptr==NULL) + retVal=0; + else + { + if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize)) + retVal=0; + } + fclose(stream); + *pFilePtr=ptr; + return retVal; +} + +int main(int argc, char *argv[]) +{ + int BlockSizeCompress=0x8000; + int BlockSizeUncompress=0x8000; + int cprLevel=Z_DEFAULT_COMPRESSION ; + long lFileSize; + unsigned char* FilePtr; + long lBufferSizeCpr; + long lBufferSizeUncpr; + long lCompressedSize=0; + unsigned char* CprPtr; + unsigned char* UncprPtr; + long lSizeCpr,lSizeUncpr; + DWORD dwGetTick,dwMsecQP; + LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc; + + if (argc<=1) + { + printf("run TestZlib [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n"); + return 0; + } + + if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0) + { + printf("error reading %s\n",argv[1]); + return 1; + } + else printf("file %s read, %u bytes\n",argv[1],lFileSize); + + if (argc>=3) + BlockSizeCompress=atol(argv[2]); + + if (argc>=4) + BlockSizeUncompress=atol(argv[3]); + + if (argc>=5) + cprLevel=(int)atol(argv[4]); + + lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200; + lBufferSizeUncpr = lBufferSizeCpr; + + CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress); + + BeginCountPerfCounter(&li_qp,TRUE); + dwGetTick=GetTickCount(); + BeginCountRdtsc(&li_rdtsc); + { + z_stream zcpr; + int ret=Z_OK; + long lOrigToDo = lFileSize; + long lOrigDone = 0; + int step=0; + memset(&zcpr,0,sizeof(z_stream)); + deflateInit(&zcpr,cprLevel); + + zcpr.next_in = FilePtr; + zcpr.next_out = CprPtr; + + + do + { + long all_read_before = zcpr.total_in; + zcpr.avail_in = min(lOrigToDo,BlockSizeCompress); + zcpr.avail_out = BlockSizeCompress; + ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH); + lOrigDone += (zcpr.total_in-all_read_before); + lOrigToDo -= (zcpr.total_in-all_read_before); + step++; + } while (ret==Z_OK); + + lSizeCpr=zcpr.total_out; + deflateEnd(&zcpr); + dwGetTick=GetTickCount()-dwGetTick; + dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); + dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); + printf("total compress size = %u, in %u step\n",lSizeCpr,step); + printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); + printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); + printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); + } + + CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr); + UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress); + + BeginCountPerfCounter(&li_qp,TRUE); + dwGetTick=GetTickCount(); + BeginCountRdtsc(&li_rdtsc); + { + z_stream zcpr; + int ret=Z_OK; + long lOrigToDo = lSizeCpr; + long lOrigDone = 0; + int step=0; + memset(&zcpr,0,sizeof(z_stream)); + inflateInit(&zcpr); + + zcpr.next_in = CprPtr; + zcpr.next_out = UncprPtr; + + + do + { + long all_read_before = zcpr.total_in; + zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress); + zcpr.avail_out = BlockSizeUncompress; + ret=inflate(&zcpr,Z_SYNC_FLUSH); + lOrigDone += (zcpr.total_in-all_read_before); + lOrigToDo -= (zcpr.total_in-all_read_before); + step++; + } while (ret==Z_OK); + + lSizeUncpr=zcpr.total_out; + inflateEnd(&zcpr); + dwGetTick=GetTickCount()-dwGetTick; + dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); + dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); + printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step); + printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); + printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); + printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); + } + + if (lSizeUncpr==lFileSize) + { + if (memcmp(FilePtr,UncprPtr,lFileSize)==0) + printf("compare ok\n"); + + } + + return 0; +} diff --git a/src/external/zlib-1.2.11/contrib/testzlib/testzlib.txt b/src/external/zlib-1.2.11/contrib/testzlib/testzlib.txt new file mode 100644 index 000000000..e508bb22f --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/testzlib/testzlib.txt @@ -0,0 +1,10 @@ +To build testzLib with Visual Studio 2005: + +copy to a directory file from : +- root of zLib tree +- contrib/testzlib +- contrib/masmx86 +- contrib/masmx64 +- contrib/vstudio/vc7 + +and open testzlib8.sln \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/untgz/Makefile b/src/external/zlib-1.2.11/contrib/untgz/Makefile new file mode 100644 index 000000000..b54266fba --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/untgz/Makefile @@ -0,0 +1,14 @@ +CC=cc +CFLAGS=-g + +untgz: untgz.o ../../libz.a + $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz + +untgz.o: untgz.c ../../zlib.h + $(CC) $(CFLAGS) -c -I../.. untgz.c + +../../libz.a: + cd ../..; ./configure; make + +clean: + rm -f untgz untgz.o *~ diff --git a/src/external/zlib-1.2.11/contrib/untgz/Makefile.msc b/src/external/zlib-1.2.11/contrib/untgz/Makefile.msc new file mode 100644 index 000000000..77b860221 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/untgz/Makefile.msc @@ -0,0 +1,17 @@ +CC=cl +CFLAGS=-MD + +untgz.exe: untgz.obj ..\..\zlib.lib + $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib + +untgz.obj: untgz.c ..\..\zlib.h + $(CC) $(CFLAGS) -c -I..\.. untgz.c + +..\..\zlib.lib: + cd ..\.. + $(MAKE) -f win32\makefile.msc + cd contrib\untgz + +clean: + -del untgz.obj + -del untgz.exe diff --git a/src/external/zlib-1.2.11/contrib/untgz/untgz.c b/src/external/zlib-1.2.11/contrib/untgz/untgz.c new file mode 100644 index 000000000..2c391e598 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/untgz/untgz.c @@ -0,0 +1,674 @@ +/* + * untgz.c -- Display contents and extract files from a gzip'd TAR file + * + * written by Pedro A. Aranda Gutierrez + * adaptation to Unix by Jean-loup Gailly + * various fixes by Cosmin Truta + */ + +#include +#include +#include +#include +#include + +#include "zlib.h" + +#ifdef unix +# include +#else +# include +# include +#endif + +#ifdef WIN32 +#include +# ifndef F_OK +# define F_OK 0 +# endif +# define mkdir(dirname,mode) _mkdir(dirname) +# ifdef _MSC_VER +# define access(path,mode) _access(path,mode) +# define chmod(path,mode) _chmod(path,mode) +# define strdup(str) _strdup(str) +# endif +#else +# include +#endif + + +/* values used in typeflag field */ + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define LNKTYPE '1' /* link */ +#define SYMTYPE '2' /* reserved */ +#define CHRTYPE '3' /* character special */ +#define BLKTYPE '4' /* block special */ +#define DIRTYPE '5' /* directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* reserved */ + +/* GNU tar extensions */ + +#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */ +#define GNUTYPE_LONGLINK 'K' /* long link name */ +#define GNUTYPE_LONGNAME 'L' /* long file name */ +#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */ +#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */ +#define GNUTYPE_SPARSE 'S' /* sparse file */ +#define GNUTYPE_VOLHDR 'V' /* tape/volume header */ + + +/* tar header */ + +#define BLOCKSIZE 512 +#define SHORTNAMESIZE 100 + +struct tar_header +{ /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; + +union tar_buffer +{ + char buffer[BLOCKSIZE]; + struct tar_header header; +}; + +struct attr_item +{ + struct attr_item *next; + char *fname; + int mode; + time_t time; +}; + +enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID }; + +char *TGZfname OF((const char *)); +void TGZnotfound OF((const char *)); + +int getoct OF((char *, int)); +char *strtime OF((time_t *)); +int setfiletime OF((char *, time_t)); +void push_attr OF((struct attr_item **, char *, int, time_t)); +void restore_attr OF((struct attr_item **)); + +int ExprMatch OF((char *, char *)); + +int makedir OF((char *)); +int matchname OF((int, int, char **, char *)); + +void error OF((const char *)); +int tar OF((gzFile, int, int, int, char **)); + +void help OF((int)); +int main OF((int, char **)); + +char *prog; + +const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL }; + +/* return the file name of the TGZ archive */ +/* or NULL if it does not exist */ + +char *TGZfname (const char *arcname) +{ + static char buffer[1024]; + int origlen,i; + + strcpy(buffer,arcname); + origlen = strlen(buffer); + + for (i=0; TGZsuffix[i]; i++) + { + strcpy(buffer+origlen,TGZsuffix[i]); + if (access(buffer,F_OK) == 0) + return buffer; + } + return NULL; +} + + +/* error message for the filename */ + +void TGZnotfound (const char *arcname) +{ + int i; + + fprintf(stderr,"%s: Couldn't find ",prog); + for (i=0;TGZsuffix[i];i++) + fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n", + arcname, + TGZsuffix[i]); + exit(1); +} + + +/* convert octal digits to int */ +/* on error return -1 */ + +int getoct (char *p,int width) +{ + int result = 0; + char c; + + while (width--) + { + c = *p++; + if (c == 0) + break; + if (c == ' ') + continue; + if (c < '0' || c > '7') + return -1; + result = result * 8 + (c - '0'); + } + return result; +} + + +/* convert time_t to string */ +/* use the "YYYY/MM/DD hh:mm:ss" format */ + +char *strtime (time_t *t) +{ + struct tm *local; + static char result[32]; + + local = localtime(t); + sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d", + local->tm_year+1900, local->tm_mon+1, local->tm_mday, + local->tm_hour, local->tm_min, local->tm_sec); + return result; +} + + +/* set file time */ + +int setfiletime (char *fname,time_t ftime) +{ +#ifdef WIN32 + static int isWinNT = -1; + SYSTEMTIME st; + FILETIME locft, modft; + struct tm *loctm; + HANDLE hFile; + int result; + + loctm = localtime(&ftime); + if (loctm == NULL) + return -1; + + st.wYear = (WORD)loctm->tm_year + 1900; + st.wMonth = (WORD)loctm->tm_mon + 1; + st.wDayOfWeek = (WORD)loctm->tm_wday; + st.wDay = (WORD)loctm->tm_mday; + st.wHour = (WORD)loctm->tm_hour; + st.wMinute = (WORD)loctm->tm_min; + st.wSecond = (WORD)loctm->tm_sec; + st.wMilliseconds = 0; + if (!SystemTimeToFileTime(&st, &locft) || + !LocalFileTimeToFileTime(&locft, &modft)) + return -1; + + if (isWinNT < 0) + isWinNT = (GetVersion() < 0x80000000) ? 1 : 0; + hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0), + NULL); + if (hFile == INVALID_HANDLE_VALUE) + return -1; + result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1; + CloseHandle(hFile); + return result; +#else + struct utimbuf settime; + + settime.actime = settime.modtime = ftime; + return utime(fname,&settime); +#endif +} + + +/* push file attributes */ + +void push_attr(struct attr_item **list,char *fname,int mode,time_t time) +{ + struct attr_item *item; + + item = (struct attr_item *)malloc(sizeof(struct attr_item)); + if (item == NULL) + error("Out of memory"); + item->fname = strdup(fname); + item->mode = mode; + item->time = time; + item->next = *list; + *list = item; +} + + +/* restore file attributes */ + +void restore_attr(struct attr_item **list) +{ + struct attr_item *item, *prev; + + for (item = *list; item != NULL; ) + { + setfiletime(item->fname,item->time); + chmod(item->fname,item->mode); + prev = item; + item = item->next; + free(prev); + } + *list = NULL; +} + + +/* match regular expression */ + +#define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) + +int ExprMatch (char *string,char *expr) +{ + while (1) + { + if (ISSPECIAL(*expr)) + { + if (*expr == '/') + { + if (*string != '\\' && *string != '/') + return 0; + string ++; expr++; + } + else if (*expr == '*') + { + if (*expr ++ == 0) + return 1; + while (*++string != *expr) + if (*string == 0) + return 0; + } + } + else + { + if (*string != *expr) + return 0; + if (*expr++ == 0) + return 1; + string++; + } + } +} + + +/* recursive mkdir */ +/* abort on ENOENT; ignore other errors like "directory already exists" */ +/* return 1 if OK */ +/* 0 on error */ + +int makedir (char *newdir) +{ + char *buffer = strdup(newdir); + char *p; + int len = strlen(buffer); + + if (len <= 0) { + free(buffer); + return 0; + } + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mkdir(buffer, 0755) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT)) + { + fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + + +int matchname (int arg,int argc,char **argv,char *fname) +{ + if (arg == argc) /* no arguments given (untgz tgzarchive) */ + return 1; + + while (arg < argc) + if (ExprMatch(fname,argv[arg++])) + return 1; + + return 0; /* ignore this for the moment being */ +} + + +/* tar file list or extract */ + +int tar (gzFile in,int action,int arg,int argc,char **argv) +{ + union tar_buffer buffer; + int len; + int err; + int getheader = 1; + int remaining = 0; + FILE *outfile = NULL; + char fname[BLOCKSIZE]; + int tarmode; + time_t tartime; + struct attr_item *attributes = NULL; + + if (action == TGZ_LIST) + printf(" date time size file\n" + " ---------- -------- --------- -------------------------------------\n"); + while (1) + { + len = gzread(in, &buffer, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + /* + * Always expect complete blocks to process + * the tar information. + */ + if (len != BLOCKSIZE) + { + action = TGZ_INVALID; /* force error exit */ + remaining = 0; /* force I/O cleanup */ + } + + /* + * If we have to get a tar header + */ + if (getheader >= 1) + { + /* + * if we met the end of the tar + * or the end-of-tar block, + * we are done + */ + if (len == 0 || buffer.header.name[0] == 0) + break; + + tarmode = getoct(buffer.header.mode,8); + tartime = (time_t)getoct(buffer.header.mtime,12); + if (tarmode == -1 || tartime == (time_t)-1) + { + buffer.header.name[0] = 0; + action = TGZ_INVALID; + } + + if (getheader == 1) + { + strncpy(fname,buffer.header.name,SHORTNAMESIZE); + if (fname[SHORTNAMESIZE-1] != 0) + fname[SHORTNAMESIZE] = 0; + } + else + { + /* + * The file name is longer than SHORTNAMESIZE + */ + if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0) + error("bad long name"); + getheader = 1; + } + + /* + * Act according to the type flag + */ + switch (buffer.header.typeflag) + { + case DIRTYPE: + if (action == TGZ_LIST) + printf(" %s %s\n",strtime(&tartime),fname); + if (action == TGZ_EXTRACT) + { + makedir(fname); + push_attr(&attributes,fname,tarmode,tartime); + } + break; + case REGTYPE: + case AREGTYPE: + remaining = getoct(buffer.header.size,12); + if (remaining == -1) + { + action = TGZ_INVALID; + break; + } + if (action == TGZ_LIST) + printf(" %s %9d %s\n",strtime(&tartime),remaining,fname); + else if (action == TGZ_EXTRACT) + { + if (matchname(arg,argc,argv,fname)) + { + outfile = fopen(fname,"wb"); + if (outfile == NULL) { + /* try creating directory */ + char *p = strrchr(fname, '/'); + if (p != NULL) { + *p = '\0'; + makedir(fname); + *p = '/'; + outfile = fopen(fname,"wb"); + } + } + if (outfile != NULL) + printf("Extracting %s\n",fname); + else + fprintf(stderr, "%s: Couldn't create %s",prog,fname); + } + else + outfile = NULL; + } + getheader = 0; + break; + case GNUTYPE_LONGLINK: + case GNUTYPE_LONGNAME: + remaining = getoct(buffer.header.size,12); + if (remaining < 0 || remaining >= BLOCKSIZE) + { + action = TGZ_INVALID; + break; + } + len = gzread(in, fname, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining) + { + action = TGZ_INVALID; + break; + } + getheader = 2; + break; + default: + if (action == TGZ_LIST) + printf(" %s <---> %s\n",strtime(&tartime),fname); + break; + } + } + else + { + unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; + + if (outfile != NULL) + { + if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) + { + fprintf(stderr, + "%s: Error writing %s -- skipping\n",prog,fname); + fclose(outfile); + outfile = NULL; + remove(fname); + } + } + remaining -= bytes; + } + + if (remaining == 0) + { + getheader = 1; + if (outfile != NULL) + { + fclose(outfile); + outfile = NULL; + if (action != TGZ_INVALID) + push_attr(&attributes,fname,tarmode,tartime); + } + } + + /* + * Abandon if errors are found + */ + if (action == TGZ_INVALID) + { + error("broken archive"); + break; + } + } + + /* + * Restore file modes and time stamps + */ + restore_attr(&attributes); + + if (gzclose(in) != Z_OK) + error("failed gzclose"); + + return 0; +} + + +/* ============================================================ */ + +void help(int exitval) +{ + printf("untgz version 0.2.1\n" + " using zlib version %s\n\n", + zlibVersion()); + printf("Usage: untgz file.tgz extract all files\n" + " untgz file.tgz fname ... extract selected files\n" + " untgz -l file.tgz list archive contents\n" + " untgz -h display this help\n"); + exit(exitval); +} + +void error(const char *msg) +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + + +/* ============================================================ */ + +#if defined(WIN32) && defined(__GNUC__) +int _CRT_glob = 0; /* disable argument globbing in MinGW */ +#endif + +int main(int argc,char **argv) +{ + int action = TGZ_EXTRACT; + int arg = 1; + char *TGZfile; + gzFile *f; + + prog = strrchr(argv[0],'\\'); + if (prog == NULL) + { + prog = strrchr(argv[0],'/'); + if (prog == NULL) + { + prog = strrchr(argv[0],':'); + if (prog == NULL) + prog = argv[0]; + else + prog++; + } + else + prog++; + } + else + prog++; + + if (argc == 1) + help(0); + + if (strcmp(argv[arg],"-l") == 0) + { + action = TGZ_LIST; + if (argc == ++arg) + help(0); + } + else if (strcmp(argv[arg],"-h") == 0) + { + help(0); + } + + if ((TGZfile = TGZfname(argv[arg])) == NULL) + TGZnotfound(argv[arg]); + + ++arg; + if ((action == TGZ_LIST) && (arg != argc)) + help(1); + +/* + * Process the TGZ file + */ + switch(action) + { + case TGZ_LIST: + case TGZ_EXTRACT: + f = gzopen(TGZfile,"rb"); + if (f == NULL) + { + fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile); + return 1; + } + exit(tar(f, action, arg, argc, argv)); + break; + + default: + error("Unknown option"); + exit(1); + } + + return 0; +} diff --git a/src/external/zlib-1.2.11/contrib/vstudio/readme.txt b/src/external/zlib-1.2.11/contrib/vstudio/readme.txt new file mode 100644 index 000000000..48cccc0d2 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/readme.txt @@ -0,0 +1,78 @@ +Building instructions for the DLL versions of Zlib 1.2.11 +======================================================== + +This directory contains projects that build zlib and minizip using +Microsoft Visual C++ 9.0/10.0. + +You don't need to build these projects yourself. You can download the +binaries from: + http://www.winimage.com/zLibDll + +More information can be found at this site. + + + + + +Build instructions for Visual Studio 2008 (32 bits or 64 bits) +-------------------------------------------------------------- +- Decompress current zlib, including all contrib/* files +- Compile assembly code (with Visual Studio Command Prompt) by running: + bld_ml64.bat (in contrib\masmx64) + bld_ml32.bat (in contrib\masmx86) +- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008 +- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32" + +Build instructions for Visual Studio 2010 (32 bits or 64 bits) +-------------------------------------------------------------- +- Decompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010 + +Build instructions for Visual Studio 2012 (32 bits or 64 bits) +-------------------------------------------------------------- +- Decompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc11\zlibvc.sln with Microsoft Visual C++ 2012 + +Build instructions for Visual Studio 2013 (32 bits or 64 bits) +-------------------------------------------------------------- +- Decompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc12\zlibvc.sln with Microsoft Visual C++ 2013 + +Build instructions for Visual Studio 2015 (32 bits or 64 bits) +-------------------------------------------------------------- +- Decompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc14\zlibvc.sln with Microsoft Visual C++ 2015 + + +Important +--------- +- To use zlibwapi.dll in your application, you must define the + macro ZLIB_WINAPI when compiling your application's source files. + + +Additional notes +---------------- +- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built + by Gilles Vollant from the zlib 1.1.x sources, and distributed at + http://www.winimage.com/zLibDll + It uses the WINAPI calling convention for the exported functions, and + includes the minizip functionality. If your application needs that + particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll. + +- The new DLL was renamed because there exist several incompatible + versions of zlib.dll on the Internet. + +- There is also an official DLL build of zlib, named zlib1.dll. This one + is exporting the functions using the CDECL convention. See the file + win32\DLL_FAQ.txt found in this zlib distribution. + +- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol + has a slightly different effect. To avoid compatibility problems, do + not define it here. + + +Gilles Vollant +info@winimage.com + +Visual Studio 2013 and 2015 Projects from Sean Hunt +seandhunt_7@yahoo.com diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/miniunz.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc10/miniunz.vcxproj new file mode 100644 index 000000000..1b3624215 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/miniunz.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/miniunz.vcxproj.filters b/src/external/zlib-1.2.11/contrib/vstudio/vc10/miniunz.vcxproj.filters new file mode 100644 index 000000000..0bd12210c --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/miniunz.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {048af943-022b-4db6-beeb-a54c34774ee2} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {c1d600d2-888f-4aea-b73e-8b0dd9befa0c} + h;hpp;hxx;hm;inl;inc + + + {0844199a-966b-4f19-81db-1e0125e141b9} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/minizip.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc10/minizip.vcxproj new file mode 100644 index 000000000..ccd3651df --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/minizip.vcxproj @@ -0,0 +1,307 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/minizip.vcxproj.filters b/src/external/zlib-1.2.11/contrib/vstudio/vc10/minizip.vcxproj.filters new file mode 100644 index 000000000..7076d76ff --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/minizip.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {c0419b40-bf50-40da-b153-ff74215b79de} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {bb87b070-735b-478e-92ce-7383abb2f36c} + h;hpp;hxx;hm;inl;inc + + + {f46ab6a6-548f-43cb-ae96-681abb5bd5db} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlib.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlib.vcxproj new file mode 100644 index 000000000..476b8ea45 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlib.vcxproj @@ -0,0 +1,420 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + true + + + Application + true + + + Application + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + EditAndContinue + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlib.vcxproj.filters b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlib.vcxproj.filters new file mode 100644 index 000000000..327649103 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlib.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {c1f6a2e3-5da5-4955-8653-310d3efe05a9} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {c2aaffdc-2c95-4d6f-8466-4bec5890af2c} + h;hpp;hxx;hm;inl;inc + + + {c274fe07-05f2-461c-964b-f6341e4e7eb5} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlibdll.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlibdll.vcxproj new file mode 100644 index 000000000..8e38876fa --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlibdll.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlibdll.vcxproj.filters b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlibdll.vcxproj.filters new file mode 100644 index 000000000..ab87f09f4 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/testzlibdll.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {fa61a89f-93fc-4c89-b29e-36224b7592f4} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {d4b85da0-2ba2-4934-b57f-e2584e3848ee} + h;hpp;hxx;hm;inl;inc + + + {e573e075-00bd-4a7d-bd67-a8cc9bfc5aca} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlib.rc b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlib.rc new file mode 100644 index 000000000..c4e4b016e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.11\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibstat.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibstat.vcxproj new file mode 100644 index 000000000..45389a352 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibstat.vcxproj @@ -0,0 +1,473 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebug + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibstat.vcxproj.filters b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibstat.vcxproj.filters new file mode 100644 index 000000000..0c8b2501c --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibstat.vcxproj.filters @@ -0,0 +1,77 @@ + + + + + {174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.def b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.def new file mode 100644 index 000000000..f876c3bca --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.def @@ -0,0 +1,153 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 + +; zlib1 v1.2.9 added: + inflateCodesUsed @168 + inflateValidate @169 + uncompress2 @170 + gzfread @171 + gzfwrite @172 + deflateGetDictionary @173 + adler32_z @174 + crc32_z @175 diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.sln b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.sln new file mode 100644 index 000000000..649f40c7e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.sln @@ -0,0 +1,135 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.vcxproj new file mode 100644 index 000000000..7d7c49a6d --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.vcxproj @@ -0,0 +1,657 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + zlibwapid + zlibwapi + zlibwapi + zlibwapid + zlibwapi + zlibwapi + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebug + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + true + .\zlibvc.def + true + true + Windows + false + + + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + true + false + .\zlibvc.def + true + Windows + false + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + true + false + .\zlibvc.def + true + Windows + false + + + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + true + .\zlibvc.def + true + true + Windows + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + true + false + .\zlibvc.def + true + Windows + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + true + false + .\zlibvc.def + true + Windows + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.vcxproj.filters b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.vcxproj.filters new file mode 100644 index 000000000..22786824f --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc10/zlibvc.vcxproj.filters @@ -0,0 +1,118 @@ + + + + + {07934a85-8b61-443d-a0ee-b2eedb74f3cd} + cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 + + + {1d99675b-433d-4a21-9e50-ed4ab8b19762} + h;hpp;hxx;hm;inl;fi;fd + + + {431c0958-fa71-44d0-9084-2d19d100c0cc} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/miniunz.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc11/miniunz.vcxproj new file mode 100644 index 000000000..99be63d69 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/miniunz.vcxproj @@ -0,0 +1,314 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + Application + MultiByte + v110 + + + Application + Unicode + v110 + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + v110 + + + Application + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/minizip.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc11/minizip.vcxproj new file mode 100644 index 000000000..d6e98f4d5 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/minizip.vcxproj @@ -0,0 +1,311 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + v110 + + + Application + Unicode + v110 + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + v110 + + + Application + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/testzlib.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc11/testzlib.vcxproj new file mode 100644 index 000000000..0115dd17b --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/testzlib.vcxproj @@ -0,0 +1,426 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + v110 + + + Application + MultiByte + true + v110 + + + Application + Unicode + v110 + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + true + v110 + + + Application + true + v110 + + + Application + v110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/testzlibdll.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc11/testzlibdll.vcxproj new file mode 100644 index 000000000..9d36336eb --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/testzlibdll.vcxproj @@ -0,0 +1,314 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + v110 + + + Application + Unicode + v110 + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + v110 + + + Application + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlib.rc b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlib.rc new file mode 100644 index 000000000..c4e4b016e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.11\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibstat.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibstat.vcxproj new file mode 100644 index 000000000..64b4d869d --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibstat.vcxproj @@ -0,0 +1,464 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + v110 + + + StaticLibrary + false + v110 + + + StaticLibrary + false + v110 + Unicode + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + v110 + + + StaticLibrary + false + v110 + + + StaticLibrary + false + v110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.def b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.def new file mode 100644 index 000000000..f876c3bca --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.def @@ -0,0 +1,153 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 + +; zlib1 v1.2.9 added: + inflateCodesUsed @168 + inflateValidate @169 + uncompress2 @170 + gzfread @171 + gzfwrite @172 + deflateGetDictionary @173 + adler32_z @174 + crc32_z @175 diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.sln b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.sln new file mode 100644 index 000000000..b7e381266 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.sln @@ -0,0 +1,117 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.vcxproj new file mode 100644 index 000000000..c4cffccf1 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc11/zlibvc.vcxproj @@ -0,0 +1,688 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + v110 + Unicode + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + true + v110 + + + DynamicLibrary + false + v110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\contrib\masmx64 +bld_ml64.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/miniunz.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc12/miniunz.vcxproj new file mode 100644 index 000000000..d88ac7fc7 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/miniunz.vcxproj @@ -0,0 +1,316 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + Application + MultiByte + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/minizip.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc12/minizip.vcxproj new file mode 100644 index 000000000..f1f239c9e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/minizip.vcxproj @@ -0,0 +1,313 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/testzlib.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc12/testzlib.vcxproj new file mode 100644 index 000000000..64b2cbe34 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/testzlib.vcxproj @@ -0,0 +1,430 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + v120 + + + Application + MultiByte + true + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + true + v120 + + + Application + MultiByte + true + v120 + + + Application + MultiByte + v120 + + + Application + true + v120 + + + Application + true + v120 + + + Application + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + false + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/testzlibdll.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc12/testzlibdll.vcxproj new file mode 100644 index 000000000..c66573a8b --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/testzlibdll.vcxproj @@ -0,0 +1,316 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlib.rc b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlib.rc new file mode 100644 index 000000000..c4e4b016e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.11\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibstat.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibstat.vcxproj new file mode 100644 index 000000000..3fdee7c50 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibstat.vcxproj @@ -0,0 +1,467 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + Unicode + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.def b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.def new file mode 100644 index 000000000..f876c3bca --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.def @@ -0,0 +1,153 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 + +; zlib1 v1.2.9 added: + inflateCodesUsed @168 + inflateValidate @169 + uncompress2 @170 + gzfread @171 + gzfwrite @172 + deflateGetDictionary @173 + adler32_z @174 + crc32_z @175 diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.sln b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.sln new file mode 100644 index 000000000..dcda22984 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.sln @@ -0,0 +1,119 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.vcxproj new file mode 100644 index 000000000..ab2b6c360 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc12/zlibvc.vcxproj @@ -0,0 +1,692 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + v120 + Unicode + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + v120 + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + false + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\contrib\masmx64 +bld_ml64.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/miniunz.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc14/miniunz.vcxproj new file mode 100644 index 000000000..9b5c07587 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/miniunz.vcxproj @@ -0,0 +1,316 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + Application + MultiByte + v140 + + + Application + Unicode + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/minizip.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc14/minizip.vcxproj new file mode 100644 index 000000000..968a410a1 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/minizip.vcxproj @@ -0,0 +1,313 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + v140 + + + Application + Unicode + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/testzlib.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc14/testzlib.vcxproj new file mode 100644 index 000000000..2c371252a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/testzlib.vcxproj @@ -0,0 +1,430 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + v140 + + + Application + MultiByte + true + v140 + + + Application + Unicode + v140 + + + Application + MultiByte + true + v140 + + + Application + MultiByte + true + v140 + + + Application + MultiByte + v140 + + + Application + true + v140 + + + Application + true + v140 + + + Application + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + false + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/testzlibdll.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc14/testzlibdll.vcxproj new file mode 100644 index 000000000..d87474dec --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/testzlibdll.vcxproj @@ -0,0 +1,316 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + v140 + + + Application + Unicode + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + Application + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlib.rc b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlib.rc new file mode 100644 index 000000000..c4e4b016e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.11\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibstat.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibstat.vcxproj new file mode 100644 index 000000000..3e4b98639 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibstat.vcxproj @@ -0,0 +1,467 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + Unicode + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + + + StaticLibrary + false + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.def b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.def new file mode 100644 index 000000000..f876c3bca --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.def @@ -0,0 +1,153 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 + +; zlib1 v1.2.9 added: + inflateCodesUsed @168 + inflateValidate @169 + uncompress2 @170 + gzfread @171 + gzfwrite @172 + deflateGetDictionary @173 + adler32_z @174 + crc32_z @175 diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.sln b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.sln new file mode 100644 index 000000000..6f4a1076a --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.sln @@ -0,0 +1,119 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.vcxproj b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.vcxproj new file mode 100644 index 000000000..f8f673cb0 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc14/zlibvc.vcxproj @@ -0,0 +1,692 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + + + + DynamicLibrary + false + true + v140 + + + DynamicLibrary + false + true + v140 + + + DynamicLibrary + false + v140 + Unicode + + + DynamicLibrary + false + true + v140 + + + DynamicLibrary + false + true + v140 + + + DynamicLibrary + false + v140 + + + DynamicLibrary + false + true + v140 + + + DynamicLibrary + false + true + v140 + + + DynamicLibrary + false + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + false + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\contrib\masmx64 +bld_ml64.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/miniunz.vcproj b/src/external/zlib-1.2.11/contrib/vstudio/vc9/miniunz.vcproj new file mode 100644 index 000000000..038a9e5fa --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/miniunz.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/minizip.vcproj b/src/external/zlib-1.2.11/contrib/vstudio/vc9/minizip.vcproj new file mode 100644 index 000000000..ad4023991 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/minizip.vcproj @@ -0,0 +1,562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/testzlib.vcproj b/src/external/zlib-1.2.11/contrib/vstudio/vc9/testzlib.vcproj new file mode 100644 index 000000000..c9f19d24e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/testzlib.vcproj @@ -0,0 +1,852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/testzlibdll.vcproj b/src/external/zlib-1.2.11/contrib/vstudio/vc9/testzlibdll.vcproj new file mode 100644 index 000000000..d7530fd7d --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/testzlibdll.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlib.rc b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlib.rc new file mode 100644 index 000000000..c4e4b016e --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.11\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibstat.vcproj b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibstat.vcproj new file mode 100644 index 000000000..d4ffb46b2 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibstat.vcproj @@ -0,0 +1,835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.def b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.def new file mode 100644 index 000000000..f876c3bca --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.def @@ -0,0 +1,153 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 + +; zlib1 v1.2.9 added: + inflateCodesUsed @168 + inflateValidate @169 + uncompress2 @170 + gzfread @171 + gzfwrite @172 + deflateGetDictionary @173 + adler32_z @174 + crc32_z @175 diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.sln b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.sln new file mode 100644 index 000000000..75c64c3f4 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.sln @@ -0,0 +1,144 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.vcproj b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.vcproj new file mode 100644 index 000000000..95bb241f3 --- /dev/null +++ b/src/external/zlib-1.2.11/contrib/vstudio/vc9/zlibvc.vcproj @@ -0,0 +1,1156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/crc32.c b/src/external/zlib-1.2.11/crc32.c new file mode 100644 index 000000000..9580440c0 --- /dev/null +++ b/src/external/zlib-1.2.11/crc32.c @@ -0,0 +1,442 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +/* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif +#ifdef BYFOUR + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, z_size_t)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, z_size_t)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local z_crc_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const z_crc_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + z_crc_t c; + int n, k; + z_crc_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (z_crc_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = ZSWAP32(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = ZSWAP32(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const z_crc_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const z_crc_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const z_crc_t FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32_z(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + z_size_t len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + z_crc_t endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + return crc32_z(crc, buf, len); +} + +#ifdef BYFOUR + +/* + This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit + integer pointer type. This violates the strict aliasing rule, where a + compiler can assume, for optimization purposes, that two pointers to + fundamentally different types won't ever point to the same memory. This can + manifest as a problem only if one of the pointers is written to. This code + only reads from those pointers. So long as this code remains isolated in + this compilation unit, there won't be a problem. For this reason, this code + should not be copied and pasted into a compilation unit in which other code + writes to the buffer that is passed to these routines. + */ + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + z_size_t len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *buf4++; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + z_size_t len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(ZSWAP32(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/src/external/zlib-1.2.11/crc32.h b/src/external/zlib-1.2.11/crc32.h new file mode 100644 index 000000000..9e0c77810 --- /dev/null +++ b/src/external/zlib-1.2.11/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/src/external/zlib-1.2.11/deflate.c b/src/external/zlib-1.2.11/deflate.c new file mode 100644 index 000000000..1ec761448 --- /dev/null +++ b/src/external/zlib-1.2.11/deflate.c @@ -0,0 +1,2163 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local int deflateStateCheck OF((z_streamp strm)); +local void slide_hash OF((deflate_state *s)); +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV +# pragma message("Assembler code may have bugs -- use at your own risk") + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef ZLIB_DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +local void slide_hash(s) + deflate_state *s; +{ + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = (uInt)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = (uInt)memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck (strm) + z_streamp strm; +{ + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) + z_streamp strm; + Bytef *dictionary; + uInt *dictLength; +{ + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + s->high_water) { + /* Flush the last buffer: */ + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_out == 0) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (uInt)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (deflateStateCheck(strm)) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE) { + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (deflateStateCheck(source) || dest == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = (int)s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* ZLIB_DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + } + else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + } + s->block_start = s->strstart; + s->insert += MIN(used, s->w_size - s->insert); + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart - 1; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + } + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (uInt)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/src/external/zlib-1.2.11/deflate.h b/src/external/zlib-1.2.11/deflate.h new file mode 100644 index 000000000..23ecdd312 --- /dev/null +++ b/src/external/zlib-1.2.11/deflate.h @@ -0,0 +1,349 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + ulg pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + ulg gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef ZLIB_DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef ZLIB_DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/src/external/zlib-1.2.11/doc/algorithm.txt b/src/external/zlib-1.2.11/doc/algorithm.txt new file mode 100644 index 000000000..c97f49502 --- /dev/null +++ b/src/external/zlib-1.2.11/doc/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend too much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://tools.ietf.org/html/rfc1951 diff --git a/src/external/zlib-1.2.11/doc/rfc1950.txt b/src/external/zlib-1.2.11/doc/rfc1950.txt new file mode 100644 index 000000000..ce6428a0f --- /dev/null +++ b/src/external/zlib-1.2.11/doc/rfc1950.txt @@ -0,0 +1,619 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1950 Aladdin Enterprises +Category: Informational J-L. Gailly + Info-ZIP + May 1996 + + + ZLIB Compressed Data Format Specification version 3.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format. The + data can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a priori + bounded amount of intermediate storage. The format presently uses + the DEFLATE compression method but can be easily extended to use + other compression methods. It can be implemented readily in a manner + not covered by patents. This specification also defines the ADLER-32 + checksum (an extension and improvement of the Fletcher checksum), + used for detection of data corruption, and provides an algorithm for + computing it. + + + + +Deutsch & Gailly Informational [Page 1] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 3 + 2.1. Overall conventions ....................................... 3 + 2.2. Data format ............................................... 4 + 2.3. Compliance ................................................ 7 + 3. References ..................................................... 7 + 4. Source code .................................................... 8 + 5. Security Considerations ........................................ 8 + 6. Acknowledgements ............................................... 8 + 7. Authors' Addresses ............................................. 8 + 8. Appendix: Rationale ............................................ 9 + 9. Appendix: Sample code ..........................................10 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence can + be used in data communications or similar structures such as + Unix filters; + + * Can use a number of different compression methods; + + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely. + + The data format defined by this specification does not attempt to + allow random access to compressed data. + + + + + + + +Deutsch & Gailly Informational [Page 2] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into zlib format and/or decompress data from zlib + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compressed data format that can be + used for in-memory compression of a sequence of arbitrary bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below, for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + Version 3.1 was the first public release of this specification. + In version 3.2, some terminology was changed and the Adler-32 + sample code was rewritten for clarity. In version 3.3, the + support for a preset dictionary was introduced, and the + specification was converted to RFC style. + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + + + +Deutsch & Gailly Informational [Page 3] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the MOST-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00000010|00001000| + +--------+--------+ + ^ ^ + | | + | + less significant byte = 8 + + more significant byte = 2 x 256 + + 2.2. Data format + + A zlib stream has the following structure: + + 0 1 + +---+---+ + |CMF|FLG| (more-->) + +---+---+ + + + + + + + + +Deutsch & Gailly Informational [Page 4] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + (if FLG.FDICT set) + + 0 1 2 3 + +---+---+---+---+ + | DICTID | (more-->) + +---+---+---+---+ + + +=====================+---+---+---+---+ + |...compressed data...| ADLER32 | + +=====================+---+---+---+---+ + + Any data which may appear after ADLER32 are not part of the zlib + stream. + + CMF (Compression Method and flags) + This byte is divided into a 4-bit compression method and a 4- + bit information field depending on the compression method. + + bits 0 to 3 CM Compression method + bits 4 to 7 CINFO Compression info + + CM (Compression method) + This identifies the compression method used in the file. CM = 8 + denotes the "deflate" compression method with a window size up + to 32K. This is the method used by gzip and PNG (see + references [1] and [2] in Chapter 3, below, for the reference + documents). CM = 15 is reserved. It might be used in a future + version of this specification to indicate the presence of an + extra field before the compressed data. + + CINFO (Compression info) + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window + size, minus eight (CINFO=7 indicates a 32K window size). Values + of CINFO above 7 are not allowed in this version of the + specification. CINFO is not defined in this specification for + CM not equal to 8. + + FLG (FLaGs) + This flag byte is divided as follows: + + bits 0 to 4 FCHECK (check bits for CMF and FLG) + bit 5 FDICT (preset dictionary) + bits 6 to 7 FLEVEL (compression level) + + The FCHECK value must be such that CMF and FLG, when viewed as + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + is a multiple of 31. + + + + +Deutsch & Gailly Informational [Page 5] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + FDICT (Preset dictionary) + If FDICT is set, a DICT dictionary identifier is present + immediately after the FLG byte. The dictionary is a sequence of + bytes which are initially fed to the compressor without + producing any compressed output. DICT is the Adler-32 checksum + of this sequence of bytes (see the definition of ADLER32 + below). The decompressor can use this identifier to determine + which dictionary has been used by the compressor. + + FLEVEL (Compression level) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + 0 - compressor used fastest algorithm + 1 - compressor used fast algorithm + 2 - compressor used default algorithm + 3 - compressor used maximum compression, slowest algorithm + + The information in FLEVEL is not needed for decompression; it + is there to indicate if recompression might be worthwhile. + + compressed data + For compression method 8, the compressed data is stored in the + deflate compressed data format as described in the document + "DEFLATE Compressed Data Format Specification" by L. Peter + Deutsch. (See reference [3] in Chapter 3, below) + + Other compressed data formats are not specified in this version + of the zlib specification. + + ADLER32 (Adler-32 checksum) + This contains a checksum value of the uncompressed data + (excluding any dictionary data) computed according to Adler-32 + algorithm. This algorithm is a 32-bit extension and improvement + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + standard. See references [4] and [5] in Chapter 3, below) + + Adler-32 is composed of two sums accumulated per byte: s1 is + the sum of all bytes, s2 is the sum of all s1 values. Both sums + are done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in most- + significant-byte first (network) order. + + + + + + + + +Deutsch & Gailly Informational [Page 6] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 2.3. Compliance + + A compliant compressor must produce streams with correct CMF, FLG + and ADLER32, but need not support preset dictionaries. When the + zlib data format is used as part of another standard data format, + the compressor may use only preset dictionaries that are specified + by this other data format. If this other format does not use the + preset dictionary feature, the compressor must not set the FDICT + flag. + + A compliant decompressor must check CMF, FLG, and ADLER32, and + provide an error indication if any of these have incorrect values. + A compliant decompressor must give an error indication if CM is + not one of the values defined in this specification (only the + value 8 is permitted in this version), since another value could + indicate the presence of new features that would cause subsequent + data to be interpreted incorrectly. A compliant decompressor must + give an error indication if FDICT is set and DICTID is not the + identifier of a known preset dictionary. A decompressor may + ignore FLEVEL and still be compliant. When the zlib data format + is being used as a part of another standard format, a compliant + decompressor must support all the preset dictionaries specified by + the other format. When the other format does not use the preset + dictionary feature, a compliant decompressor must reject any + stream in which the FDICT flag is set. + +3. References + + [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", + available in ftp://ftp.uu.net/graphics/png/documents/ + + [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Fletcher, J. G., "An Arithmetic Checksum for Serial + Transmissions," IEEE Transactions on Communications, Vol. COM-30, + No. 1, January 1982, pp. 247-252. + + [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," + November, 1993, pp. 144, 145. (Available from + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. + + + + + + + +Deutsch & Gailly Informational [Page 7] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +4. Source code + + Source code for a C language implementation of a "zlib" compliant + library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +5. Security Considerations + + A decoder that fails to check the ADLER32 checksum value may be + subject to undetected data corruption. + +6. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +7. Authors' Addresses + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + + Jean-Loup Gailly + + EMail: + + Questions about the technical content of this specification can be + sent by email to + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + +Deutsch & Gailly Informational [Page 8] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +8. Appendix: Rationale + + 8.1. Preset dictionaries + + A preset dictionary is specially useful to compress short input + sequences. The compressor can take advantage of the dictionary + context to encode the input in a more compact manner. The + decompressor can be initialized with the appropriate context by + virtually decompressing a compressed version of the dictionary + without producing any output. However for certain compression + algorithms such as the deflate algorithm this operation can be + achieved without actually performing any decompression. + + The compressor and the decompressor must use exactly the same + dictionary. The dictionary may be fixed or may be chosen among a + certain number of predefined dictionaries, according to the kind + of input data. The decompressor can determine which dictionary has + been chosen by the compressor by checking the dictionary + identifier. This document does not specify the contents of + predefined dictionaries, since the optimal dictionaries are + application specific. Standard data formats using this feature of + the zlib specification must precisely define the allowed + dictionaries. + + 8.2. The Adler-32 algorithm + + The Adler-32 algorithm is much faster than the CRC32 algorithm yet + still provides an extremely low probability of undetected errors. + + The modulo on unsigned long accumulators can be delayed for 5552 + bytes, so the modulo operation time is negligible. If the bytes + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + and order sensitive, unlike the first sum, which is just a + checksum. That 65521 is prime is important to avoid a possible + large class of two-byte errors that leave the check unchanged. + (The Fletcher checksum uses 255, which is not prime and which also + makes the Fletcher check insensitive to single byte changes 0 <-> + 255.) + + The sum s1 is initialized to 1 instead of zero to make the length + of the sequence part of s2, so that the length does not have to be + checked separately. (Any sequence of zeroes has a Fletcher + checksum of zero.) + + + + + + + + +Deutsch & Gailly Informational [Page 9] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +9. Appendix: Sample code + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + #define BASE 65521 /* largest prime smaller than 65536 */ + + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + + + + +Deutsch & Gailly Informational [Page 10] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch & Gailly Informational [Page 11] + diff --git a/src/external/zlib-1.2.11/doc/rfc1951.txt b/src/external/zlib-1.2.11/doc/rfc1951.txt new file mode 100644 index 000000000..403c8c722 --- /dev/null +++ b/src/external/zlib-1.2.11/doc/rfc1951.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1951 Aladdin Enterprises +Category: Informational May 1996 + + + DEFLATE Compressed Data Format Specification version 1.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. The data can be produced or + consumed, even for an arbitrarily long sequentially presented input + data stream, using only an a priori bounded amount of intermediate + storage. The format can be implemented readily in a manner not + covered by patents. + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 4 + 2. Compressed representation overview ............................. 4 + 3. Detailed specification ......................................... 5 + 3.1. Overall conventions ....................................... 5 + 3.1.1. Packing into bytes .................................. 5 + 3.2. Compressed block format ................................... 6 + 3.2.1. Synopsis of prefix and Huffman coding ............... 6 + 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 + 3.2.3. Details of block format ............................. 9 + 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 + 3.2.5. Compressed blocks (length and distance codes) ...... 11 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 + 3.3. Compliance ............................................... 14 + 4. Compression algorithm details ................................. 14 + 5. References .................................................... 16 + 6. Security Considerations ....................................... 16 + 7. Source code ................................................... 16 + 8. Acknowledgements .............................................. 16 + 9. Author's Address .............................................. 17 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures + such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + + + +Deutsch Informational [Page 2] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + + A simple counting argument shows that no lossless compression + algorithm can compress every possible input data set. For the + format defined here, the worst case expansion is 5 bytes per 32K- + byte block, i.e., a size increase of 0.015% for large data sets. + English text usually compresses by a factor of 2.5 to 3; + executable files usually compress somewhat less; graphical data + such as raster images may compress much more. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into "deflate" format and/or decompress data from + "deflate" format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding + is helpful but not required. + + 1.3. Scope + + The specification specifies a method for representing a sequence + of bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). + For this specification, a byte is exactly 8 bits, even on machines + + + +Deutsch Informational [Page 3] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + which store a character on a number of bits different from eight. + See below, for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + 1.6. Changes from previous versions + + There have been no technical changes to the deflate format since + version 1.1 of this specification. In version 1.2, some + terminology was changed. Version 1.3 is a conversion of the + specification to RFC style. + +2. Compressed representation overview + + A compressed data set consists of a series of blocks, corresponding + to successive blocks of input data. The block sizes are arbitrary, + except that non-compressible blocks are limited to 65,535 bytes. + + Each block is compressed using a combination of the LZ77 algorithm + and Huffman coding. The Huffman trees for each block are independent + of those for previous or subsequent blocks; the LZ77 algorithm may + use a reference to a duplicated string occurring in a previous block, + up to 32K input bytes before. + + Each block consists of two parts: a pair of Huffman code trees that + describe the representation of the compressed data part, and a + compressed data part. (The Huffman trees themselves are compressed + using Huffman encoding.) The compressed data consists of a series of + elements of two types: literal bytes (of strings that have not been + detected as duplicated within the previous 32K input bytes), and + pointers to duplicated strings, where a pointer is represented as a + pair . The representation used in the + "deflate" format limits distances to 32K bytes and lengths to 258 + bytes, but does not limit the size of a block, except for + uncompressible blocks, which are limited as noted above. + + Each type of value (literals, distances, and lengths) in the + compressed data is represented using a Huffman code, using one code + tree for literals and lengths and a separate code tree for distances. + The code trees for each block appear in a compact form just before + the compressed data for that block. + + + + + + + + + + +Deutsch Informational [Page 4] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +3. Detailed specification + + 3.1. Overall conventions In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + 3.1.1. Packing into bytes + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, + since the final data format described here is byte- rather than + + + +Deutsch Informational [Page 5] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + bit-oriented. However, we describe the compressed block format + in below, as a sequence of data elements of various bit + lengths, not a sequence of bytes. We must therefore specify + how to pack these data elements into bytes to form the final + compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than Huffman codes are packed + starting with the least-significant bit of the data + element. + * Huffman codes are packed starting with the most- + significant bit of the code. + + In other words, if one were to print out the compressed data as + a sequence of bytes, starting with the first byte at the + *right* margin and proceeding to the *left*, with the most- + significant bit of each byte on the left as usual, one would be + able to parse the result from right to left, with fixed-width + elements in the correct MSB-to-LSB order and Huffman codes in + bit-reversed order (i.e., with the first bit of the code in the + relative LSB position). + + 3.2. Compressed block format + + 3.2.1. Synopsis of prefix and Huffman coding + + Prefix coding represents symbols from an a priori known + alphabet by bit sequences (codes), one code for each symbol, in + a manner such that different symbols may be represented by bit + sequences of different lengths, but a parser can always parse + an encoded string unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the + two edges descending from each non-leaf node are labeled 0 and + 1 and in which the leaf nodes correspond one-for-one with (are + labeled with) the symbols of the alphabet; then the code for a + symbol is the sequence of 0's and 1's on the edges leading from + the root to the leaf labeled with that symbol. For example: + + + + + + + + + + + +Deutsch Informational [Page 6] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from an encoded input + stream by walking down the tree from the root, at each step + choosing the edge corresponding to the next input bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code + (one which represents strings with those symbol frequencies + using the fewest bits of any possible prefix codes for that + alphabet). Such a code is called a Huffman code. (See + reference [1] in Chapter 5, references for additional + information on Huffman codes.) + + Note that in the "deflate" format, the Huffman codes for the + various alphabets must not exceed certain maximum code lengths. + This constraint complicates the algorithm for computing code + lengths from symbol frequencies. Again, see Chapter 5, + references for details. + + 3.2.2. Use of Huffman coding in the "deflate" format + + The Huffman codes used for each alphabet in the "deflate" + format have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols + they represent; + + * Shorter codes lexicographically precede longer codes. + + + + + + + + + + + + +Deutsch Informational [Page 7] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + We could recode the example above to follow this rule as + follows, assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the Huffman code for an alphabet + just by giving the bit lengths of the codes for each symbol of + the alphabet in order; this is sufficient to determine the + actual codes. In our example, the code is completely defined + by the sequence of bit lengths (2, 1, 3, 3). The following + algorithm generates the codes as integers, intended to be read + from most- to least-significant bit. The code lengths are + initially in tree[I].Len; the codes are produced in + tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + + + +Deutsch Informational [Page 8] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, + 3, 2, 4, 4). After step 1, we have: + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + + 3.2.3. Details of block format + + Each block of compressed data begins with 3 header bits + containing the following data: + + first bit BFINAL + next 2 bits BTYPE + + Note that the header bits do not necessarily begin on a byte + boundary, since a block does not necessarily occupy an integral + number of bytes. + + + + + +Deutsch Informational [Page 9] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + BFINAL is set if and only if this is the last block of the data + set. + + BTYPE specifies how the data are compressed, as follows: + + 00 - no compression + 01 - compressed with fixed Huffman codes + 10 - compressed with dynamic Huffman codes + 11 - reserved (error) + + The only difference between the two compressed cases is how the + Huffman codes for the literal/length and distance alphabets are + defined. + + In all cases, the decoding algorithm for the actual data is as + follows: + + do + read block header from input stream. + if stored with no compression + skip any remaining bits in current partially + processed byte + read LEN and NLEN (see next section) + copy LEN bytes of data to output + otherwise + if compressed with dynamic Huffman codes + read representation of code trees (see + subsection below) + loop (until end of block code recognized) + decode literal/length value from input stream + if value < 256 + copy value (literal byte) to output stream + otherwise + if value = end of block (256) + break from loop + otherwise (value = 257..285) + decode distance from input stream + + move backwards distance bytes in the output + stream, and copy length bytes from this + position to the output stream. + end loop + while not last block + + Note that a duplicated string reference may refer to a string + in a previous block; i.e., the backward distance may cross one + or more block boundaries. However a distance cannot refer past + the beginning of the output stream. (An application using a + + + +Deutsch Informational [Page 10] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + preset dictionary might discard part of the output stream; a + distance can refer to that part of the output stream anyway) + Note also that the referenced string may overlap the current + position; for example, if the last 2 bytes decoded have values + X and Y, a string reference with + adds X,Y,X,Y,X to the output stream. + + We now specify each compression method in turn. + + 3.2.4. Non-compressed blocks (BTYPE=00) + + Any bits of input up to the next byte boundary are ignored. + The rest of the block consists of the following information: + + 0 1 2 3 4... + +---+---+---+---+================================+ + | LEN | NLEN |... LEN bytes of literal data...| + +---+---+---+---+================================+ + + LEN is the number of data bytes in the block. NLEN is the + one's complement of LEN. + + 3.2.5. Compressed blocks (length and distance codes) + + As noted above, encoded data blocks in the "deflate" format + consist of sequences of symbols drawn from three conceptually + distinct alphabets: either literal bytes, from the alphabet of + byte values (0..255), or pairs, + where the length is drawn from (3..258) and the distance is + drawn from (1..32,768). In fact, the literal and length + alphabets are merged into a single alphabet (0..285), where + values 0..255 represent literal bytes, the value 256 indicates + end-of-block, and values 257..285 represent length codes + (possibly in conjunction with extra bits following the symbol + code) as follows: + + + + + + + + + + + + + + + + +Deutsch Informational [Page 11] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + Extra Extra Extra + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 257 0 3 267 1 15,16 277 4 67-82 + 258 0 4 268 1 17,18 278 4 83-98 + 259 0 5 269 2 19-22 279 4 99-114 + 260 0 6 270 2 23-26 280 4 115-130 + 261 0 7 271 2 27-30 281 5 131-162 + 262 0 8 272 2 31-34 282 5 163-194 + 263 0 9 273 3 35-42 283 5 195-226 + 264 0 10 274 3 43-50 284 5 227-257 + 265 1 11,12 275 3 51-58 285 0 258 + 266 1 13,14 276 3 59-66 + + The extra bits should be interpreted as a machine integer + stored with the most-significant bit first, e.g., bits 1110 + represent the value 14. + + Extra Extra Extra + Code Bits Dist Code Bits Dist Code Bits Distance + ---- ---- ---- ---- ---- ------ ---- ---- -------- + 0 0 1 10 4 33-48 20 9 1025-1536 + 1 0 2 11 4 49-64 21 9 1537-2048 + 2 0 3 12 5 65-96 22 10 2049-3072 + 3 0 4 13 5 97-128 23 10 3073-4096 + 4 1 5,6 14 6 129-192 24 11 4097-6144 + 5 1 7,8 15 6 193-256 25 11 6145-8192 + 6 2 9-12 16 7 257-384 26 12 8193-12288 + 7 2 13-16 17 7 385-512 27 12 12289-16384 + 8 3 17-24 18 8 513-768 28 13 16385-24576 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 + + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) + + The Huffman codes for the two alphabets are fixed, and are not + represented explicitly in the data. The Huffman code lengths + for the literal/length alphabet are: + + Lit Value Bits Codes + --------- ---- ----- + 0 - 143 8 00110000 through + 10111111 + 144 - 255 9 110010000 through + 111111111 + 256 - 279 7 0000000 through + 0010111 + 280 - 287 8 11000000 through + 11000111 + + + +Deutsch Informational [Page 12] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + The code lengths are sufficient to generate the actual codes, + as described above; we show the codes in the table for added + clarity. Literal/length values 286-287 will never actually + occur in the compressed data, but participate in the code + construction. + + Distance codes 0-31 are represented by (fixed-length) 5-bit + codes, with possible additional bits as shown in the table + shown in Paragraph 3.2.5, above. Note that distance codes 30- + 31 will never actually occur in the compressed data. + + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) + + The Huffman codes for the two alphabets appear in the block + immediately after the header bits and before the actual + compressed data, first the literal/length code and then the + distance code. Each code is defined by a sequence of code + lengths, as discussed in Paragraph 3.2.2, above. For even + greater compactness, the code length sequences themselves are + compressed using a Huffman code. The alphabet for code lengths + is as follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous code length 3 - 6 times. + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + Example: Codes 8, 16 (+2 bits 11), + 16 (+2 bits 10) will expand to + 12 code lengths of 8 (1 + 6 + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + 18: Repeat a code length of 0 for 11 - 138 times + (7 bits of length) + + A code length of 0 indicates that the corresponding symbol in + the literal/length or distance alphabet will not occur in the + block, and should not participate in the Huffman code + construction algorithm given earlier. If only one distance + code is used, it is encoded using one bit, not zero bits; in + this case there is a single code length of one, with one unused + code. One distance code of zero bits means that there are no + distance codes used at all (the data is all literals). + + We can now define the format of the block: + + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) + + + +Deutsch Informational [Page 13] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + (HCLEN + 4) x 3 bits: code lengths for the code length + alphabet given just above, in the order: 16, 17, 18, + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + + These code lengths are interpreted as 3-bit integers + (0-7); as above, a code length of 0 means the + corresponding symbol (literal/length or distance code + length) is not used. + + HLIT + 257 code lengths for the literal/length alphabet, + encoded using the code length Huffman code + + HDIST + 1 code lengths for the distance alphabet, + encoded using the code length Huffman code + + The actual compressed data of the block, + encoded using the literal/length and distance Huffman + codes + + The literal/length symbol 256 (end of data), + encoded using the literal/length Huffman code + + The code length repeat codes can cross from HLIT + 257 to the + HDIST + 1 code lengths. In other words, all code lengths form + a single sequence of HLIT + HDIST + 258 values. + + 3.3. Compliance + + A compressor may limit further the ranges of values specified in + the previous section and still be compliant; for example, it may + limit the range of backward pointers to some value smaller than + 32K. Similarly, a compressor may limit the size of blocks so that + a compressible block fits in memory. + + A compliant decompressor must accept the full range of possible + values defined in the previous section, and must accept blocks of + arbitrary size. + +4. Compression algorithm details + + While it is the intent of this document to define the "deflate" + compressed data format without reference to any particular + compression algorithm, the format is related to the compressed + formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); + since many variations of LZ77 are patented, it is strongly + recommended that the implementor of a compressor follow the general + algorithm presented here, which is known not to be patented per se. + The material in this section is not part of the definition of the + + + +Deutsch Informational [Page 14] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + specification per se, and a compressor need not follow it in order to + be compliant. + + The compressor terminates a block when it determines that starting a + new block with fresh trees would be useful, or when the block size + fills up the compressor's block buffer. + + The compressor uses a chained hash table to find duplicated strings, + using a hash function that operates on 3-byte sequences. At any + given point during compression, let XYZ be the next 3 input bytes to + be examined (not necessarily all different, of course). First, the + compressor examines the hash chain for XYZ. If the chain is empty, + the compressor simply writes out X as a literal byte and advances one + byte in the input. If the hash chain is not empty, indicating that + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the + same hash function value) has occurred recently, the compressor + compares all strings on the XYZ hash chain with the actual input data + sequence starting at the current point, and selects the longest + match. + + The compressor searches the hash chains starting with the most recent + strings, to favor small distances and thus take advantage of the + Huffman encoding. The hash chains are singly linked. There are no + deletions from the hash chains; the algorithm simply discards matches + that are too old. To avoid a worst-case situation, very long hash + chains are arbitrarily truncated at a certain length, determined by a + run-time parameter. + + To improve overall compression, the compressor optionally defers the + selection of matches ("lazy matching"): after a match of length N has + been found, the compressor searches for a longer match starting at + the next input byte. If it finds a longer match, it truncates the + previous match to a length of one (thus producing a single literal + byte) and then emits the longer match. Otherwise, it emits the + original match, and, as described above, advances N bytes before + continuing. + + Run-time parameters also control this "lazy match" procedure. If + compression ratio is most important, the compressor attempts a + complete second search regardless of the length of the first match. + In the normal case, if the current match is "long enough", the + compressor reduces the search for a longer match, thus speeding up + the process. If speed is most important, the compressor inserts new + strings in the hash table only when no match was found, or when the + match is not "too long". This degrades the compression ratio but + saves time since there are both fewer insertions and fewer searches. + + + + + +Deutsch Informational [Page 15] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +5. References + + [1] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + + [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data + Compression", IEEE Transactions on Information Theory, Vol. 23, + No. 3, pp. 337-343. + + [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, + available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ + + [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix + encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. + + [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," + Comm. ACM, 33,4, April 1990, pp. 449-459. + +6. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data. See + reference [3], for example. + +7. Source code + + Source code for a C language implementation of a "deflate" compliant + compressor and decompressor is available within the zlib package at + ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +8. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark + Adler wrote the related software described in this specification. + Glenn Randers-Pehrson converted this document to RFC and HTML format. + + + +Deutsch Informational [Page 16] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +9. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch Informational [Page 17] + diff --git a/src/external/zlib-1.2.11/doc/rfc1952.txt b/src/external/zlib-1.2.11/doc/rfc1952.txt new file mode 100644 index 000000000..a8e51b456 --- /dev/null +++ b/src/external/zlib-1.2.11/doc/rfc1952.txt @@ -0,0 +1,675 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1952 Aladdin Enterprises +Category: Informational May 1996 + + + GZIP file format specification version 4.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that is + compatible with the widely used GZIP utility. The format includes a + cyclic redundancy check value for detecting data corruption. The + format presently uses the DEFLATE method of compression but can be + easily extended to use other compression methods. The format can be + implemented readily in a manner not covered by patents. + + + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1952 GZIP File Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................. 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 4 + 2.1. Overall conventions ....................................... 4 + 2.2. File format ............................................... 5 + 2.3. Member format ............................................. 5 + 2.3.1. Member header and trailer ........................... 6 + 2.3.1.1. Extra field ................................... 8 + 2.3.1.2. Compliance .................................... 9 + 3. References .................................................. 9 + 4. Security Considerations .................................... 10 + 5. Acknowledgements ........................................... 10 + 6. Author's Address ........................................... 10 + 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 + 8. Appendix: Sample CRC Code .................................. 11 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can compress or decompress a data stream (as opposed to a + randomly accessible file) to produce another data stream, + using only an a priori bounded amount of intermediate + storage, and hence can be used in data communications or + similar structures such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + + + +Deutsch Informational [Page 2] + +RFC 1952 GZIP File Format Specification May 1996 + + + The data format defined by this specification does not attempt to: + + * Provide random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well as + the best currently available specialized algorithms. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into gzip format and/or decompress data from gzip + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compression method and a file format + (the latter assuming only that a file can store a sequence of + arbitrary bytes). It does not specify any particular interface to + a file system or anything about character sets or encodings + (except for file names and comments, which are optional). + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any file that conforms to all the + specifications presented here; a compliant compressor must produce + files that conform to all the specifications presented here. The + material in the appendices is not part of the specification per se + and is not relevant to compliance. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + There have been no technical changes to the gzip format since + version 4.1 of this specification. In version 4.2, some + terminology was changed, and the sample CRC code was rewritten for + clarity and to eliminate the requirement for the caller to do pre- + and post-conditioning. Version 4.3 is a conversion of the + specification to RFC style. + + + +Deutsch Informational [Page 3] + +RFC 1952 GZIP File Format Specification May 1996 + + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, since + the data format described here is byte- rather than bit-oriented. + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + + +Deutsch Informational [Page 4] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.2. File format + + A gzip file consists of a series of "members" (compressed data + sets). The format of each member is specified in the following + section. The members simply appear one after another in the file, + with no additional information before, between, or after them. + + 2.3. Member format + + Each member has the following structure: + + +---+---+---+---+---+---+---+---+---+---+ + |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) + +---+---+---+---+---+---+---+---+---+---+ + + (if FLG.FEXTRA set) + + +---+---+=================================+ + | XLEN |...XLEN bytes of "extra field"...| (more-->) + +---+---+=================================+ + + (if FLG.FNAME set) + + +=========================================+ + |...original file name, zero-terminated...| (more-->) + +=========================================+ + + (if FLG.FCOMMENT set) + + +===================================+ + |...file comment, zero-terminated...| (more-->) + +===================================+ + + (if FLG.FHCRC set) + + +---+---+ + | CRC16 | + +---+---+ + + +=======================+ + |...compressed blocks...| (more-->) + +=======================+ + + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | CRC32 | ISIZE | + +---+---+---+---+---+---+---+---+ + + + + +Deutsch Informational [Page 5] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.3.1. Member header and trailer + + ID1 (IDentification 1) + ID2 (IDentification 2) + These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 + (0x8b, \213), to identify the file as being in gzip format. + + CM (Compression Method) + This identifies the compression method used in the file. CM + = 0-7 are reserved. CM = 8 denotes the "deflate" + compression method, which is the one customarily used by + gzip and which is documented elsewhere. + + FLG (FLaGs) + This flag byte is divided into individual bits as follows: + + bit 0 FTEXT + bit 1 FHCRC + bit 2 FEXTRA + bit 3 FNAME + bit 4 FCOMMENT + bit 5 reserved + bit 6 reserved + bit 7 reserved + + If FTEXT is set, the file is probably ASCII text. This is + an optional indication, which the compressor may set by + checking a small amount of the input data to see whether any + non-ASCII characters are present. In case of doubt, FTEXT + is cleared, indicating binary data. For systems which have + different file formats for ascii text and binary data, the + decompressor can use FTEXT to choose the appropriate format. + We deliberately do not specify the algorithm used to set + this bit, since a compressor always has the option of + leaving it cleared and a decompressor always has the option + of ignoring it and letting some other program handle issues + of data conversion. + + If FHCRC is set, a CRC16 for the gzip header is present, + immediately before the compressed data. The CRC16 consists + of the two least significant bytes of the CRC32 for all + bytes of the gzip header up to and not including the CRC16. + [The FHCRC bit was never set by versions of gzip up to + 1.2.4, even though it was documented with a different + meaning in gzip 1.2.4.] + + If FEXTRA is set, optional extra fields are present, as + described in a following section. + + + +Deutsch Informational [Page 6] + +RFC 1952 GZIP File Format Specification May 1996 + + + If FNAME is set, an original file name is present, + terminated by a zero byte. The name must consist of ISO + 8859-1 (LATIN-1) characters; on operating systems using + EBCDIC or any other character set for file names, the name + must be translated to the ISO LATIN-1 character set. This + is the original name of the file being compressed, with any + directory components removed, and, if the file being + compressed is on a file system with case insensitive names, + forced to lower case. There is no original file name if the + data was compressed from a source other than a named file; + for example, if the source was stdin on a Unix system, there + is no file name. + + If FCOMMENT is set, a zero-terminated file comment is + present. This comment is not interpreted; it is only + intended for human consumption. The comment must consist of + ISO 8859-1 (LATIN-1) characters. Line breaks should be + denoted by a single line feed character (10 decimal). + + Reserved FLG bits must be zero. + + MTIME (Modification TIME) + This gives the most recent modification time of the original + file being compressed. The time is in Unix format, i.e., + seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this + may cause problems for MS-DOS and other systems that use + local rather than Universal time.) If the compressed data + did not come from a file, MTIME is set to the time at which + compression started. MTIME = 0 means no time stamp is + available. + + XFL (eXtra FLags) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + XFL = 2 - compressor used maximum compression, + slowest algorithm + XFL = 4 - compressor used fastest algorithm + + OS (Operating System) + This identifies the type of file system on which compression + took place. This may be useful in determining end-of-line + convention for text files. The currently defined values are + as follows: + + + + + + +Deutsch Informational [Page 7] + +RFC 1952 GZIP File Format Specification May 1996 + + + 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + 1 - Amiga + 2 - VMS (or OpenVMS) + 3 - Unix + 4 - VM/CMS + 5 - Atari TOS + 6 - HPFS filesystem (OS/2, NT) + 7 - Macintosh + 8 - Z-System + 9 - CP/M + 10 - TOPS-20 + 11 - NTFS filesystem (NT) + 12 - QDOS + 13 - Acorn RISCOS + 255 - unknown + + XLEN (eXtra LENgth) + If FLG.FEXTRA is set, this gives the length of the optional + extra field. See below for details. + + CRC32 (CRC-32) + This contains a Cyclic Redundancy Check value of the + uncompressed data computed according to CRC-32 algorithm + used in the ISO 3309 standard and in section 8.1.1.6.2 of + ITU-T recommendation V.42. (See http://www.iso.ch for + ordering ISO documents. See gopher://info.itu.ch for an + online version of ITU-T V.42.) + + ISIZE (Input SIZE) + This contains the size of the original (uncompressed) input + data modulo 2^32. + + 2.3.1.1. Extra field + + If the FLG.FEXTRA bit is set, an "extra field" is present in + the header, with total length XLEN bytes. It consists of a + series of subfields, each of the form: + + +---+---+---+---+==================================+ + |SI1|SI2| LEN |... LEN bytes of subfield data ...| + +---+---+---+---+==================================+ + + SI1 and SI2 provide a subfield ID, typically two ASCII letters + with some mnemonic value. Jean-Loup Gailly + is maintaining a registry of subfield + IDs; please send him any subfield ID you wish to use. Subfield + IDs with SI2 = 0 are reserved for future use. The following + IDs are currently defined: + + + +Deutsch Informational [Page 8] + +RFC 1952 GZIP File Format Specification May 1996 + + + SI1 SI2 Data + ---------- ---------- ---- + 0x41 ('A') 0x70 ('P') Apollo file type information + + LEN gives the length of the subfield data, excluding the 4 + initial bytes. + + 2.3.1.2. Compliance + + A compliant compressor must produce files with correct ID1, + ID2, CM, CRC32, and ISIZE, but may set all the other fields in + the fixed-length part of the header to default values (255 for + OS, 0 for all others). The compressor must set all reserved + bits to zero. + + A compliant decompressor must check ID1, ID2, and CM, and + provide an error indication if any of these have incorrect + values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC + at least so it can skip over the optional fields if they are + present. It need not examine any other part of the header or + trailer; in particular, a decompressor may ignore FTEXT and OS + and always produce binary output, and still be compliant. A + compliant decompressor must give an error indication if any + reserved bit is non-zero, since such a bit could indicate the + presence of a new field that would cause subsequent data to be + interpreted incorrectly. + +3. References + + [1] "Information Processing - 8-bit single-byte coded graphic + character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). + The ISO 8859-1 (Latin-1) character set is a superset of 7-bit + ASCII. Files defining this character set are available as + iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ + + [2] ISO 3309 + + [3] ITU-T recommendation V.42 + + [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in + ftp://prep.ai.mit.edu/pub/gnu/ + + [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table + Look-Up", Communications of the ACM, 31(8), pp.1008-1013. + + + + +Deutsch Informational [Page 9] + +RFC 1952 GZIP File Format Specification May 1996 + + + [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, + pp.118-133. + + [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, + describing the CRC concept. + +4. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data, such as by + setting and checking the CRC-32 check value. + +5. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +6. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + +Deutsch Informational [Page 10] + +RFC 1952 GZIP File Format Specification May 1996 + + +7. Appendix: Jean-Loup Gailly's gzip utility + + The most widely used implementation of gzip compression, and the + original documentation on which this specification is based, were + created by Jean-Loup Gailly . Since this + implementation is a de facto standard, we mention some more of its + features here. Again, the material in this section is not part of + the specification per se, and implementations need not follow it to + be compliant. + + When compressing or decompressing a file, gzip preserves the + protection, ownership, and modification time attributes on the local + file system, since there is no provision for representing protection + attributes in the gzip file format itself. Since the file format + includes a modification time, the gzip decompressor provides a + command line switch that assigns the modification time from the file, + rather than the local modification time of the compressed input, to + the decompressed output. + +8. Appendix: Sample CRC Code + + The following sample code represents a practical implementation of + the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 + for a formal specification.) + + The sample code is in the ANSI C programming language. Non C users + may find it easier to read with these hints: + + & Bitwise AND operator. + ^ Bitwise exclusive-OR operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero + bit(s) at the left. + ! Logical NOT operator. + ++ "n++" increments the variable n. + 0xNNN 0x introduces a hexadecimal (base 16) constant. + Suffix L indicates a long value (at least 32 bits). + + /* Table of CRCs of all 8-bit messages. */ + unsigned long crc_table[256]; + + /* Flag: has the table been computed? Initially false. */ + int crc_table_computed = 0; + + /* Make the table for a fast CRC. */ + void make_crc_table(void) + { + unsigned long c; + + + +Deutsch Informational [Page 11] + +RFC 1952 GZIP File Format Specification May 1996 + + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; + } + + /* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); + */ + unsigned long update_crc(unsigned long crc, + unsigned char *buf, int len) + { + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + unsigned long crc(unsigned char *buf, int len) + { + return update_crc(0L, buf, len); + } + + + + +Deutsch Informational [Page 12] + diff --git a/src/external/zlib-1.2.11/doc/txtvsbin.txt b/src/external/zlib-1.2.11/doc/txtvsbin.txt new file mode 100644 index 000000000..3d0f0634f --- /dev/null +++ b/src/external/zlib-1.2.11/doc/txtvsbin.txt @@ -0,0 +1,107 @@ +A Fast Method for Identifying Plain Text Files +============================================== + + +Introduction +------------ + +Given a file coming from an unknown source, it is sometimes desirable +to find out whether the format of that file is plain text. Although +this may appear like a simple task, a fully accurate detection of the +file type requires heavy-duty semantic analysis on the file contents. +It is, however, possible to obtain satisfactory results by employing +various heuristics. + +Previous versions of PKZip and other zip-compatible compression tools +were using a crude detection scheme: if more than 80% (4/5) of the bytes +found in a certain buffer are within the range [7..127], the file is +labeled as plain text, otherwise it is labeled as binary. A prominent +limitation of this scheme is the restriction to Latin-based alphabets. +Other alphabets, like Greek, Cyrillic or Asian, make extensive use of +the bytes within the range [128..255], and texts using these alphabets +are most often misidentified by this scheme; in other words, the rate +of false negatives is sometimes too high, which means that the recall +is low. Another weakness of this scheme is a reduced precision, due to +the false positives that may occur when binary files containing large +amounts of textual characters are misidentified as plain text. + +In this article we propose a new, simple detection scheme that features +a much increased precision and a near-100% recall. This scheme is +designed to work on ASCII, Unicode and other ASCII-derived alphabets, +and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) +and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings +(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. + + +The Algorithm +------------- + +The algorithm works by dividing the set of bytecodes [0..255] into three +categories: +- The white list of textual bytecodes: + 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. +- The gray list of tolerated bytecodes: + 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). +- The black list of undesired, non-textual bytecodes: + 0 (NUL) to 6, 14 to 31. + +If a file contains at least one byte that belongs to the white list and +no byte that belongs to the black list, then the file is categorized as +plain text; otherwise, it is categorized as binary. (The boundary case, +when the file is empty, automatically falls into the latter category.) + + +Rationale +--------- + +The idea behind this algorithm relies on two observations. + +The first observation is that, although the full range of 7-bit codes +[0..127] is properly specified by the ASCII standard, most control +characters in the range [0..31] are not used in practice. The only +widely-used, almost universally-portable control codes are 9 (TAB), +10 (LF) and 13 (CR). There are a few more control codes that are +recognized on a reduced range of platforms and text viewers/editors: +7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these +codes are rarely (if ever) used alone, without being accompanied by +some printable text. Even the newer, portable text formats such as +XML avoid using control characters outside the list mentioned here. + +The second observation is that most of the binary files tend to contain +control characters, especially 0 (NUL). Even though the older text +detection schemes observe the presence of non-ASCII codes from the range +[128..255], the precision rarely has to suffer if this upper range is +labeled as textual, because the files that are genuinely binary tend to +contain both control characters and codes from the upper range. On the +other hand, the upper range needs to be labeled as textual, because it +is used by virtually all ASCII extensions. In particular, this range is +used for encoding non-Latin scripts. + +Since there is no counting involved, other than simply observing the +presence or the absence of some byte values, the algorithm produces +consistent results, regardless what alphabet encoding is being used. +(If counting were involved, it could be possible to obtain different +results on a text encoded, say, using ISO-8859-16 versus UTF-8.) + +There is an extra category of plain text files that are "polluted" with +one or more black-listed codes, either by mistake or by peculiar design +considerations. In such cases, a scheme that tolerates a small fraction +of black-listed codes would provide an increased recall (i.e. more true +positives). This, however, incurs a reduced precision overall, since +false positives are more likely to appear in binary files that contain +large chunks of textual data. Furthermore, "polluted" plain text should +be regarded as binary by general-purpose text detection schemes, because +general-purpose text processing algorithms might not be applicable. +Under this premise, it is safe to say that our detection method provides +a near-100% recall. + +Experiments have been run on many files coming from various platforms +and applications. We tried plain text files, system logs, source code, +formatted office documents, compiled object code, etc. The results +confirm the optimistic assumptions about the capabilities of this +algorithm. + + +-- +Cosmin Truta +Last updated: 2006-May-28 diff --git a/src/external/zlib-1.2.11/examples/README.examples b/src/external/zlib-1.2.11/examples/README.examples new file mode 100644 index 000000000..56a31714e --- /dev/null +++ b/src/external/zlib-1.2.11/examples/README.examples @@ -0,0 +1,49 @@ +This directory contains examples of the use of zlib and other relevant +programs and documentation. + +enough.c + calculation and justification of ENOUGH parameter in inftrees.h + - calculates the maximum table space used in inflate tree + construction over all possible Huffman codes + +fitblk.c + compress just enough input to nearly fill a requested output size + - zlib isn't designed to do this, but fitblk does it anyway + +gun.c + uncompress a gzip file + - illustrates the use of inflateBack() for high speed file-to-file + decompression using call-back functions + - is approximately twice as fast as gzip -d + - also provides Unix uncompress functionality, again twice as fast + +gzappend.c + append to a gzip file + - illustrates the use of the Z_BLOCK flush parameter for inflate() + - illustrates the use of deflatePrime() to start at any bit + +gzjoin.c + join gzip files without recalculating the crc or recompressing + - illustrates the use of the Z_BLOCK flush parameter for inflate() + - illustrates the use of crc32_combine() + +gzlog.c +gzlog.h + efficiently and robustly maintain a message log file in gzip format + - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(), + and deflateSetDictionary() + - illustrates use of a gzip header extra field + +zlib_how.html + painfully comprehensive description of zpipe.c (see below) + - describes in excruciating detail the use of deflate() and inflate() + +zpipe.c + reads and writes zlib streams from stdin to stdout + - illustrates the proper use of deflate() and inflate() + - deeply commented in zlib_how.html (see above) + +zran.c + index a zlib or gzip stream and randomly access it + - illustrates the use of Z_BLOCK, inflatePrime(), and + inflateSetDictionary() to provide random access diff --git a/src/external/zlib-1.2.11/examples/enough.c b/src/external/zlib-1.2.11/examples/enough.c new file mode 100644 index 000000000..b99114430 --- /dev/null +++ b/src/external/zlib-1.2.11/examples/enough.c @@ -0,0 +1,572 @@ +/* enough.c -- determine the maximum size of inflate's Huffman code tables over + * all possible valid and complete Huffman codes, subject to a length limit. + * Copyright (C) 2007, 2008, 2012 Mark Adler + * Version 1.4 18 August 2012 Mark Adler + */ + +/* Version history: + 1.0 3 Jan 2007 First version (derived from codecount.c version 1.4) + 1.1 4 Jan 2007 Use faster incremental table usage computation + Prune examine() search on previously visited states + 1.2 5 Jan 2007 Comments clean up + As inflate does, decrease root for short codes + Refuse cases where inflate would increase root + 1.3 17 Feb 2008 Add argument for initial root table size + Fix bug for initial root table size == max - 1 + Use a macro to compute the history index + 1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!) + Clean up comparisons of different types + Clean up code indentation + */ + +/* + Examine all possible Huffman codes for a given number of symbols and a + maximum code length in bits to determine the maximum table size for zilb's + inflate. Only complete Huffman codes are counted. + + Two codes are considered distinct if the vectors of the number of codes per + length are not identical. So permutations of the symbol assignments result + in the same code for the counting, as do permutations of the assignments of + the bit values to the codes (i.e. only canonical codes are counted). + + We build a code from shorter to longer lengths, determining how many symbols + are coded at each length. At each step, we have how many symbols remain to + be coded, what the last code length used was, and how many bit patterns of + that length remain unused. Then we add one to the code length and double the + number of unused patterns to graduate to the next code length. We then + assign all portions of the remaining symbols to that code length that + preserve the properties of a correct and eventually complete code. Those + properties are: we cannot use more bit patterns than are available; and when + all the symbols are used, there are exactly zero possible bit patterns + remaining. + + The inflate Huffman decoding algorithm uses two-level lookup tables for + speed. There is a single first-level table to decode codes up to root bits + in length (root == 9 in the current inflate implementation). The table + has 1 << root entries and is indexed by the next root bits of input. Codes + shorter than root bits have replicated table entries, so that the correct + entry is pointed to regardless of the bits that follow the short code. If + the code is longer than root bits, then the table entry points to a second- + level table. The size of that table is determined by the longest code with + that root-bit prefix. If that longest code has length len, then the table + has size 1 << (len - root), to index the remaining bits in that set of + codes. Each subsequent root-bit prefix then has its own sub-table. The + total number of table entries required by the code is calculated + incrementally as the number of codes at each bit length is populated. When + all of the codes are shorter than root bits, then root is reduced to the + longest code length, resulting in a single, smaller, one-level table. + + The inflate algorithm also provides for small values of root (relative to + the log2 of the number of symbols), where the shortest code has more bits + than root. In that case, root is increased to the length of the shortest + code. This program, by design, does not handle that case, so it is verified + that the number of symbols is less than 2^(root + 1). + + In order to speed up the examination (by about ten orders of magnitude for + the default arguments), the intermediate states in the build-up of a code + are remembered and previously visited branches are pruned. The memory + required for this will increase rapidly with the total number of symbols and + the maximum code length in bits. However this is a very small price to pay + for the vast speedup. + + First, all of the possible Huffman codes are counted, and reachable + intermediate states are noted by a non-zero count in a saved-results array. + Second, the intermediate states that lead to (root + 1) bit or longer codes + are used to look at all sub-codes from those junctures for their inflate + memory usage. (The amount of memory used is not affected by the number of + codes of root bits or less in length.) Third, the visited states in the + construction of those sub-codes and the associated calculation of the table + size is recalled in order to avoid recalculating from the same juncture. + Beginning the code examination at (root + 1) bit codes, which is enabled by + identifying the reachable nodes, accounts for about six of the orders of + magnitude of improvement for the default arguments. About another four + orders of magnitude come from not revisiting previous states. Out of + approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes + need to be examined to cover all of the possible table memory usage cases + for the default arguments of 286 symbols limited to 15-bit codes. + + Note that an unsigned long long type is used for counting. It is quite easy + to exceed the capacity of an eight-byte integer with a large number of + symbols and a large maximum code length, so multiple-precision arithmetic + would need to replace the unsigned long long arithmetic in that case. This + program will abort if an overflow occurs. The big_t type identifies where + the counting takes place. + + An unsigned long long type is also used for calculating the number of + possible codes remaining at the maximum length. This limits the maximum + code length to the number of bits in a long long minus the number of bits + needed to represent the symbols in a flat code. The code_t type identifies + where the bit pattern counting takes place. + */ + +#include +#include +#include +#include + +#define local static + +/* special data types */ +typedef unsigned long long big_t; /* type for code counting */ +typedef unsigned long long code_t; /* type for bit pattern counting */ +struct tab { /* type for been here check */ + size_t len; /* length of bit vector in char's */ + char *vec; /* allocated bit vector */ +}; + +/* The array for saving results, num[], is indexed with this triplet: + + syms: number of symbols remaining to code + left: number of available bit patterns at length len + len: number of bits in the codes currently being assigned + + Those indices are constrained thusly when saving results: + + syms: 3..totsym (totsym == total symbols to code) + left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6) + len: 1..max - 1 (max == maximum code length in bits) + + syms == 2 is not saved since that immediately leads to a single code. left + must be even, since it represents the number of available bit patterns at + the current length, which is double the number at the previous length. + left ends at syms-1 since left == syms immediately results in a single code. + (left > sym is not allowed since that would result in an incomplete code.) + len is less than max, since the code completes immediately when len == max. + + The offset into the array is calculated for the three indices with the + first one (syms) being outermost, and the last one (len) being innermost. + We build the array with length max-1 lists for the len index, with syms-3 + of those for each symbol. There are totsym-2 of those, with each one + varying in length as a function of sym. See the calculation of index in + count() for the index, and the calculation of size in main() for the size + of the array. + + For the deflate example of 286 symbols limited to 15-bit codes, the array + has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than + half of the space allocated for saved results is actually used -- not all + possible triplets are reached in the generation of valid Huffman codes. + */ + +/* The array for tracking visited states, done[], is itself indexed identically + to the num[] array as described above for the (syms, left, len) triplet. + Each element in the array is further indexed by the (mem, rem) doublet, + where mem is the amount of inflate table space used so far, and rem is the + remaining unused entries in the current inflate sub-table. Each indexed + element is simply one bit indicating whether the state has been visited or + not. Since the ranges for mem and rem are not known a priori, each bit + vector is of a variable size, and grows as needed to accommodate the visited + states. mem and rem are used to calculate a single index in a triangular + array. Since the range of mem is expected in the default case to be about + ten times larger than the range of rem, the array is skewed to reduce the + memory usage, with eight times the range for mem than for rem. See the + calculations for offset and bit in beenhere() for the details. + + For the deflate example of 286 symbols limited to 15-bit codes, the bit + vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[] + array itself. + */ + +/* Globals to avoid propagating constants or constant pointers recursively */ +local int max; /* maximum allowed bit length for the codes */ +local int root; /* size of base code table in bits */ +local int large; /* largest code table so far */ +local size_t size; /* number of elements in num and done */ +local int *code; /* number of symbols assigned to each bit length */ +local big_t *num; /* saved results array for code counting */ +local struct tab *done; /* states already evaluated array */ + +/* Index function for num[] and done[] */ +#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1) + +/* Free allocated space. Uses globals code, num, and done. */ +local void cleanup(void) +{ + size_t n; + + if (done != NULL) { + for (n = 0; n < size; n++) + if (done[n].len) + free(done[n].vec); + free(done); + } + if (num != NULL) + free(num); + if (code != NULL) + free(code); +} + +/* Return the number of possible Huffman codes using bit patterns of lengths + len through max inclusive, coding syms symbols, with left bit patterns of + length len unused -- return -1 if there is an overflow in the counting. + Keep a record of previous results in num to prevent repeating the same + calculation. Uses the globals max and num. */ +local big_t count(int syms, int len, int left) +{ + big_t sum; /* number of possible codes from this juncture */ + big_t got; /* value returned from count() */ + int least; /* least number of syms to use at this juncture */ + int most; /* most number of syms to use at this juncture */ + int use; /* number of bit patterns to use in next call */ + size_t index; /* index of this case in *num */ + + /* see if only one possible code */ + if (syms == left) + return 1; + + /* note and verify the expected state */ + assert(syms > left && left > 0 && len < max); + + /* see if we've done this one already */ + index = INDEX(syms, left, len); + got = num[index]; + if (got) + return got; /* we have -- return the saved result */ + + /* we need to use at least this many bit patterns so that the code won't be + incomplete at the next length (more bit patterns than symbols) */ + least = (left << 1) - syms; + if (least < 0) + least = 0; + + /* we can use at most this many bit patterns, lest there not be enough + available for the remaining symbols at the maximum length (if there were + no limit to the code length, this would become: most = left - 1) */ + most = (((code_t)left << (max - len)) - syms) / + (((code_t)1 << (max - len)) - 1); + + /* count all possible codes from this juncture and add them up */ + sum = 0; + for (use = least; use <= most; use++) { + got = count(syms - use, len + 1, (left - use) << 1); + sum += got; + if (got == (big_t)0 - 1 || sum < got) /* overflow */ + return (big_t)0 - 1; + } + + /* verify that all recursive calls are productive */ + assert(sum != 0); + + /* save the result and return it */ + num[index] = sum; + return sum; +} + +/* Return true if we've been here before, set to true if not. Set a bit in a + bit vector to indicate visiting this state. Each (syms,len,left) state + has a variable size bit vector indexed by (mem,rem). The bit vector is + lengthened if needed to allow setting the (mem,rem) bit. */ +local int beenhere(int syms, int len, int left, int mem, int rem) +{ + size_t index; /* index for this state's bit vector */ + size_t offset; /* offset in this state's bit vector */ + int bit; /* mask for this state's bit */ + size_t length; /* length of the bit vector in bytes */ + char *vector; /* new or enlarged bit vector */ + + /* point to vector for (syms,left,len), bit in vector for (mem,rem) */ + index = INDEX(syms, left, len); + mem -= 1 << root; + offset = (mem >> 3) + rem; + offset = ((offset * (offset + 1)) >> 1) + rem; + bit = 1 << (mem & 7); + + /* see if we've been here */ + length = done[index].len; + if (offset < length && (done[index].vec[offset] & bit) != 0) + return 1; /* done this! */ + + /* we haven't been here before -- set the bit to show we have now */ + + /* see if we need to lengthen the vector in order to set the bit */ + if (length <= offset) { + /* if we have one already, enlarge it, zero out the appended space */ + if (length) { + do { + length <<= 1; + } while (length <= offset); + vector = realloc(done[index].vec, length); + if (vector != NULL) + memset(vector + done[index].len, 0, length - done[index].len); + } + + /* otherwise we need to make a new vector and zero it out */ + else { + length = 1 << (len - root); + while (length <= offset) + length <<= 1; + vector = calloc(length, sizeof(char)); + } + + /* in either case, bail if we can't get the memory */ + if (vector == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + cleanup(); + exit(1); + } + + /* install the new vector */ + done[index].len = length; + done[index].vec = vector; + } + + /* set the bit */ + done[index].vec[offset] |= bit; + return 0; +} + +/* Examine all possible codes from the given node (syms, len, left). Compute + the amount of memory required to build inflate's decoding tables, where the + number of code structures used so far is mem, and the number remaining in + the current sub-table is rem. Uses the globals max, code, root, large, and + done. */ +local void examine(int syms, int len, int left, int mem, int rem) +{ + int least; /* least number of syms to use at this juncture */ + int most; /* most number of syms to use at this juncture */ + int use; /* number of bit patterns to use in next call */ + + /* see if we have a complete code */ + if (syms == left) { + /* set the last code entry */ + code[len] = left; + + /* complete computation of memory used by this code */ + while (rem < left) { + left -= rem; + rem = 1 << (len - root); + mem += rem; + } + assert(rem == left); + + /* if this is a new maximum, show the entries used and the sub-code */ + if (mem > large) { + large = mem; + printf("max %d: ", mem); + for (use = root + 1; use <= max; use++) + if (code[use]) + printf("%d[%d] ", code[use], use); + putchar('\n'); + fflush(stdout); + } + + /* remove entries as we drop back down in the recursion */ + code[len] = 0; + return; + } + + /* prune the tree if we can */ + if (beenhere(syms, len, left, mem, rem)) + return; + + /* we need to use at least this many bit patterns so that the code won't be + incomplete at the next length (more bit patterns than symbols) */ + least = (left << 1) - syms; + if (least < 0) + least = 0; + + /* we can use at most this many bit patterns, lest there not be enough + available for the remaining symbols at the maximum length (if there were + no limit to the code length, this would become: most = left - 1) */ + most = (((code_t)left << (max - len)) - syms) / + (((code_t)1 << (max - len)) - 1); + + /* occupy least table spaces, creating new sub-tables as needed */ + use = least; + while (rem < use) { + use -= rem; + rem = 1 << (len - root); + mem += rem; + } + rem -= use; + + /* examine codes from here, updating table space as we go */ + for (use = least; use <= most; use++) { + code[len] = use; + examine(syms - use, len + 1, (left - use) << 1, + mem + (rem ? 1 << (len - root) : 0), rem << 1); + if (rem == 0) { + rem = 1 << (len - root); + mem += rem; + } + rem--; + } + + /* remove entries as we drop back down in the recursion */ + code[len] = 0; +} + +/* Look at all sub-codes starting with root + 1 bits. Look at only the valid + intermediate code states (syms, left, len). For each completed code, + calculate the amount of memory required by inflate to build the decoding + tables. Find the maximum amount of memory required and show the code that + requires that maximum. Uses the globals max, root, and num. */ +local void enough(int syms) +{ + int n; /* number of remaing symbols for this node */ + int left; /* number of unused bit patterns at this length */ + size_t index; /* index of this case in *num */ + + /* clear code */ + for (n = 0; n <= max; n++) + code[n] = 0; + + /* look at all (root + 1) bit and longer codes */ + large = 1 << root; /* base table */ + if (root < max) /* otherwise, there's only a base table */ + for (n = 3; n <= syms; n++) + for (left = 2; left < n; left += 2) + { + /* look at all reachable (root + 1) bit nodes, and the + resulting codes (complete at root + 2 or more) */ + index = INDEX(n, left, root + 1); + if (root + 1 < max && num[index]) /* reachable node */ + examine(n, root + 1, left, 1 << root, 0); + + /* also look at root bit codes with completions at root + 1 + bits (not saved in num, since complete), just in case */ + if (num[index - 1] && n <= left << 1) + examine((n - left) << 1, root + 1, (n - left) << 1, + 1 << root, 0); + } + + /* done */ + printf("done: maximum of %d table entries\n", large); +} + +/* + Examine and show the total number of possible Huffman codes for a given + maximum number of symbols, initial root table size, and maximum code length + in bits -- those are the command arguments in that order. The default + values are 286, 9, and 15 respectively, for the deflate literal/length code. + The possible codes are counted for each number of coded symbols from two to + the maximum. The counts for each of those and the total number of codes are + shown. The maximum number of inflate table entires is then calculated + across all possible codes. Each new maximum number of table entries and the + associated sub-code (starting at root + 1 == 10 bits) is shown. + + To count and examine Huffman codes that are not length-limited, provide a + maximum length equal to the number of symbols minus one. + + For the deflate literal/length code, use "enough". For the deflate distance + code, use "enough 30 6". + + This uses the %llu printf format to print big_t numbers, which assumes that + big_t is an unsigned long long. If the big_t type is changed (for example + to a multiple precision type), the method of printing will also need to be + updated. + */ +int main(int argc, char **argv) +{ + int syms; /* total number of symbols to code */ + int n; /* number of symbols to code for this run */ + big_t got; /* return value of count() */ + big_t sum; /* accumulated number of codes over n */ + code_t word; /* for counting bits in code_t */ + + /* set up globals for cleanup() */ + code = NULL; + num = NULL; + done = NULL; + + /* get arguments -- default to the deflate literal/length code */ + syms = 286; + root = 9; + max = 15; + if (argc > 1) { + syms = atoi(argv[1]); + if (argc > 2) { + root = atoi(argv[2]); + if (argc > 3) + max = atoi(argv[3]); + } + } + if (argc > 4 || syms < 2 || root < 1 || max < 1) { + fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n", + stderr); + return 1; + } + + /* if not restricting the code length, the longest is syms - 1 */ + if (max > syms - 1) + max = syms - 1; + + /* determine the number of bits in a code_t */ + for (n = 0, word = 1; word; n++, word <<= 1) + ; + + /* make sure that the calculation of most will not overflow */ + if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) { + fputs("abort: code length too long for internal types\n", stderr); + return 1; + } + + /* reject impossible code requests */ + if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) { + fprintf(stderr, "%d symbols cannot be coded in %d bits\n", + syms, max); + return 1; + } + + /* allocate code vector */ + code = calloc(max + 1, sizeof(int)); + if (code == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + return 1; + } + + /* determine size of saved results array, checking for overflows, + allocate and clear the array (set all to zero with calloc()) */ + if (syms == 2) /* iff max == 1 */ + num = NULL; /* won't be saving any results */ + else { + size = syms >> 1; + if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) || + (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) || + (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) || + (num = calloc(size, sizeof(big_t))) == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + cleanup(); + return 1; + } + } + + /* count possible codes for all numbers of symbols, add up counts */ + sum = 0; + for (n = 2; n <= syms; n++) { + got = count(n, 1, 2); + sum += got; + if (got == (big_t)0 - 1 || sum < got) { /* overflow */ + fputs("abort: can't count that high!\n", stderr); + cleanup(); + return 1; + } + printf("%llu %d-codes\n", got, n); + } + printf("%llu total codes for 2 to %d symbols", sum, syms); + if (max < syms - 1) + printf(" (%d-bit length limit)\n", max); + else + puts(" (no length limit)"); + + /* allocate and clear done array for beenhere() */ + if (syms == 2) + done = NULL; + else if (size > ((size_t)0 - 1) / sizeof(struct tab) || + (done = calloc(size, sizeof(struct tab))) == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + cleanup(); + return 1; + } + + /* find and show maximum inflate table usage */ + if (root > max) /* reduce root to max length */ + root = max; + if ((code_t)syms < ((code_t)1 << (root + 1))) + enough(syms); + else + puts("cannot handle minimum code lengths > root"); + + /* done */ + cleanup(); + return 0; +} diff --git a/src/external/zlib-1.2.11/examples/fitblk.c b/src/external/zlib-1.2.11/examples/fitblk.c new file mode 100644 index 000000000..c61de5c99 --- /dev/null +++ b/src/external/zlib-1.2.11/examples/fitblk.c @@ -0,0 +1,233 @@ +/* fitblk.c: example of fitting compressed output to a specified size + Not copyrighted -- provided to the public domain + Version 1.1 25 November 2004 Mark Adler */ + +/* Version history: + 1.0 24 Nov 2004 First version + 1.1 25 Nov 2004 Change deflateInit2() to deflateInit() + Use fixed-size, stack-allocated raw buffers + Simplify code moving compression to subroutines + Use assert() for internal errors + Add detailed description of approach + */ + +/* Approach to just fitting a requested compressed size: + + fitblk performs three compression passes on a portion of the input + data in order to determine how much of that input will compress to + nearly the requested output block size. The first pass generates + enough deflate blocks to produce output to fill the requested + output size plus a specfied excess amount (see the EXCESS define + below). The last deflate block may go quite a bit past that, but + is discarded. The second pass decompresses and recompresses just + the compressed data that fit in the requested plus excess sized + buffer. The deflate process is terminated after that amount of + input, which is less than the amount consumed on the first pass. + The last deflate block of the result will be of a comparable size + to the final product, so that the header for that deflate block and + the compression ratio for that block will be about the same as in + the final product. The third compression pass decompresses the + result of the second step, but only the compressed data up to the + requested size minus an amount to allow the compressed stream to + complete (see the MARGIN define below). That will result in a + final compressed stream whose length is less than or equal to the + requested size. Assuming sufficient input and a requested size + greater than a few hundred bytes, the shortfall will typically be + less than ten bytes. + + If the input is short enough that the first compression completes + before filling the requested output size, then that compressed + stream is return with no recompression. + + EXCESS is chosen to be just greater than the shortfall seen in a + two pass approach similar to the above. That shortfall is due to + the last deflate block compressing more efficiently with a smaller + header on the second pass. EXCESS is set to be large enough so + that there is enough uncompressed data for the second pass to fill + out the requested size, and small enough so that the final deflate + block of the second pass will be close in size to the final deflate + block of the third and final pass. MARGIN is chosen to be just + large enough to assure that the final compression has enough room + to complete in all cases. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +/* print nastygram and leave */ +local void quit(char *why) +{ + fprintf(stderr, "fitblk abort: %s\n", why); + exit(1); +} + +#define RAWLEN 4096 /* intermediate uncompressed buffer size */ + +/* compress from file to def until provided buffer is full or end of + input reached; return last deflate() return value, or Z_ERRNO if + there was read error on the file */ +local int partcompress(FILE *in, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + def->avail_in = fread(raw, 1, RAWLEN, in); + if (ferror(in)) + return Z_ERRNO; + def->next_in = raw; + if (feof(in)) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (def->avail_out != 0 && flush == Z_NO_FLUSH); + return ret; +} + +/* recompress from inf's input to def's output; the input for inf and + the output for def are set in those structures before calling; + return last deflate() return value, or Z_MEM_ERROR if inflate() + was not able to allocate enough memory when it needed to */ +local int recompress(z_streamp inf, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + /* decompress */ + inf->avail_out = RAWLEN; + inf->next_out = raw; + ret = inflate(inf, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && + ret != Z_NEED_DICT); + if (ret == Z_MEM_ERROR) + return ret; + + /* compress what was decompresed until done or no room */ + def->avail_in = RAWLEN - inf->avail_out; + def->next_in = raw; + if (inf->avail_out != 0) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (ret != Z_STREAM_END && def->avail_out != 0); + return ret; +} + +#define EXCESS 256 /* empirically determined stream overage */ +#define MARGIN 8 /* amount to back off for completion */ + +/* compress from stdin to fixed-size block on stdout */ +int main(int argc, char **argv) +{ + int ret; /* return code */ + unsigned size; /* requested fixed output block size */ + unsigned have; /* bytes written by deflate() call */ + unsigned char *blk; /* intermediate and final stream */ + unsigned char *tmp; /* close to desired size stream */ + z_stream def, inf; /* zlib deflate and inflate states */ + + /* get requested output size */ + if (argc != 2) + quit("need one argument: size of output block"); + ret = strtol(argv[1], argv + 1, 10); + if (argv[1][0] != 0) + quit("argument must be a number"); + if (ret < 8) /* 8 is minimum zlib stream size */ + quit("need positive size of 8 or greater"); + size = (unsigned)ret; + + /* allocate memory for buffers and compression engine */ + blk = malloc(size + EXCESS); + def.zalloc = Z_NULL; + def.zfree = Z_NULL; + def.opaque = Z_NULL; + ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK || blk == NULL) + quit("out of memory"); + + /* compress from stdin until output full, or no more input */ + def.avail_out = size + EXCESS; + def.next_out = blk; + ret = partcompress(stdin, &def); + if (ret == Z_ERRNO) + quit("error reading input"); + + /* if it all fit, then size was undersubscribed -- done! */ + if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { + /* write block to stdout */ + have = size + EXCESS - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (all input)\n", + size - have, size); + return 0; + } + + /* it didn't all fit -- set up for recompression */ + inf.zalloc = Z_NULL; + inf.zfree = Z_NULL; + inf.opaque = Z_NULL; + inf.avail_in = 0; + inf.next_in = Z_NULL; + ret = inflateInit(&inf); + tmp = malloc(size + EXCESS); + if (ret != Z_OK || tmp == NULL) + quit("out of memory"); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do first recompression close to the right amount */ + inf.avail_in = size + EXCESS; + inf.next_in = blk; + def.avail_out = size + EXCESS; + def.next_out = tmp; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + + /* set up for next reocmpression */ + ret = inflateReset(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do second and final recompression (third compression) */ + inf.avail_in = size - MARGIN; /* assure stream will complete */ + inf.next_in = tmp; + def.avail_out = size; + def.next_out = blk; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ + + /* done -- write block to stdout */ + have = size - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + free(tmp); + ret = inflateEnd(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (%lu input)\n", + size - have, size, def.total_in); + return 0; +} diff --git a/src/external/zlib-1.2.11/examples/gun.c b/src/external/zlib-1.2.11/examples/gun.c new file mode 100644 index 000000000..be44fa51f --- /dev/null +++ b/src/external/zlib-1.2.11/examples/gun.c @@ -0,0 +1,702 @@ +/* gun.c -- simple gunzip to give an example of the use of inflateBack() + * Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + Version 1.7 12 August 2012 Mark Adler */ + +/* Version history: + 1.0 16 Feb 2003 First version for testing of inflateBack() + 1.1 21 Feb 2005 Decompress concatenated gzip streams + Remove use of "this" variable (C++ keyword) + Fix return value for in() + Improve allocation failure checking + Add typecasting for void * structures + Add -h option for command version and usage + Add a bunch of comments + 1.2 20 Mar 2005 Add Unix compress (LZW) decompression + Copy file attributes from input file to output file + 1.3 12 Jun 2005 Add casts for error messages [Oberhumer] + 1.4 8 Dec 2006 LZW decompression speed improvements + 1.5 9 Feb 2008 Avoid warning in latest version of gcc + 1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings + 1.7 12 Aug 2012 Update for z_const usage in zlib 1.2.8 + */ + +/* + gun [ -t ] [ name ... ] + + decompresses the data in the named gzip files. If no arguments are given, + gun will decompress from stdin to stdout. The names must end in .gz, -gz, + .z, -z, _z, or .Z. The uncompressed data will be written to a file name + with the suffix stripped. On success, the original file is deleted. On + failure, the output file is deleted. For most failures, the command will + continue to process the remaining names on the command line. A memory + allocation failure will abort the command. If -t is specified, then the + listed files or stdin will be tested as gzip files for integrity (without + checking for a proper suffix), no output will be written, and no files + will be deleted. + + Like gzip, gun allows concatenated gzip streams and will decompress them, + writing all of the uncompressed data to the output. Unlike gzip, gun allows + an empty file on input, and will produce no error writing an empty output + file. + + gun will also decompress files made by Unix compress, which uses LZW + compression. These files are automatically detected by virtue of their + magic header bytes. Since the end of Unix compress stream is marked by the + end-of-file, they cannot be concantenated. If a Unix compress stream is + encountered in an input file, it is the last stream in that file. + + Like gunzip and uncompress, the file attributes of the original compressed + file are maintained in the final uncompressed file, to the extent that the + user permissions allow it. + + On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version + 1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the + LZW decompression provided by gun is about twice as fast as the standard + Unix uncompress command. + */ + +/* external functions and related types and constants */ +#include /* fprintf() */ +#include /* malloc(), free() */ +#include /* strerror(), strcmp(), strlen(), memcpy() */ +#include /* errno */ +#include /* open() */ +#include /* read(), write(), close(), chown(), unlink() */ +#include +#include /* stat(), chmod() */ +#include /* utime() */ +#include "zlib.h" /* inflateBackInit(), inflateBack(), */ + /* inflateBackEnd(), crc32() */ + +/* function declaration */ +#define local static + +/* buffer constants */ +#define SIZE 32768U /* input and output buffer sizes */ +#define PIECE 16384 /* limits i/o chunks for 16-bit int case */ + +/* structure for infback() to pass to input function in() -- it maintains the + input file and a buffer of size SIZE */ +struct ind { + int infile; + unsigned char *inbuf; +}; + +/* Load input buffer, assumed to be empty, and return bytes loaded and a + pointer to them. read() is called until the buffer is full, or until it + returns end-of-file or error. Return 0 on error. */ +local unsigned in(void *in_desc, z_const unsigned char **buf) +{ + int ret; + unsigned len; + unsigned char *next; + struct ind *me = (struct ind *)in_desc; + + next = me->inbuf; + *buf = next; + len = 0; + do { + ret = PIECE; + if ((unsigned)ret > SIZE - len) + ret = (int)(SIZE - len); + ret = (int)read(me->infile, next, ret); + if (ret == -1) { + len = 0; + break; + } + next += ret; + len += ret; + } while (ret != 0 && len < SIZE); + return len; +} + +/* structure for infback() to pass to output function out() -- it maintains the + output file, a running CRC-32 check on the output and the total number of + bytes output, both for checking against the gzip trailer. (The length in + the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and + the output is greater than 4 GB.) */ +struct outd { + int outfile; + int check; /* true if checking crc and total */ + unsigned long crc; + unsigned long total; +}; + +/* Write output buffer and update the CRC-32 and total bytes written. write() + is called until all of the output is written or an error is encountered. + On success out() returns 0. For a write failure, out() returns 1. If the + output file descriptor is -1, then nothing is written. + */ +local int out(void *out_desc, unsigned char *buf, unsigned len) +{ + int ret; + struct outd *me = (struct outd *)out_desc; + + if (me->check) { + me->crc = crc32(me->crc, buf, len); + me->total += len; + } + if (me->outfile != -1) + do { + ret = PIECE; + if ((unsigned)ret > len) + ret = (int)len; + ret = (int)write(me->outfile, buf, ret); + if (ret == -1) + return 1; + buf += ret; + len -= ret; + } while (len != 0); + return 0; +} + +/* next input byte macro for use inside lunpipe() and gunpipe() */ +#define NEXT() (have ? 0 : (have = in(indp, &next)), \ + last = have ? (have--, (int)(*next++)) : -1) + +/* memory for gunpipe() and lunpipe() -- + the first 256 entries of prefix[] and suffix[] are never used, could + have offset the index, but it's faster to waste the memory */ +unsigned char inbuf[SIZE]; /* input buffer */ +unsigned char outbuf[SIZE]; /* output buffer */ +unsigned short prefix[65536]; /* index to LZW prefix string */ +unsigned char suffix[65536]; /* one-character LZW suffix */ +unsigned char match[65280 + 2]; /* buffer for reversed match or gzip + 32K sliding window */ + +/* throw out what's left in the current bits byte buffer (this is a vestigial + aspect of the compressed data format derived from an implementation that + made use of a special VAX machine instruction!) */ +#define FLUSHCODE() \ + do { \ + left = 0; \ + rem = 0; \ + if (chunk > have) { \ + chunk -= have; \ + have = 0; \ + if (NEXT() == -1) \ + break; \ + chunk--; \ + if (chunk > have) { \ + chunk = have = 0; \ + break; \ + } \ + } \ + have -= chunk; \ + next += chunk; \ + chunk = 0; \ + } while (0) + +/* Decompress a compress (LZW) file from indp to outfile. The compress magic + header (two bytes) has already been read and verified. There are have bytes + of buffered input at next. strm is used for passing error information back + to gunpipe(). + + lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of + file, read error, or write error (a write error indicated by strm->next_in + not equal to Z_NULL), or Z_DATA_ERROR for invalid input. + */ +local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp, + int outfile, z_stream *strm) +{ + int last; /* last byte read by NEXT(), or -1 if EOF */ + unsigned chunk; /* bytes left in current chunk */ + int left; /* bits left in rem */ + unsigned rem; /* unused bits from input */ + int bits; /* current bits per code */ + unsigned code; /* code, table traversal index */ + unsigned mask; /* mask for current bits codes */ + int max; /* maximum bits per code for this stream */ + unsigned flags; /* compress flags, then block compress flag */ + unsigned end; /* last valid entry in prefix/suffix tables */ + unsigned temp; /* current code */ + unsigned prev; /* previous code */ + unsigned final; /* last character written for previous code */ + unsigned stack; /* next position for reversed string */ + unsigned outcnt; /* bytes in output buffer */ + struct outd outd; /* output structure */ + unsigned char *p; + + /* set up output */ + outd.outfile = outfile; + outd.check = 0; + + /* process remainder of compress header -- a flags byte */ + flags = NEXT(); + if (last == -1) + return Z_BUF_ERROR; + if (flags & 0x60) { + strm->msg = (char *)"unknown lzw flags set"; + return Z_DATA_ERROR; + } + max = flags & 0x1f; + if (max < 9 || max > 16) { + strm->msg = (char *)"lzw bits out of range"; + return Z_DATA_ERROR; + } + if (max == 9) /* 9 doesn't really mean 9 */ + max = 10; + flags &= 0x80; /* true if block compress */ + + /* clear table */ + bits = 9; + mask = 0x1ff; + end = flags ? 256 : 255; + + /* set up: get first 9-bit code, which is the first decompressed byte, but + don't create a table entry until the next code */ + if (NEXT() == -1) /* no compressed data is ok */ + return Z_OK; + final = prev = (unsigned)last; /* low 8 bits of code */ + if (NEXT() == -1) /* missing a bit */ + return Z_BUF_ERROR; + if (last & 1) { /* code must be < 256 */ + strm->msg = (char *)"invalid lzw code"; + return Z_DATA_ERROR; + } + rem = (unsigned)last >> 1; /* remaining 7 bits */ + left = 7; + chunk = bits - 2; /* 7 bytes left in this chunk */ + outbuf[0] = (unsigned char)final; /* write first decompressed byte */ + outcnt = 1; + + /* decode codes */ + stack = 0; + for (;;) { + /* if the table will be full after this, increment the code size */ + if (end >= mask && bits < max) { + FLUSHCODE(); + bits++; + mask <<= 1; + mask++; + } + + /* get a code of length bits */ + if (chunk == 0) /* decrement chunk modulo bits */ + chunk = bits; + code = rem; /* low bits of code */ + if (NEXT() == -1) { /* EOF is end of compressed data */ + /* write remaining buffered output */ + if (outcnt && out(&outd, outbuf, outcnt)) { + strm->next_in = outbuf; /* signal write error */ + return Z_BUF_ERROR; + } + return Z_OK; + } + code += (unsigned)last << left; /* middle (or high) bits of code */ + left += 8; + chunk--; + if (bits > left) { /* need more bits */ + if (NEXT() == -1) /* can't end in middle of code */ + return Z_BUF_ERROR; + code += (unsigned)last << left; /* high bits of code */ + left += 8; + chunk--; + } + code &= mask; /* mask to current code length */ + left -= bits; /* number of unused bits */ + rem = (unsigned)last >> (8 - left); /* unused bits from last byte */ + + /* process clear code (256) */ + if (code == 256 && flags) { + FLUSHCODE(); + bits = 9; /* initialize bits and mask */ + mask = 0x1ff; + end = 255; /* empty table */ + continue; /* get next code */ + } + + /* special code to reuse last match */ + temp = code; /* save the current code */ + if (code > end) { + /* Be picky on the allowed code here, and make sure that the code + we drop through (prev) will be a valid index so that random + input does not cause an exception. The code != end + 1 check is + empirically derived, and not checked in the original uncompress + code. If this ever causes a problem, that check could be safely + removed. Leaving this check in greatly improves gun's ability + to detect random or corrupted input after a compress header. + In any case, the prev > end check must be retained. */ + if (code != end + 1 || prev > end) { + strm->msg = (char *)"invalid lzw code"; + return Z_DATA_ERROR; + } + match[stack++] = (unsigned char)final; + code = prev; + } + + /* walk through linked list to generate output in reverse order */ + p = match + stack; + while (code >= 256) { + *p++ = suffix[code]; + code = prefix[code]; + } + stack = p - match; + match[stack++] = (unsigned char)code; + final = code; + + /* link new table entry */ + if (end < mask) { + end++; + prefix[end] = (unsigned short)prev; + suffix[end] = (unsigned char)final; + } + + /* set previous code for next iteration */ + prev = temp; + + /* write output in forward order */ + while (stack > SIZE - outcnt) { + while (outcnt < SIZE) + outbuf[outcnt++] = match[--stack]; + if (out(&outd, outbuf, outcnt)) { + strm->next_in = outbuf; /* signal write error */ + return Z_BUF_ERROR; + } + outcnt = 0; + } + p = match + stack; + do { + outbuf[outcnt++] = *--p; + } while (p > match); + stack = 0; + + /* loop for next code with final and prev as the last match, rem and + left provide the first 0..7 bits of the next code, end is the last + valid table entry */ + } +} + +/* Decompress a gzip file from infile to outfile. strm is assumed to have been + successfully initialized with inflateBackInit(). The input file may consist + of a series of gzip streams, in which case all of them will be decompressed + to the output file. If outfile is -1, then the gzip stream(s) integrity is + checked and nothing is written. + + The return value is a zlib error code: Z_MEM_ERROR if out of memory, + Z_DATA_ERROR if the header or the compressed data is invalid, or if the + trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends + prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip + stream) follows a valid gzip stream. + */ +local int gunpipe(z_stream *strm, int infile, int outfile) +{ + int ret, first, last; + unsigned have, flags, len; + z_const unsigned char *next = NULL; + struct ind ind, *indp; + struct outd outd; + + /* setup input buffer */ + ind.infile = infile; + ind.inbuf = inbuf; + indp = &ind; + + /* decompress concatenated gzip streams */ + have = 0; /* no input data read in yet */ + first = 1; /* looking for first gzip header */ + strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ + for (;;) { + /* look for the two magic header bytes for a gzip stream */ + if (NEXT() == -1) { + ret = Z_OK; + break; /* empty gzip stream is ok */ + } + if (last != 31 || (NEXT() != 139 && last != 157)) { + strm->msg = (char *)"incorrect header check"; + ret = first ? Z_DATA_ERROR : Z_ERRNO; + break; /* not a gzip or compress header */ + } + first = 0; /* next non-header is junk */ + + /* process a compress (LZW) file -- can't be concatenated after this */ + if (last == 157) { + ret = lunpipe(have, next, indp, outfile, strm); + break; + } + + /* process remainder of gzip header */ + ret = Z_BUF_ERROR; + if (NEXT() != 8) { /* only deflate method allowed */ + if (last == -1) break; + strm->msg = (char *)"unknown compression method"; + ret = Z_DATA_ERROR; + break; + } + flags = NEXT(); /* header flags */ + NEXT(); /* discard mod time, xflgs, os */ + NEXT(); + NEXT(); + NEXT(); + NEXT(); + NEXT(); + if (last == -1) break; + if (flags & 0xe0) { + strm->msg = (char *)"unknown header flags set"; + ret = Z_DATA_ERROR; + break; + } + if (flags & 4) { /* extra field */ + len = NEXT(); + len += (unsigned)(NEXT()) << 8; + if (last == -1) break; + while (len > have) { + len -= have; + have = 0; + if (NEXT() == -1) break; + len--; + } + if (last == -1) break; + have -= len; + next += len; + } + if (flags & 8) /* file name */ + while (NEXT() != 0 && last != -1) + ; + if (flags & 16) /* comment */ + while (NEXT() != 0 && last != -1) + ; + if (flags & 2) { /* header crc */ + NEXT(); + NEXT(); + } + if (last == -1) break; + + /* set up output */ + outd.outfile = outfile; + outd.check = 1; + outd.crc = crc32(0L, Z_NULL, 0); + outd.total = 0; + + /* decompress data to output */ + strm->next_in = next; + strm->avail_in = have; + ret = inflateBack(strm, in, indp, out, &outd); + if (ret != Z_STREAM_END) break; + next = strm->next_in; + have = strm->avail_in; + strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ + + /* check trailer */ + ret = Z_BUF_ERROR; + if (NEXT() != (int)(outd.crc & 0xff) || + NEXT() != (int)((outd.crc >> 8) & 0xff) || + NEXT() != (int)((outd.crc >> 16) & 0xff) || + NEXT() != (int)((outd.crc >> 24) & 0xff)) { + /* crc error */ + if (last != -1) { + strm->msg = (char *)"incorrect data check"; + ret = Z_DATA_ERROR; + } + break; + } + if (NEXT() != (int)(outd.total & 0xff) || + NEXT() != (int)((outd.total >> 8) & 0xff) || + NEXT() != (int)((outd.total >> 16) & 0xff) || + NEXT() != (int)((outd.total >> 24) & 0xff)) { + /* length error */ + if (last != -1) { + strm->msg = (char *)"incorrect length check"; + ret = Z_DATA_ERROR; + } + break; + } + + /* go back and look for another gzip stream */ + } + + /* clean up and return */ + return ret; +} + +/* Copy file attributes, from -> to, as best we can. This is best effort, so + no errors are reported. The mode bits, including suid, sgid, and the sticky + bit are copied (if allowed), the owner's user id and group id are copied + (again if allowed), and the access and modify times are copied. */ +local void copymeta(char *from, char *to) +{ + struct stat was; + struct utimbuf when; + + /* get all of from's Unix meta data, return if not a regular file */ + if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG) + return; + + /* set to's mode bits, ignore errors */ + (void)chmod(to, was.st_mode & 07777); + + /* copy owner's user and group, ignore errors */ + (void)chown(to, was.st_uid, was.st_gid); + + /* copy access and modify times, ignore errors */ + when.actime = was.st_atime; + when.modtime = was.st_mtime; + (void)utime(to, &when); +} + +/* Decompress the file inname to the file outnname, of if test is true, just + decompress without writing and check the gzip trailer for integrity. If + inname is NULL or an empty string, read from stdin. If outname is NULL or + an empty string, write to stdout. strm is a pre-initialized inflateBack + structure. When appropriate, copy the file attributes from inname to + outname. + + gunzip() returns 1 if there is an out-of-memory error or an unexpected + return code from gunpipe(). Otherwise it returns 0. + */ +local int gunzip(z_stream *strm, char *inname, char *outname, int test) +{ + int ret; + int infile, outfile; + + /* open files */ + if (inname == NULL || *inname == 0) { + inname = "-"; + infile = 0; /* stdin */ + } + else { + infile = open(inname, O_RDONLY, 0); + if (infile == -1) { + fprintf(stderr, "gun cannot open %s\n", inname); + return 0; + } + } + if (test) + outfile = -1; + else if (outname == NULL || *outname == 0) { + outname = "-"; + outfile = 1; /* stdout */ + } + else { + outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666); + if (outfile == -1) { + close(infile); + fprintf(stderr, "gun cannot create %s\n", outname); + return 0; + } + } + errno = 0; + + /* decompress */ + ret = gunpipe(strm, infile, outfile); + if (outfile > 2) close(outfile); + if (infile > 2) close(infile); + + /* interpret result */ + switch (ret) { + case Z_OK: + case Z_ERRNO: + if (infile > 2 && outfile > 2) { + copymeta(inname, outname); /* copy attributes */ + unlink(inname); + } + if (ret == Z_ERRNO) + fprintf(stderr, "gun warning: trailing garbage ignored in %s\n", + inname); + break; + case Z_DATA_ERROR: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg); + break; + case Z_MEM_ERROR: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun out of memory error--aborting\n"); + return 1; + case Z_BUF_ERROR: + if (outfile > 2) unlink(outname); + if (strm->next_in != Z_NULL) { + fprintf(stderr, "gun write error on %s: %s\n", + outname, strerror(errno)); + } + else if (errno) { + fprintf(stderr, "gun read error on %s: %s\n", + inname, strerror(errno)); + } + else { + fprintf(stderr, "gun unexpected end of file on %s\n", + inname); + } + break; + default: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun internal error--aborting\n"); + return 1; + } + return 0; +} + +/* Process the gun command line arguments. See the command syntax near the + beginning of this source file. */ +int main(int argc, char **argv) +{ + int ret, len, test; + char *outname; + unsigned char *window; + z_stream strm; + + /* initialize inflateBack state for repeated use */ + window = match; /* reuse LZW match buffer */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = inflateBackInit(&strm, 15, window); + if (ret != Z_OK) { + fprintf(stderr, "gun out of memory error--aborting\n"); + return 1; + } + + /* decompress each file to the same name with the suffix removed */ + argc--; + argv++; + test = 0; + if (argc && strcmp(*argv, "-h") == 0) { + fprintf(stderr, "gun 1.6 (17 Jan 2010)\n"); + fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n"); + fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n"); + return 0; + } + if (argc && strcmp(*argv, "-t") == 0) { + test = 1; + argc--; + argv++; + } + if (argc) + do { + if (test) + outname = NULL; + else { + len = (int)strlen(*argv); + if (strcmp(*argv + len - 3, ".gz") == 0 || + strcmp(*argv + len - 3, "-gz") == 0) + len -= 3; + else if (strcmp(*argv + len - 2, ".z") == 0 || + strcmp(*argv + len - 2, "-z") == 0 || + strcmp(*argv + len - 2, "_z") == 0 || + strcmp(*argv + len - 2, ".Z") == 0) + len -= 2; + else { + fprintf(stderr, "gun error: no gz type on %s--skipping\n", + *argv); + continue; + } + outname = malloc(len + 1); + if (outname == NULL) { + fprintf(stderr, "gun out of memory error--aborting\n"); + ret = 1; + break; + } + memcpy(outname, *argv, len); + outname[len] = 0; + } + ret = gunzip(&strm, *argv, outname, test); + if (outname != NULL) free(outname); + if (ret) break; + } while (argv++, --argc); + else + ret = gunzip(&strm, NULL, NULL, test); + + /* clean up */ + inflateBackEnd(&strm); + return ret; +} diff --git a/src/external/zlib-1.2.11/examples/gzappend.c b/src/external/zlib-1.2.11/examples/gzappend.c new file mode 100644 index 000000000..662dec379 --- /dev/null +++ b/src/external/zlib-1.2.11/examples/gzappend.c @@ -0,0 +1,504 @@ +/* gzappend -- command to append to a gzip file + + Copyright (C) 2003, 2012 Mark Adler, all rights reserved + version 1.2, 11 Oct 2012 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + * Change history: + * + * 1.0 19 Oct 2003 - First version + * 1.1 4 Nov 2003 - Expand and clarify some comments and notes + * - Add version and copyright to help + * - Send help to stdout instead of stderr + * - Add some preemptive typecasts + * - Add L to constants in lseek() calls + * - Remove some debugging information in error messages + * - Use new data_type definition for zlib 1.2.1 + * - Simplfy and unify file operations + * - Finish off gzip file in gztack() + * - Use deflatePrime() instead of adding empty blocks + * - Keep gzip file clean on appended file read errors + * - Use in-place rotate instead of auxiliary buffer + * (Why you ask? Because it was fun to write!) + * 1.2 11 Oct 2012 - Fix for proper z_const usage + * - Check for input buffer malloc failure + */ + +/* + gzappend takes a gzip file and appends to it, compressing files from the + command line or data from stdin. The gzip file is written to directly, to + avoid copying that file, in case it's large. Note that this results in the + unfriendly behavior that if gzappend fails, the gzip file is corrupted. + + This program was written to illustrate the use of the new Z_BLOCK option of + zlib 1.2.x's inflate() function. This option returns from inflate() at each + block boundary to facilitate locating and modifying the last block bit at + the start of the final deflate block. Also whether using Z_BLOCK or not, + another required feature of zlib 1.2.x is that inflate() now provides the + number of unusued bits in the last input byte used. gzappend will not work + with versions of zlib earlier than 1.2.1. + + gzappend first decompresses the gzip file internally, discarding all but + the last 32K of uncompressed data, and noting the location of the last block + bit and the number of unused bits in the last byte of the compressed data. + The gzip trailer containing the CRC-32 and length of the uncompressed data + is verified. This trailer will be later overwritten. + + Then the last block bit is cleared by seeking back in the file and rewriting + the byte that contains it. Seeking forward, the last byte of the compressed + data is saved along with the number of unused bits to initialize deflate. + + A deflate process is initialized, using the last 32K of the uncompressed + data from the gzip file to initialize the dictionary. If the total + uncompressed data was less than 32K, then all of it is used to initialize + the dictionary. The deflate output bit buffer is also initialized with the + last bits from the original deflate stream. From here on, the data to + append is simply compressed using deflate, and written to the gzip file. + When that is complete, the new CRC-32 and uncompressed length are written + as the trailer of the gzip file. + */ + +#include +#include +#include +#include +#include +#include "zlib.h" + +#define local static +#define LGCHUNK 14 +#define CHUNK (1U << LGCHUNK) +#define DSIZE 32768U + +/* print an error message and terminate with extreme prejudice */ +local void bye(char *msg1, char *msg2) +{ + fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2); + exit(1); +} + +/* return the greatest common divisor of a and b using Euclid's algorithm, + modified to be fast when one argument much greater than the other, and + coded to avoid unnecessary swapping */ +local unsigned gcd(unsigned a, unsigned b) +{ + unsigned c; + + while (a && b) + if (a > b) { + c = b; + while (a - c >= c) + c <<= 1; + a -= c; + } + else { + c = a; + while (b - c >= c) + c <<= 1; + b -= c; + } + return a + b; +} + +/* rotate list[0..len-1] left by rot positions, in place */ +local void rotate(unsigned char *list, unsigned len, unsigned rot) +{ + unsigned char tmp; + unsigned cycles; + unsigned char *start, *last, *to, *from; + + /* normalize rot and handle degenerate cases */ + if (len < 2) return; + if (rot >= len) rot %= len; + if (rot == 0) return; + + /* pointer to last entry in list */ + last = list + (len - 1); + + /* do simple left shift by one */ + if (rot == 1) { + tmp = *list; + memcpy(list, list + 1, len - 1); + *last = tmp; + return; + } + + /* do simple right shift by one */ + if (rot == len - 1) { + tmp = *last; + memmove(list + 1, list, len - 1); + *list = tmp; + return; + } + + /* otherwise do rotate as a set of cycles in place */ + cycles = gcd(len, rot); /* number of cycles */ + do { + start = from = list + cycles; /* start index is arbitrary */ + tmp = *from; /* save entry to be overwritten */ + for (;;) { + to = from; /* next step in cycle */ + from += rot; /* go right rot positions */ + if (from > last) from -= len; /* (pointer better not wrap) */ + if (from == start) break; /* all but one shifted */ + *to = *from; /* shift left */ + } + *to = tmp; /* complete the circle */ + } while (--cycles); +} + +/* structure for gzip file read operations */ +typedef struct { + int fd; /* file descriptor */ + int size; /* 1 << size is bytes in buf */ + unsigned left; /* bytes available at next */ + unsigned char *buf; /* buffer */ + z_const unsigned char *next; /* next byte in buffer */ + char *name; /* file name for error messages */ +} file; + +/* reload buffer */ +local int readin(file *in) +{ + int len; + + len = read(in->fd, in->buf, 1 << in->size); + if (len == -1) bye("error reading ", in->name); + in->left = (unsigned)len; + in->next = in->buf; + return len; +} + +/* read from file in, exit if end-of-file */ +local int readmore(file *in) +{ + if (readin(in) == 0) bye("unexpected end of ", in->name); + return 0; +} + +#define read1(in) (in->left == 0 ? readmore(in) : 0, \ + in->left--, *(in->next)++) + +/* skip over n bytes of in */ +local void skip(file *in, unsigned n) +{ + unsigned bypass; + + if (n > in->left) { + n -= in->left; + bypass = n & ~((1U << in->size) - 1); + if (bypass) { + if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1) + bye("seeking ", in->name); + n -= bypass; + } + readmore(in); + if (n > in->left) + bye("unexpected end of ", in->name); + } + in->left -= n; + in->next += n; +} + +/* read a four-byte unsigned integer, little-endian, from in */ +unsigned long read4(file *in) +{ + unsigned long val; + + val = read1(in); + val += (unsigned)read1(in) << 8; + val += (unsigned long)read1(in) << 16; + val += (unsigned long)read1(in) << 24; + return val; +} + +/* skip over gzip header */ +local void gzheader(file *in) +{ + int flags; + unsigned n; + + if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file"); + if (read1(in) != 8) bye("unknown compression method in", in->name); + flags = read1(in); + if (flags & 0xe0) bye("unknown header flags set in", in->name); + skip(in, 6); + if (flags & 4) { + n = read1(in); + n += (unsigned)(read1(in)) << 8; + skip(in, n); + } + if (flags & 8) while (read1(in) != 0) ; + if (flags & 16) while (read1(in) != 0) ; + if (flags & 2) skip(in, 2); +} + +/* decompress gzip file "name", return strm with a deflate stream ready to + continue compression of the data in the gzip file, and return a file + descriptor pointing to where to write the compressed data -- the deflate + stream is initialized to compress using level "level" */ +local int gzscan(char *name, z_stream *strm, int level) +{ + int ret, lastbit, left, full; + unsigned have; + unsigned long crc, tot; + unsigned char *window; + off_t lastoff, end; + file gz; + + /* open gzip file */ + gz.name = name; + gz.fd = open(name, O_RDWR, 0); + if (gz.fd == -1) bye("cannot open ", name); + gz.buf = malloc(CHUNK); + if (gz.buf == NULL) bye("out of memory", ""); + gz.size = LGCHUNK; + gz.left = 0; + + /* skip gzip header */ + gzheader(&gz); + + /* prepare to decompress */ + window = malloc(DSIZE); + if (window == NULL) bye("out of memory", ""); + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = inflateInit2(strm, -15); + if (ret != Z_OK) bye("out of memory", " or library mismatch"); + + /* decompress the deflate stream, saving append information */ + lastbit = 0; + lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left; + left = 0; + strm->avail_in = gz.left; + strm->next_in = gz.next; + crc = crc32(0L, Z_NULL, 0); + have = full = 0; + do { + /* if needed, get more input */ + if (strm->avail_in == 0) { + readmore(&gz); + strm->avail_in = gz.left; + strm->next_in = gz.next; + } + + /* set up output to next available section of sliding window */ + strm->avail_out = DSIZE - have; + strm->next_out = window + have; + + /* inflate and check for errors */ + ret = inflate(strm, Z_BLOCK); + if (ret == Z_STREAM_ERROR) bye("internal stream error!", ""); + if (ret == Z_MEM_ERROR) bye("out of memory", ""); + if (ret == Z_DATA_ERROR) + bye("invalid compressed data--format violated in", name); + + /* update crc and sliding window pointer */ + crc = crc32(crc, window + have, DSIZE - have - strm->avail_out); + if (strm->avail_out) + have = DSIZE - strm->avail_out; + else { + have = 0; + full = 1; + } + + /* process end of block */ + if (strm->data_type & 128) { + if (strm->data_type & 64) + left = strm->data_type & 0x1f; + else { + lastbit = strm->data_type & 0x1f; + lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in; + } + } + } while (ret != Z_STREAM_END); + inflateEnd(strm); + gz.left = strm->avail_in; + gz.next = strm->next_in; + + /* save the location of the end of the compressed data */ + end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left; + + /* check gzip trailer and save total for deflate */ + if (crc != read4(&gz)) + bye("invalid compressed data--crc mismatch in ", name); + tot = strm->total_out; + if ((tot & 0xffffffffUL) != read4(&gz)) + bye("invalid compressed data--length mismatch in", name); + + /* if not at end of file, warn */ + if (gz.left || readin(&gz)) + fprintf(stderr, + "gzappend warning: junk at end of gzip file overwritten\n"); + + /* clear last block bit */ + lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET); + if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name); + *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7))); + lseek(gz.fd, -1L, SEEK_CUR); + if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name); + + /* if window wrapped, build dictionary from window by rotating */ + if (full) { + rotate(window, DSIZE, have); + have = DSIZE; + } + + /* set up deflate stream with window, crc, total_in, and leftover bits */ + ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) bye("out of memory", ""); + deflateSetDictionary(strm, window, have); + strm->adler = crc; + strm->total_in = tot; + if (left) { + lseek(gz.fd, --end, SEEK_SET); + if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name); + deflatePrime(strm, 8 - left, *gz.buf); + } + lseek(gz.fd, end, SEEK_SET); + + /* clean up and return */ + free(window); + free(gz.buf); + return gz.fd; +} + +/* append file "name" to gzip file gd using deflate stream strm -- if last + is true, then finish off the deflate stream at the end */ +local void gztack(char *name, int gd, z_stream *strm, int last) +{ + int fd, len, ret; + unsigned left; + unsigned char *in, *out; + + /* open file to compress and append */ + fd = 0; + if (name != NULL) { + fd = open(name, O_RDONLY, 0); + if (fd == -1) + fprintf(stderr, "gzappend warning: %s not found, skipping ...\n", + name); + } + + /* allocate buffers */ + in = malloc(CHUNK); + out = malloc(CHUNK); + if (in == NULL || out == NULL) bye("out of memory", ""); + + /* compress input file and append to gzip file */ + do { + /* get more input */ + len = read(fd, in, CHUNK); + if (len == -1) { + fprintf(stderr, + "gzappend warning: error reading %s, skipping rest ...\n", + name); + len = 0; + } + strm->avail_in = (unsigned)len; + strm->next_in = in; + if (len) strm->adler = crc32(strm->adler, in, (unsigned)len); + + /* compress and write all available output */ + do { + strm->avail_out = CHUNK; + strm->next_out = out; + ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH); + left = CHUNK - strm->avail_out; + while (left) { + len = write(gd, out + CHUNK - strm->avail_out - left, left); + if (len == -1) bye("writing gzip file", ""); + left -= (unsigned)len; + } + } while (strm->avail_out == 0 && ret != Z_STREAM_END); + } while (len != 0); + + /* write trailer after last entry */ + if (last) { + deflateEnd(strm); + out[0] = (unsigned char)(strm->adler); + out[1] = (unsigned char)(strm->adler >> 8); + out[2] = (unsigned char)(strm->adler >> 16); + out[3] = (unsigned char)(strm->adler >> 24); + out[4] = (unsigned char)(strm->total_in); + out[5] = (unsigned char)(strm->total_in >> 8); + out[6] = (unsigned char)(strm->total_in >> 16); + out[7] = (unsigned char)(strm->total_in >> 24); + len = 8; + do { + ret = write(gd, out + 8 - len, len); + if (ret == -1) bye("writing gzip file", ""); + len -= ret; + } while (len); + close(gd); + } + + /* clean up and return */ + free(out); + free(in); + if (fd > 0) close(fd); +} + +/* process the compression level option if present, scan the gzip file, and + append the specified files, or append the data from stdin if no other file + names are provided on the command line -- the gzip file must be writable + and seekable */ +int main(int argc, char **argv) +{ + int gd, level; + z_stream strm; + + /* ignore command name */ + argc--; argv++; + + /* provide usage if no arguments */ + if (*argv == NULL) { + printf( + "gzappend 1.2 (11 Oct 2012) Copyright (C) 2003, 2012 Mark Adler\n" + ); + printf( + "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n"); + return 0; + } + + /* set compression level */ + level = Z_DEFAULT_COMPRESSION; + if (argv[0][0] == '-') { + if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0) + bye("invalid compression level", ""); + level = argv[0][1] - '0'; + if (*++argv == NULL) bye("no gzip file name after options", ""); + } + + /* prepare to append to gzip file */ + gd = gzscan(*argv++, &strm, level); + + /* append files on command line, or from stdin if none */ + if (*argv == NULL) + gztack(NULL, gd, &strm, 1); + else + do { + gztack(*argv, gd, &strm, argv[1] == NULL); + } while (*++argv != NULL); + return 0; +} diff --git a/src/external/zlib-1.2.11/examples/gzjoin.c b/src/external/zlib-1.2.11/examples/gzjoin.c new file mode 100644 index 000000000..89e809844 --- /dev/null +++ b/src/external/zlib-1.2.11/examples/gzjoin.c @@ -0,0 +1,449 @@ +/* gzjoin -- command to join gzip files into one gzip file + + Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved + version 1.2, 14 Aug 2012 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + * Change history: + * + * 1.0 11 Dec 2004 - First version + * 1.1 12 Jun 2005 - Changed ssize_t to long for portability + * 1.2 14 Aug 2012 - Clean up for z_const usage + */ + +/* + gzjoin takes one or more gzip files on the command line and writes out a + single gzip file that will uncompress to the concatenation of the + uncompressed data from the individual gzip files. gzjoin does this without + having to recompress any of the data and without having to calculate a new + crc32 for the concatenated uncompressed data. gzjoin does however have to + decompress all of the input data in order to find the bits in the compressed + data that need to be modified to concatenate the streams. + + gzjoin does not do an integrity check on the input gzip files other than + checking the gzip header and decompressing the compressed data. They are + otherwise assumed to be complete and correct. + + Each joint between gzip files removes at least 18 bytes of previous trailer + and subsequent header, and inserts an average of about three bytes to the + compressed data in order to connect the streams. The output gzip file + has a minimal ten-byte gzip header with no file name or modification time. + + This program was written to illustrate the use of the Z_BLOCK option of + inflate() and the crc32_combine() function. gzjoin will not compile with + versions of zlib earlier than 1.2.3. + */ + +#include /* fputs(), fprintf(), fwrite(), putc() */ +#include /* exit(), malloc(), free() */ +#include /* open() */ +#include /* close(), read(), lseek() */ +#include "zlib.h" + /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */ + +#define local static + +/* exit with an error (return a value to allow use in an expression) */ +local int bail(char *why1, char *why2) +{ + fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2); + exit(1); + return 0; +} + +/* -- simple buffered file input with access to the buffer -- */ + +#define CHUNK 32768 /* must be a power of two and fit in unsigned */ + +/* bin buffered input file type */ +typedef struct { + char *name; /* name of file for error messages */ + int fd; /* file descriptor */ + unsigned left; /* bytes remaining at next */ + unsigned char *next; /* next byte to read */ + unsigned char *buf; /* allocated buffer of length CHUNK */ +} bin; + +/* close a buffered file and free allocated memory */ +local void bclose(bin *in) +{ + if (in != NULL) { + if (in->fd != -1) + close(in->fd); + if (in->buf != NULL) + free(in->buf); + free(in); + } +} + +/* open a buffered file for input, return a pointer to type bin, or NULL on + failure */ +local bin *bopen(char *name) +{ + bin *in; + + in = malloc(sizeof(bin)); + if (in == NULL) + return NULL; + in->buf = malloc(CHUNK); + in->fd = open(name, O_RDONLY, 0); + if (in->buf == NULL || in->fd == -1) { + bclose(in); + return NULL; + } + in->left = 0; + in->next = in->buf; + in->name = name; + return in; +} + +/* load buffer from file, return -1 on read error, 0 or 1 on success, with + 1 indicating that end-of-file was reached */ +local int bload(bin *in) +{ + long len; + + if (in == NULL) + return -1; + if (in->left != 0) + return 0; + in->next = in->buf; + do { + len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left); + if (len < 0) + return -1; + in->left += (unsigned)len; + } while (len != 0 && in->left < CHUNK); + return len == 0 ? 1 : 0; +} + +/* get a byte from the file, bail if end of file */ +#define bget(in) (in->left ? 0 : bload(in), \ + in->left ? (in->left--, *(in->next)++) : \ + bail("unexpected end of file on ", in->name)) + +/* get a four-byte little-endian unsigned integer from file */ +local unsigned long bget4(bin *in) +{ + unsigned long val; + + val = bget(in); + val += (unsigned long)(bget(in)) << 8; + val += (unsigned long)(bget(in)) << 16; + val += (unsigned long)(bget(in)) << 24; + return val; +} + +/* skip bytes in file */ +local void bskip(bin *in, unsigned skip) +{ + /* check pointer */ + if (in == NULL) + return; + + /* easy case -- skip bytes in buffer */ + if (skip <= in->left) { + in->left -= skip; + in->next += skip; + return; + } + + /* skip what's in buffer, discard buffer contents */ + skip -= in->left; + in->left = 0; + + /* seek past multiples of CHUNK bytes */ + if (skip > CHUNK) { + unsigned left; + + left = skip & (CHUNK - 1); + if (left == 0) { + /* exact number of chunks: seek all the way minus one byte to check + for end-of-file with a read */ + lseek(in->fd, skip - 1, SEEK_CUR); + if (read(in->fd, in->buf, 1) != 1) + bail("unexpected end of file on ", in->name); + return; + } + + /* skip the integral chunks, update skip with remainder */ + lseek(in->fd, skip - left, SEEK_CUR); + skip = left; + } + + /* read more input and skip remainder */ + bload(in); + if (skip > in->left) + bail("unexpected end of file on ", in->name); + in->left -= skip; + in->next += skip; +} + +/* -- end of buffered input functions -- */ + +/* skip the gzip header from file in */ +local void gzhead(bin *in) +{ + int flags; + + /* verify gzip magic header and compression method */ + if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8) + bail(in->name, " is not a valid gzip file"); + + /* get and verify flags */ + flags = bget(in); + if ((flags & 0xe0) != 0) + bail("unknown reserved bits set in ", in->name); + + /* skip modification time, extra flags, and os */ + bskip(in, 6); + + /* skip extra field if present */ + if (flags & 4) { + unsigned len; + + len = bget(in); + len += (unsigned)(bget(in)) << 8; + bskip(in, len); + } + + /* skip file name if present */ + if (flags & 8) + while (bget(in) != 0) + ; + + /* skip comment if present */ + if (flags & 16) + while (bget(in) != 0) + ; + + /* skip header crc if present */ + if (flags & 2) + bskip(in, 2); +} + +/* write a four-byte little-endian unsigned integer to out */ +local void put4(unsigned long val, FILE *out) +{ + putc(val & 0xff, out); + putc((val >> 8) & 0xff, out); + putc((val >> 16) & 0xff, out); + putc((val >> 24) & 0xff, out); +} + +/* Load up zlib stream from buffered input, bail if end of file */ +local void zpull(z_streamp strm, bin *in) +{ + if (in->left == 0) + bload(in); + if (in->left == 0) + bail("unexpected end of file on ", in->name); + strm->avail_in = in->left; + strm->next_in = in->next; +} + +/* Write header for gzip file to out and initialize trailer. */ +local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out) +{ + fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out); + *crc = crc32(0L, Z_NULL, 0); + *tot = 0; +} + +/* Copy the compressed data from name, zeroing the last block bit of the last + block if clr is true, and adding empty blocks as needed to get to a byte + boundary. If clr is false, then the last block becomes the last block of + the output, and the gzip trailer is written. crc and tot maintains the + crc and length (modulo 2^32) of the output for the trailer. The resulting + gzip file is written to out. gzinit() must be called before the first call + of gzcopy() to write the gzip header and to initialize crc and tot. */ +local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot, + FILE *out) +{ + int ret; /* return value from zlib functions */ + int pos; /* where the "last block" bit is in byte */ + int last; /* true if processing the last block */ + bin *in; /* buffered input file */ + unsigned char *start; /* start of compressed data in buffer */ + unsigned char *junk; /* buffer for uncompressed data -- discarded */ + z_off_t len; /* length of uncompressed data (support > 4 GB) */ + z_stream strm; /* zlib inflate stream */ + + /* open gzip file and skip header */ + in = bopen(name); + if (in == NULL) + bail("could not open ", name); + gzhead(in); + + /* allocate buffer for uncompressed data and initialize raw inflate + stream */ + junk = malloc(CHUNK); + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -15); + if (junk == NULL || ret != Z_OK) + bail("out of memory", ""); + + /* inflate and copy compressed data, clear last-block bit if requested */ + len = 0; + zpull(&strm, in); + start = in->next; + last = start[0] & 1; + if (last && clr) + start[0] &= ~1; + strm.avail_out = 0; + for (;;) { + /* if input used and output done, write used input and get more */ + if (strm.avail_in == 0 && strm.avail_out != 0) { + fwrite(start, 1, strm.next_in - start, out); + start = in->buf; + in->left = 0; + zpull(&strm, in); + } + + /* decompress -- return early when end-of-block reached */ + strm.avail_out = CHUNK; + strm.next_out = junk; + ret = inflate(&strm, Z_BLOCK); + switch (ret) { + case Z_MEM_ERROR: + bail("out of memory", ""); + case Z_DATA_ERROR: + bail("invalid compressed data in ", in->name); + } + + /* update length of uncompressed data */ + len += CHUNK - strm.avail_out; + + /* check for block boundary (only get this when block copied out) */ + if (strm.data_type & 128) { + /* if that was the last block, then done */ + if (last) + break; + + /* number of unused bits in last byte */ + pos = strm.data_type & 7; + + /* find the next last-block bit */ + if (pos != 0) { + /* next last-block bit is in last used byte */ + pos = 0x100 >> pos; + last = strm.next_in[-1] & pos; + if (last && clr) + in->buf[strm.next_in - in->buf - 1] &= ~pos; + } + else { + /* next last-block bit is in next unused byte */ + if (strm.avail_in == 0) { + /* don't have that byte yet -- get it */ + fwrite(start, 1, strm.next_in - start, out); + start = in->buf; + in->left = 0; + zpull(&strm, in); + } + last = strm.next_in[0] & 1; + if (last && clr) + in->buf[strm.next_in - in->buf] &= ~1; + } + } + } + + /* update buffer with unused input */ + in->left = strm.avail_in; + in->next = in->buf + (strm.next_in - in->buf); + + /* copy used input, write empty blocks to get to byte boundary */ + pos = strm.data_type & 7; + fwrite(start, 1, in->next - start - 1, out); + last = in->next[-1]; + if (pos == 0 || !clr) + /* already at byte boundary, or last file: write last byte */ + putc(last, out); + else { + /* append empty blocks to last byte */ + last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */ + if (pos & 1) { + /* odd -- append an empty stored block */ + putc(last, out); + if (pos == 1) + putc(0, out); /* two more bits in block header */ + fwrite("\0\0\xff\xff", 1, 4, out); + } + else { + /* even -- append 1, 2, or 3 empty fixed blocks */ + switch (pos) { + case 6: + putc(last | 8, out); + last = 0; + case 4: + putc(last | 0x20, out); + last = 0; + case 2: + putc(last | 0x80, out); + putc(0, out); + } + } + } + + /* update crc and tot */ + *crc = crc32_combine(*crc, bget4(in), len); + *tot += (unsigned long)len; + + /* clean up */ + inflateEnd(&strm); + free(junk); + bclose(in); + + /* write trailer if this is the last gzip file */ + if (!clr) { + put4(*crc, out); + put4(*tot, out); + } +} + +/* join the gzip files on the command line, write result to stdout */ +int main(int argc, char **argv) +{ + unsigned long crc, tot; /* running crc and total uncompressed length */ + + /* skip command name */ + argc--; + argv++; + + /* show usage if no arguments */ + if (argc == 0) { + fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n", + stderr); + return 0; + } + + /* join gzip files on command line and write to stdout */ + gzinit(&crc, &tot, stdout); + while (argc--) + gzcopy(*argv++, argc, &crc, &tot, stdout); + + /* done */ + return 0; +} diff --git a/src/external/zlib-1.2.11/examples/gzlog.c b/src/external/zlib-1.2.11/examples/gzlog.c new file mode 100644 index 000000000..b8c29274e --- /dev/null +++ b/src/external/zlib-1.2.11/examples/gzlog.c @@ -0,0 +1,1059 @@ +/* + * gzlog.c + * Copyright (C) 2004, 2008, 2012, 2016 Mark Adler, all rights reserved + * For conditions of distribution and use, see copyright notice in gzlog.h + * version 2.2, 14 Aug 2012 + */ + +/* + gzlog provides a mechanism for frequently appending short strings to a gzip + file that is efficient both in execution time and compression ratio. The + strategy is to write the short strings in an uncompressed form to the end of + the gzip file, only compressing when the amount of uncompressed data has + reached a given threshold. + + gzlog also provides protection against interruptions in the process due to + system crashes. The status of the operation is recorded in an extra field + in the gzip file, and is only updated once the gzip file is brought to a + valid state. The last data to be appended or compressed is saved in an + auxiliary file, so that if the operation is interrupted, it can be completed + the next time an append operation is attempted. + + gzlog maintains another auxiliary file with the last 32K of data from the + compressed portion, which is preloaded for the compression of the subsequent + data. This minimizes the impact to the compression ratio of appending. + */ + +/* + Operations Concept: + + Files (log name "foo"): + foo.gz -- gzip file with the complete log + foo.add -- last message to append or last data to compress + foo.dict -- dictionary of the last 32K of data for next compression + foo.temp -- temporary dictionary file for compression after this one + foo.lock -- lock file for reading and writing the other files + foo.repairs -- log file for log file recovery operations (not compressed) + + gzip file structure: + - fixed-length (no file name) header with extra field (see below) + - compressed data ending initially with empty stored block + - uncompressed data filling out originally empty stored block and + subsequent stored blocks as needed (16K max each) + - gzip trailer + - no junk at end (no other gzip streams) + + When appending data, the information in the first three items above plus the + foo.add file are sufficient to recover an interrupted append operation. The + extra field has the necessary information to restore the start of the last + stored block and determine where to append the data in the foo.add file, as + well as the crc and length of the gzip data before the append operation. + + The foo.add file is created before the gzip file is marked for append, and + deleted after the gzip file is marked as complete. So if the append + operation is interrupted, the data to add will still be there. If due to + some external force, the foo.add file gets deleted between when the append + operation was interrupted and when recovery is attempted, the gzip file will + still be restored, but without the appended data. + + When compressing data, the information in the first two items above plus the + foo.add file are sufficient to recover an interrupted compress operation. + The extra field has the necessary information to find the end of the + compressed data, and contains both the crc and length of just the compressed + data and of the complete set of data including the contents of the foo.add + file. + + Again, the foo.add file is maintained during the compress operation in case + of an interruption. If in the unlikely event the foo.add file with the data + to be compressed is missing due to some external force, a gzip file with + just the previous compressed data will be reconstructed. In this case, all + of the data that was to be compressed is lost (approximately one megabyte). + This will not occur if all that happened was an interruption of the compress + operation. + + The third state that is marked is the replacement of the old dictionary with + the new dictionary after a compress operation. Once compression is + complete, the gzip file is marked as being in the replace state. This + completes the gzip file, so an interrupt after being so marked does not + result in recompression. Then the dictionary file is replaced, and the gzip + file is marked as completed. This state prevents the possibility of + restarting compression with the wrong dictionary file. + + All three operations are wrapped by a lock/unlock procedure. In order to + gain exclusive access to the log files, first a foo.lock file must be + exclusively created. When all operations are complete, the lock is + released by deleting the foo.lock file. If when attempting to create the + lock file, it already exists and the modify time of the lock file is more + than five minutes old (set by the PATIENCE define below), then the old + lock file is considered stale and deleted, and the exclusive creation of + the lock file is retried. To assure that there are no false assessments + of the staleness of the lock file, the operations periodically touch the + lock file to update the modified date. + + Following is the definition of the extra field with all of the information + required to enable the above append and compress operations and their + recovery if interrupted. Multi-byte values are stored little endian + (consistent with the gzip format). File pointers are eight bytes long. + The crc's and lengths for the gzip trailer are four bytes long. (Note that + the length at the end of a gzip file is used for error checking only, and + for large files is actually the length modulo 2^32.) The stored block + length is two bytes long. The gzip extra field two-byte identification is + "ap" for append. It is assumed that writing the extra field to the file is + an "atomic" operation. That is, either all of the extra field is written + to the file, or none of it is, if the operation is interrupted right at the + point of updating the extra field. This is a reasonable assumption, since + the extra field is within the first 52 bytes of the file, which is smaller + than any expected block size for a mass storage device (usually 512 bytes or + larger). + + Extra field (35 bytes): + - Pointer to first stored block length -- this points to the two-byte length + of the first stored block, which is followed by the two-byte, one's + complement of that length. The stored block length is preceded by the + three-bit header of the stored block, which is the actual start of the + stored block in the deflate format. See the bit offset field below. + - Pointer to the last stored block length. This is the same as above, but + for the last stored block of the uncompressed data in the gzip file. + Initially this is the same as the first stored block length pointer. + When the stored block gets to 16K (see the MAX_STORE define), then a new + stored block as added, at which point the last stored block length pointer + is different from the first stored block length pointer. When they are + different, the first bit of the last stored block header is eight bits, or + one byte back from the block length. + - Compressed data crc and length. This is the crc and length of the data + that is in the compressed portion of the deflate stream. These are used + only in the event that the foo.add file containing the data to compress is + lost after a compress operation is interrupted. + - Total data crc and length. This is the crc and length of all of the data + stored in the gzip file, compressed and uncompressed. It is used to + reconstruct the gzip trailer when compressing, as well as when recovering + interrupted operations. + - Final stored block length. This is used to quickly find where to append, + and allows the restoration of the original final stored block state when + an append operation is interrupted. + - First stored block start as the number of bits back from the final stored + block first length byte. This value is in the range of 3..10, and is + stored as the low three bits of the final byte of the extra field after + subtracting three (0..7). This allows the last-block bit of the stored + block header to be updated when a new stored block is added, for the case + when the first stored block and the last stored block are the same. (When + they are different, the numbers of bits back is known to be eight.) This + also allows for new compressed data to be appended to the old compressed + data in the compress operation, overwriting the previous first stored + block, or for the compressed data to be terminated and a valid gzip file + reconstructed on the off chance that a compression operation was + interrupted and the data to compress in the foo.add file was deleted. + - The operation in process. This is the next two bits in the last byte (the + bits under the mask 0x18). The are interpreted as 0: nothing in process, + 1: append in process, 2: compress in process, 3: replace in process. + - The top three bits of the last byte in the extra field are reserved and + are currently set to zero. + + Main procedure: + - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of + the system open() call. If the modify time of an existing lock file is + more than PATIENCE seconds old, then the lock file is deleted and the + exclusive create is retried. + - Load the extra field from the foo.gz file, and see if an operation was in + progress but not completed. If so, apply the recovery procedure below. + - Perform the append procedure with the provided data. + - If the uncompressed data in the foo.gz file is 1MB or more, apply the + compress procedure. + - Delete the foo.lock file. + + Append procedure: + - Put what to append in the foo.add file so that the operation can be + restarted if this procedure is interrupted. + - Mark the foo.gz extra field with the append operation in progress. + + Restore the original last-block bit and stored block length of the last + stored block from the information in the extra field, in case a previous + append operation was interrupted. + - Append the provided data to the last stored block, creating new stored + blocks as needed and updating the stored blocks last-block bits and + lengths. + - Update the crc and length with the new data, and write the gzip trailer. + - Write over the extra field (with a single write operation) with the new + pointers, lengths, and crc's, and mark the gzip file as not in process. + Though there is still a foo.add file, it will be ignored since nothing + is in process. If a foo.add file is leftover from a previously + completed operation, it is truncated when writing new data to it. + - Delete the foo.add file. + + Compress and replace procedures: + - Read all of the uncompressed data in the stored blocks in foo.gz and write + it to foo.add. Also write foo.temp with the last 32K of that data to + provide a dictionary for the next invocation of this procedure. + - Rewrite the extra field marking foo.gz with a compression in process. + * If there is no data provided to compress (due to a missing foo.add file + when recovering), reconstruct and truncate the foo.gz file to contain + only the previous compressed data and proceed to the step after the next + one. Otherwise ... + - Compress the data with the dictionary in foo.dict, and write to the + foo.gz file starting at the bit immediately following the last previously + compressed block. If there is no foo.dict, proceed anyway with the + compression at slightly reduced efficiency. (For the foo.dict file to be + missing requires some external failure beyond simply the interruption of + a compress operation.) During this process, the foo.lock file is + periodically touched to assure that that file is not considered stale by + another process before we're done. The deflation is terminated with a + non-last empty static block (10 bits long), that is then located and + written over by a last-bit-set empty stored block. + - Append the crc and length of the data in the gzip file (previously + calculated during the append operations). + - Write over the extra field with the updated stored block offsets, bits + back, crc's, and lengths, and mark foo.gz as in process for a replacement + of the dictionary. + @ Delete the foo.add file. + - Replace foo.dict with foo.temp. + - Write over the extra field, marking foo.gz as complete. + + Recovery procedure: + - If not a replace recovery, read in the foo.add file, and provide that data + to the appropriate recovery below. If there is no foo.add file, provide + a zero data length to the recovery. In that case, the append recovery + restores the foo.gz to the previous compressed + uncompressed data state. + For the the compress recovery, a missing foo.add file results in foo.gz + being restored to the previous compressed-only data state. + - Append recovery: + - Pick up append at + step above + - Compress recovery: + - Pick up compress at * step above + - Replace recovery: + - Pick up compress at @ step above + - Log the repair with a date stamp in foo.repairs + */ + +#include +#include /* rename, fopen, fprintf, fclose */ +#include /* malloc, free */ +#include /* strlen, strrchr, strcpy, strncpy, strcmp */ +#include /* open */ +#include /* lseek, read, write, close, unlink, sleep, */ + /* ftruncate, fsync */ +#include /* errno */ +#include /* time, ctime */ +#include /* stat */ +#include /* utimes */ +#include "zlib.h" /* crc32 */ + +#include "gzlog.h" /* header for external access */ + +#define local static +typedef unsigned int uint; +typedef unsigned long ulong; + +/* Macro for debugging to deterministically force recovery operations */ +#ifdef GZLOG_DEBUG + #include /* longjmp */ + jmp_buf gzlog_jump; /* where to go back to */ + int gzlog_bail = 0; /* which point to bail at (1..8) */ + int gzlog_count = -1; /* number of times through to wait */ +# define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \ + longjmp(gzlog_jump, gzlog_bail); } while (0) +#else +# define BAIL(n) +#endif + +/* how old the lock file can be in seconds before considering it stale */ +#define PATIENCE 300 + +/* maximum stored block size in Kbytes -- must be in 1..63 */ +#define MAX_STORE 16 + +/* number of stored Kbytes to trigger compression (must be >= 32 to allow + dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to + discard the stored block headers contribution of five bytes each) */ +#define TRIGGER 1024 + +/* size of a deflate dictionary (this cannot be changed) */ +#define DICT 32768U + +/* values for the operation (2 bits) */ +#define NO_OP 0 +#define APPEND_OP 1 +#define COMPRESS_OP 2 +#define REPLACE_OP 3 + +/* macros to extract little-endian integers from an unsigned byte buffer */ +#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8)) +#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16)) +#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32)) + +/* macros to store integers into a byte buffer in little-endian order */ +#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0) +#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0) +#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0) + +/* internal structure for log information */ +#define LOGID "\106\035\172" /* should be three non-zero characters */ +struct log { + char id[4]; /* contains LOGID to detect inadvertent overwrites */ + int fd; /* file descriptor for .gz file, opened read/write */ + char *path; /* allocated path, e.g. "/var/log/foo" or "foo" */ + char *end; /* end of path, for appending suffices such as ".gz" */ + off_t first; /* offset of first stored block first length byte */ + int back; /* location of first block id in bits back from first */ + uint stored; /* bytes currently in last stored block */ + off_t last; /* offset of last stored block first length byte */ + ulong ccrc; /* crc of compressed data */ + ulong clen; /* length (modulo 2^32) of compressed data */ + ulong tcrc; /* crc of total data */ + ulong tlen; /* length (modulo 2^32) of total data */ + time_t lock; /* last modify time of our lock file */ +}; + +/* gzip header for gzlog */ +local unsigned char log_gzhead[] = { + 0x1f, 0x8b, /* magic gzip id */ + 8, /* compression method is deflate */ + 4, /* there is an extra field (no file name) */ + 0, 0, 0, 0, /* no modification time provided */ + 0, 0xff, /* no extra flags, no OS specified */ + 39, 0, 'a', 'p', 35, 0 /* extra field with "ap" subfield */ + /* 35 is EXTRA, 39 is EXTRA + 4 */ +}; + +#define HEAD sizeof(log_gzhead) /* should be 16 */ + +/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */ +local unsigned char log_gzext[] = { + 52, 0, 0, 0, 0, 0, 0, 0, /* offset of first stored block length */ + 52, 0, 0, 0, 0, 0, 0, 0, /* offset of last stored block length */ + 0, 0, 0, 0, 0, 0, 0, 0, /* compressed data crc and length */ + 0, 0, 0, 0, 0, 0, 0, 0, /* total data crc and length */ + 0, 0, /* final stored block data length */ + 5 /* op is NO_OP, last bit 8 bits back */ +}; + +#define EXTRA sizeof(log_gzext) /* should be 35 */ + +/* initial gzip data and trailer */ +local unsigned char log_gzbody[] = { + 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */ + 0, 0, 0, 0, /* crc */ + 0, 0, 0, 0 /* uncompressed length */ +}; + +#define BODY sizeof(log_gzbody) + +/* Exclusively create foo.lock in order to negotiate exclusive access to the + foo.* files. If the modify time of an existing lock file is greater than + PATIENCE seconds in the past, then consider the lock file to have been + abandoned, delete it, and try the exclusive create again. Save the lock + file modify time for verification of ownership. Return 0 on success, or -1 + on failure, usually due to an access restriction or invalid path. Note that + if stat() or unlink() fails, it may be due to another process noticing the + abandoned lock file a smidge sooner and deleting it, so those are not + flagged as an error. */ +local int log_lock(struct log *log) +{ + int fd; + struct stat st; + + strcpy(log->end, ".lock"); + while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) { + if (errno != EEXIST) + return -1; + if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) { + unlink(log->path); + continue; + } + sleep(2); /* relinquish the CPU for two seconds while waiting */ + } + close(fd); + if (stat(log->path, &st) == 0) + log->lock = st.st_mtime; + return 0; +} + +/* Update the modify time of the lock file to now, in order to prevent another + task from thinking that the lock is stale. Save the lock file modify time + for verification of ownership. */ +local void log_touch(struct log *log) +{ + struct stat st; + + strcpy(log->end, ".lock"); + utimes(log->path, NULL); + if (stat(log->path, &st) == 0) + log->lock = st.st_mtime; +} + +/* Check the log file modify time against what is expected. Return true if + this is not our lock. If it is our lock, touch it to keep it. */ +local int log_check(struct log *log) +{ + struct stat st; + + strcpy(log->end, ".lock"); + if (stat(log->path, &st) || st.st_mtime != log->lock) + return 1; + log_touch(log); + return 0; +} + +/* Unlock a previously acquired lock, but only if it's ours. */ +local void log_unlock(struct log *log) +{ + if (log_check(log)) + return; + strcpy(log->end, ".lock"); + unlink(log->path); + log->lock = 0; +} + +/* Check the gzip header and read in the extra field, filling in the values in + the log structure. Return op on success or -1 if the gzip header was not as + expected. op is the current operation in progress last written to the extra + field. This assumes that the gzip file has already been opened, with the + file descriptor log->fd. */ +local int log_head(struct log *log) +{ + int op; + unsigned char buf[HEAD + EXTRA]; + + if (lseek(log->fd, 0, SEEK_SET) < 0 || + read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA || + memcmp(buf, log_gzhead, HEAD)) { + return -1; + } + log->first = PULL8(buf + HEAD); + log->last = PULL8(buf + HEAD + 8); + log->ccrc = PULL4(buf + HEAD + 16); + log->clen = PULL4(buf + HEAD + 20); + log->tcrc = PULL4(buf + HEAD + 24); + log->tlen = PULL4(buf + HEAD + 28); + log->stored = PULL2(buf + HEAD + 32); + log->back = 3 + (buf[HEAD + 34] & 7); + op = (buf[HEAD + 34] >> 3) & 3; + return op; +} + +/* Write over the extra field contents, marking the operation as op. Use fsync + to assure that the device is written to, and in the requested order. This + operation, and only this operation, is assumed to be atomic in order to + assure that the log is recoverable in the event of an interruption at any + point in the process. Return -1 if the write to foo.gz failed. */ +local int log_mark(struct log *log, int op) +{ + int ret; + unsigned char ext[EXTRA]; + + PUT8(ext, log->first); + PUT8(ext + 8, log->last); + PUT4(ext + 16, log->ccrc); + PUT4(ext + 20, log->clen); + PUT4(ext + 24, log->tcrc); + PUT4(ext + 28, log->tlen); + PUT2(ext + 32, log->stored); + ext[34] = log->back - 3 + (op << 3); + fsync(log->fd); + ret = lseek(log->fd, HEAD, SEEK_SET) < 0 || + write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0; + fsync(log->fd); + return ret; +} + +/* Rewrite the last block header bits and subsequent zero bits to get to a byte + boundary, setting the last block bit if last is true, and then write the + remainder of the stored block header (length and one's complement). Leave + the file pointer after the end of the last stored block data. Return -1 if + there is a read or write failure on the foo.gz file */ +local int log_last(struct log *log, int last) +{ + int back, len, mask; + unsigned char buf[6]; + + /* determine the locations of the bytes and bits to modify */ + back = log->last == log->first ? log->back : 8; + len = back > 8 ? 2 : 1; /* bytes back from log->last */ + mask = 0x80 >> ((back - 1) & 7); /* mask for block last-bit */ + + /* get the byte to modify (one or two back) into buf[0] -- don't need to + read the byte if the last-bit is eight bits back, since in that case + the entire byte will be modified */ + buf[0] = 0; + if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 || + read(log->fd, buf, 1) != 1)) + return -1; + + /* change the last-bit of the last stored block as requested -- note + that all bits above the last-bit are set to zero, per the type bits + of a stored block being 00 and per the convention that the bits to + bring the stream to a byte boundary are also zeros */ + buf[1] = 0; + buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0); + + /* write the modified stored block header and lengths, move the file + pointer to after the last stored block data */ + PUT2(buf + 2, log->stored); + PUT2(buf + 4, log->stored ^ 0xffff); + return lseek(log->fd, log->last - len, SEEK_SET) < 0 || + write(log->fd, buf + 2 - len, len + 4) != len + 4 || + lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0; +} + +/* Append len bytes from data to the locked and open log file. len may be zero + if recovering and no .add file was found. In that case, the previous state + of the foo.gz file is restored. The data is appended uncompressed in + deflate stored blocks. Return -1 if there was an error reading or writing + the foo.gz file. */ +local int log_append(struct log *log, unsigned char *data, size_t len) +{ + uint put; + off_t end; + unsigned char buf[8]; + + /* set the last block last-bit and length, in case recovering an + interrupted append, then position the file pointer to append to the + block */ + if (log_last(log, 1)) + return -1; + + /* append, adding stored blocks and updating the offset of the last stored + block as needed, and update the total crc and length */ + while (len) { + /* append as much as we can to the last block */ + put = (MAX_STORE << 10) - log->stored; + if (put > len) + put = (uint)len; + if (put) { + if (write(log->fd, data, put) != put) + return -1; + BAIL(1); + log->tcrc = crc32(log->tcrc, data, put); + log->tlen += put; + log->stored += put; + data += put; + len -= put; + } + + /* if we need to, add a new empty stored block */ + if (len) { + /* mark current block as not last */ + if (log_last(log, 0)) + return -1; + + /* point to new, empty stored block */ + log->last += 4 + log->stored + 1; + log->stored = 0; + } + + /* mark last block as last, update its length */ + if (log_last(log, 1)) + return -1; + BAIL(2); + } + + /* write the new crc and length trailer, and truncate just in case (could + be recovering from partial append with a missing foo.add file) */ + PUT4(buf, log->tcrc); + PUT4(buf + 4, log->tlen); + if (write(log->fd, buf, 8) != 8 || + (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end)) + return -1; + + /* write the extra field, marking the log file as done, delete .add file */ + if (log_mark(log, NO_OP)) + return -1; + strcpy(log->end, ".add"); + unlink(log->path); /* ignore error, since may not exist */ + return 0; +} + +/* Replace the foo.dict file with the foo.temp file. Also delete the foo.add + file, since the compress operation may have been interrupted before that was + done. Returns 1 if memory could not be allocated, or -1 if reading or + writing foo.gz fails, or if the rename fails for some reason other than + foo.temp not existing. foo.temp not existing is a permitted error, since + the replace operation may have been interrupted after the rename is done, + but before foo.gz is marked as complete. */ +local int log_replace(struct log *log) +{ + int ret; + char *dest; + + /* delete foo.add file */ + strcpy(log->end, ".add"); + unlink(log->path); /* ignore error, since may not exist */ + BAIL(3); + + /* rename foo.name to foo.dict, replacing foo.dict if it exists */ + strcpy(log->end, ".dict"); + dest = malloc(strlen(log->path) + 1); + if (dest == NULL) + return -2; + strcpy(dest, log->path); + strcpy(log->end, ".temp"); + ret = rename(log->path, dest); + free(dest); + if (ret && errno != ENOENT) + return -1; + BAIL(4); + + /* mark the foo.gz file as done */ + return log_mark(log, NO_OP); +} + +/* Compress the len bytes at data and append the compressed data to the + foo.gz deflate data immediately after the previous compressed data. This + overwrites the previous uncompressed data, which was stored in foo.add + and is the data provided in data[0..len-1]. If this operation is + interrupted, it picks up at the start of this routine, with the foo.add + file read in again. If there is no data to compress (len == 0), then we + simply terminate the foo.gz file after the previously compressed data, + appending a final empty stored block and the gzip trailer. Return -1 if + reading or writing the log.gz file failed, or -2 if there was a memory + allocation failure. */ +local int log_compress(struct log *log, unsigned char *data, size_t len) +{ + int fd; + uint got, max; + ssize_t dict; + off_t end; + z_stream strm; + unsigned char buf[DICT]; + + /* compress and append compressed data */ + if (len) { + /* set up for deflate, allocating memory */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, + Z_DEFAULT_STRATEGY) != Z_OK) + return -2; + + /* read in dictionary (last 32K of data that was compressed) */ + strcpy(log->end, ".dict"); + fd = open(log->path, O_RDONLY, 0); + if (fd >= 0) { + dict = read(fd, buf, DICT); + close(fd); + if (dict < 0) { + deflateEnd(&strm); + return -1; + } + if (dict) + deflateSetDictionary(&strm, buf, (uint)dict); + } + log_touch(log); + + /* prime deflate with last bits of previous block, position write + pointer to write those bits and overwrite what follows */ + if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1), + SEEK_SET) < 0 || + read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) { + deflateEnd(&strm); + return -1; + } + deflatePrime(&strm, (8 - log->back) & 7, *buf); + + /* compress, finishing with a partial non-last empty static block */ + strm.next_in = data; + max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */ + do { + strm.avail_in = len > max ? max : (uint)len; + len -= strm.avail_in; + do { + strm.avail_out = DICT; + strm.next_out = buf; + deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH); + got = DICT - strm.avail_out; + if (got && write(log->fd, buf, got) != got) { + deflateEnd(&strm); + return -1; + } + log_touch(log); + } while (strm.avail_out == 0); + } while (len); + deflateEnd(&strm); + BAIL(5); + + /* find start of empty static block -- scanning backwards the first one + bit is the second bit of the block, if the last byte is zero, then + we know the byte before that has a one in the top bit, since an + empty static block is ten bits long */ + if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 || + read(log->fd, buf, 1) != 1) + return -1; + log->first++; + if (*buf) { + log->back = 1; + while ((*buf & ((uint)1 << (8 - log->back++))) == 0) + ; /* guaranteed to terminate, since *buf != 0 */ + } + else + log->back = 10; + + /* update compressed crc and length */ + log->ccrc = log->tcrc; + log->clen = log->tlen; + } + else { + /* no data to compress -- fix up existing gzip stream */ + log->tcrc = log->ccrc; + log->tlen = log->clen; + } + + /* complete and truncate gzip stream */ + log->last = log->first; + log->stored = 0; + PUT4(buf, log->tcrc); + PUT4(buf + 4, log->tlen); + if (log_last(log, 1) || write(log->fd, buf, 8) != 8 || + (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end)) + return -1; + BAIL(6); + + /* mark as being in the replace operation */ + if (log_mark(log, REPLACE_OP)) + return -1; + + /* execute the replace operation and mark the file as done */ + return log_replace(log); +} + +/* log a repair record to the .repairs file */ +local void log_log(struct log *log, int op, char *record) +{ + time_t now; + FILE *rec; + + now = time(NULL); + strcpy(log->end, ".repairs"); + rec = fopen(log->path, "a"); + if (rec == NULL) + return; + fprintf(rec, "%.24s %s recovery: %s\n", ctime(&now), op == APPEND_OP ? + "append" : (op == COMPRESS_OP ? "compress" : "replace"), record); + fclose(rec); + return; +} + +/* Recover the interrupted operation op. First read foo.add for recovering an + append or compress operation. Return -1 if there was an error reading or + writing foo.gz or reading an existing foo.add, or -2 if there was a memory + allocation failure. */ +local int log_recover(struct log *log, int op) +{ + int fd, ret = 0; + unsigned char *data = NULL; + size_t len = 0; + struct stat st; + + /* log recovery */ + log_log(log, op, "start"); + + /* load foo.add file if expected and present */ + if (op == APPEND_OP || op == COMPRESS_OP) { + strcpy(log->end, ".add"); + if (stat(log->path, &st) == 0 && st.st_size) { + len = (size_t)(st.st_size); + if ((off_t)len != st.st_size || + (data = malloc(st.st_size)) == NULL) { + log_log(log, op, "allocation failure"); + return -2; + } + if ((fd = open(log->path, O_RDONLY, 0)) < 0) { + log_log(log, op, ".add file read failure"); + return -1; + } + ret = (size_t)read(fd, data, len) != len; + close(fd); + if (ret) { + log_log(log, op, ".add file read failure"); + return -1; + } + log_log(log, op, "loaded .add file"); + } + else + log_log(log, op, "missing .add file!"); + } + + /* recover the interrupted operation */ + switch (op) { + case APPEND_OP: + ret = log_append(log, data, len); + break; + case COMPRESS_OP: + ret = log_compress(log, data, len); + break; + case REPLACE_OP: + ret = log_replace(log); + } + + /* log status */ + log_log(log, op, ret ? "failure" : "complete"); + + /* clean up */ + if (data != NULL) + free(data); + return ret; +} + +/* Close the foo.gz file (if open) and release the lock. */ +local void log_close(struct log *log) +{ + if (log->fd >= 0) + close(log->fd); + log->fd = -1; + log_unlock(log); +} + +/* Open foo.gz, verify the header, and load the extra field contents, after + first creating the foo.lock file to gain exclusive access to the foo.* + files. If foo.gz does not exist or is empty, then write the initial header, + extra, and body content of an empty foo.gz log file. If there is an error + creating the lock file due to access restrictions, or an error reading or + writing the foo.gz file, or if the foo.gz file is not a proper log file for + this object (e.g. not a gzip file or does not contain the expected extra + field), then return true. If there is an error, the lock is released. + Otherwise, the lock is left in place. */ +local int log_open(struct log *log) +{ + int op; + + /* release open file resource if left over -- can occur if lock lost + between gzlog_open() and gzlog_write() */ + if (log->fd >= 0) + close(log->fd); + log->fd = -1; + + /* negotiate exclusive access */ + if (log_lock(log) < 0) + return -1; + + /* open the log file, foo.gz */ + strcpy(log->end, ".gz"); + log->fd = open(log->path, O_RDWR | O_CREAT, 0644); + if (log->fd < 0) { + log_close(log); + return -1; + } + + /* if new, initialize foo.gz with an empty log, delete old dictionary */ + if (lseek(log->fd, 0, SEEK_END) == 0) { + if (write(log->fd, log_gzhead, HEAD) != HEAD || + write(log->fd, log_gzext, EXTRA) != EXTRA || + write(log->fd, log_gzbody, BODY) != BODY) { + log_close(log); + return -1; + } + strcpy(log->end, ".dict"); + unlink(log->path); + } + + /* verify log file and load extra field information */ + if ((op = log_head(log)) < 0) { + log_close(log); + return -1; + } + + /* check for interrupted process and if so, recover */ + if (op != NO_OP && log_recover(log, op)) { + log_close(log); + return -1; + } + + /* touch the lock file to prevent another process from grabbing it */ + log_touch(log); + return 0; +} + +/* See gzlog.h for the description of the external methods below */ +gzlog *gzlog_open(char *path) +{ + size_t n; + struct log *log; + + /* check arguments */ + if (path == NULL || *path == 0) + return NULL; + + /* allocate and initialize log structure */ + log = malloc(sizeof(struct log)); + if (log == NULL) + return NULL; + strcpy(log->id, LOGID); + log->fd = -1; + + /* save path and end of path for name construction */ + n = strlen(path); + log->path = malloc(n + 9); /* allow for ".repairs" */ + if (log->path == NULL) { + free(log); + return NULL; + } + strcpy(log->path, path); + log->end = log->path + n; + + /* gain exclusive access and verify log file -- may perform a + recovery operation if needed */ + if (log_open(log)) { + free(log->path); + free(log); + return NULL; + } + + /* return pointer to log structure */ + return log; +} + +/* gzlog_compress() return values: + 0: all good + -1: file i/o error (usually access issue) + -2: memory allocation failure + -3: invalid log pointer argument */ +int gzlog_compress(gzlog *logd) +{ + int fd, ret; + uint block; + size_t len, next; + unsigned char *data, buf[5]; + struct log *log = logd; + + /* check arguments */ + if (log == NULL || strcmp(log->id, LOGID)) + return -3; + + /* see if we lost the lock -- if so get it again and reload the extra + field information (it probably changed), recover last operation if + necessary */ + if (log_check(log) && log_open(log)) + return -1; + + /* create space for uncompressed data */ + len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) + + log->stored; + if ((data = malloc(len)) == NULL) + return -2; + + /* do statement here is just a cheap trick for error handling */ + do { + /* read in the uncompressed data */ + if (lseek(log->fd, log->first - 1, SEEK_SET) < 0) + break; + next = 0; + while (next < len) { + if (read(log->fd, buf, 5) != 5) + break; + block = PULL2(buf + 1); + if (next + block > len || + read(log->fd, (char *)data + next, block) != block) + break; + next += block; + } + if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored) + break; + log_touch(log); + + /* write the uncompressed data to the .add file */ + strcpy(log->end, ".add"); + fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + break; + ret = (size_t)write(fd, data, len) != len; + if (ret | close(fd)) + break; + log_touch(log); + + /* write the dictionary for the next compress to the .temp file */ + strcpy(log->end, ".temp"); + fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + break; + next = DICT > len ? len : DICT; + ret = (size_t)write(fd, (char *)data + len - next, next) != next; + if (ret | close(fd)) + break; + log_touch(log); + + /* roll back to compressed data, mark the compress in progress */ + log->last = log->first; + log->stored = 0; + if (log_mark(log, COMPRESS_OP)) + break; + BAIL(7); + + /* compress and append the data (clears mark) */ + ret = log_compress(log, data, len); + free(data); + return ret; + } while (0); + + /* broke out of do above on i/o error */ + free(data); + return -1; +} + +/* gzlog_write() return values: + 0: all good + -1: file i/o error (usually access issue) + -2: memory allocation failure + -3: invalid log pointer argument */ +int gzlog_write(gzlog *logd, void *data, size_t len) +{ + int fd, ret; + struct log *log = logd; + + /* check arguments */ + if (log == NULL || strcmp(log->id, LOGID)) + return -3; + if (data == NULL || len <= 0) + return 0; + + /* see if we lost the lock -- if so get it again and reload the extra + field information (it probably changed), recover last operation if + necessary */ + if (log_check(log) && log_open(log)) + return -1; + + /* create and write .add file */ + strcpy(log->end, ".add"); + fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + return -1; + ret = (size_t)write(fd, data, len) != len; + if (ret | close(fd)) + return -1; + log_touch(log); + + /* mark log file with append in progress */ + if (log_mark(log, APPEND_OP)) + return -1; + BAIL(8); + + /* append data (clears mark) */ + if (log_append(log, data, len)) + return -1; + + /* check to see if it's time to compress -- if not, then done */ + if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER) + return 0; + + /* time to compress */ + return gzlog_compress(log); +} + +/* gzlog_close() return values: + 0: ok + -3: invalid log pointer argument */ +int gzlog_close(gzlog *logd) +{ + struct log *log = logd; + + /* check arguments */ + if (log == NULL || strcmp(log->id, LOGID)) + return -3; + + /* close the log file and release the lock */ + log_close(log); + + /* free structure and return */ + if (log->path != NULL) + free(log->path); + strcpy(log->id, "bad"); + free(log); + return 0; +} diff --git a/src/external/zlib-1.2.11/examples/gzlog.h b/src/external/zlib-1.2.11/examples/gzlog.h new file mode 100644 index 000000000..86f0cecba --- /dev/null +++ b/src/external/zlib-1.2.11/examples/gzlog.h @@ -0,0 +1,91 @@ +/* gzlog.h + Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved + version 2.2, 14 Aug 2012 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* Version History: + 1.0 26 Nov 2004 First version + 2.0 25 Apr 2008 Complete redesign for recovery of interrupted operations + Interface changed slightly in that now path is a prefix + Compression now occurs as needed during gzlog_write() + gzlog_write() now always leaves the log file as valid gzip + 2.1 8 Jul 2012 Fix argument checks in gzlog_compress() and gzlog_write() + 2.2 14 Aug 2012 Clean up signed comparisons + */ + +/* + The gzlog object allows writing short messages to a gzipped log file, + opening the log file locked for small bursts, and then closing it. The log + object works by appending stored (uncompressed) data to the gzip file until + 1 MB has been accumulated. At that time, the stored data is compressed, and + replaces the uncompressed data in the file. The log file is truncated to + its new size at that time. After each write operation, the log file is a + valid gzip file that can decompressed to recover what was written. + + The gzlog operations can be interupted at any point due to an application or + system crash, and the log file will be recovered the next time the log is + opened with gzlog_open(). + */ + +#ifndef GZLOG_H +#define GZLOG_H + +/* gzlog object type */ +typedef void gzlog; + +/* Open a gzlog object, creating the log file if it does not exist. Return + NULL on error. Note that gzlog_open() could take a while to complete if it + has to wait to verify that a lock is stale (possibly for five minutes), or + if there is significant contention with other instantiations of this object + when locking the resource. path is the prefix of the file names created by + this object. If path is "foo", then the log file will be "foo.gz", and + other auxiliary files will be created and destroyed during the process: + "foo.dict" for a compression dictionary, "foo.temp" for a temporary (next) + dictionary, "foo.add" for data being added or compressed, "foo.lock" for the + lock file, and "foo.repairs" to log recovery operations performed due to + interrupted gzlog operations. A gzlog_open() followed by a gzlog_close() + will recover a previously interrupted operation, if any. */ +gzlog *gzlog_open(char *path); + +/* Write to a gzlog object. Return zero on success, -1 if there is a file i/o + error on any of the gzlog files (this should not happen if gzlog_open() + succeeded, unless the device has run out of space or leftover auxiliary + files have permissions or ownership that prevent their use), -2 if there is + a memory allocation failure, or -3 if the log argument is invalid (e.g. if + it was not created by gzlog_open()). This function will write data to the + file uncompressed, until 1 MB has been accumulated, at which time that data + will be compressed. The log file will be a valid gzip file upon successful + return. */ +int gzlog_write(gzlog *log, void *data, size_t len); + +/* Force compression of any uncompressed data in the log. This should be used + sparingly, if at all. The main application would be when a log file will + not be appended to again. If this is used to compress frequently while + appending, it will both significantly increase the execution time and + reduce the compression ratio. The return codes are the same as for + gzlog_write(). */ +int gzlog_compress(gzlog *log); + +/* Close a gzlog object. Return zero on success, -3 if the log argument is + invalid. The log object is freed, and so cannot be referenced again. */ +int gzlog_close(gzlog *log); + +#endif diff --git a/src/external/zlib-1.2.11/examples/zlib_how.html b/src/external/zlib-1.2.11/examples/zlib_how.html new file mode 100644 index 000000000..444ff1c9a --- /dev/null +++ b/src/external/zlib-1.2.11/examples/zlib_how.html @@ -0,0 +1,545 @@ + + + + +zlib Usage Example + + + +

zlib Usage Example

+We often get questions about how the deflate() and inflate() functions should be used. +Users wonder when they should provide more input, when they should use more output, +what to do with a Z_BUF_ERROR, how to make sure the process terminates properly, and +so on. So for those who have read zlib.h (a few times), and +would like further edification, below is an annotated example in C of simple routines to compress and decompress +from an input file to an output file using deflate() and inflate() respectively. The +annotations are interspersed between lines of the code. So please read between the lines. +We hope this helps explain some of the intricacies of zlib. +

+Without further adieu, here is the program zpipe.c: +


+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.4  11 December 2005  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
+   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
+                     Avoid some compiler warnings for input and output buffers
+ */
+
+We now include the header files for the required definitions. From +stdio.h we use fopen(), fread(), fwrite(), +feof(), ferror(), and fclose() for file i/o, and +fputs() for error messages. From string.h we use +strcmp() for command line argument processing. +From assert.h we use the assert() macro. +From zlib.h +we use the basic compression functions deflateInit(), +deflate(), and deflateEnd(), and the basic decompression +functions inflateInit(), inflate(), and +inflateEnd(). +

+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+This is an ugly hack required to avoid corruption of the input and output data on +Windows/MS-DOS systems. Without this, those systems would assume that the input and output +files are text, and try to convert the end-of-line characters from one standard to +another. That would corrupt binary data, and in particular would render the compressed data unusable. +This sets the input and output to binary which suppresses the end-of-line conversions. +SET_BINARY_MODE() will be used later on stdin and stdout, at the beginning of main(). +

+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+CHUNK is simply the buffer size for feeding data to and pulling data +from the zlib routines. Larger buffer sizes would be more efficient, +especially for inflate(). If the memory is available, buffers sizes +on the order of 128K or 256K bytes should be used. +

+#define CHUNK 16384
+
+The def() routine compresses data from an input file to an output file. The output data +will be in the zlib format, which is different from the gzip or zip +formats. The zlib format has a very small header of only two bytes to identify it as +a zlib stream and to provide decoding information, and a four-byte trailer with a fast +check value to verify the integrity of the uncompressed data after decoding. +

+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+
+Here are the local variables for def(). ret will be used for zlib +return codes. flush will keep track of the current flushing state for deflate(), +which is either no flushing, or flush to completion after the end of the input file is reached. +have is the amount of data returned from deflate(). The strm structure +is used to pass information to and from the zlib routines, and to maintain the +deflate() state. in and out are the input and output buffers for +deflate(). +

+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+The first thing we do is to initialize the zlib state for compression using +deflateInit(). This must be done before the first use of deflate(). +The zalloc, zfree, and opaque fields in the strm +structure must be initialized before calling deflateInit(). Here they are +set to the zlib constant Z_NULL to request that zlib use +the default memory allocation routines. An application may also choose to provide +custom memory allocation routines here. deflateInit() will allocate on the +order of 256K bytes for the internal state. +(See zlib Technical Details.) +

+deflateInit() is called with a pointer to the structure to be initialized and +the compression level, which is an integer in the range of -1 to 9. Lower compression +levels result in faster execution, but less compression. Higher levels result in +greater compression, but slower execution. The zlib constant Z_DEFAULT_COMPRESSION, +equal to -1, +provides a good compromise between compression and speed and is equivalent to level 6. +Level 0 actually does no compression at all, and in fact expands the data slightly to produce +the zlib format (it is not a byte-for-byte copy of the input). +More advanced applications of zlib +may use deflateInit2() here instead. Such an application may want to reduce how +much memory will be used, at some price in compression. Or it may need to request a +gzip header and trailer instead of a zlib header and trailer, or raw +encoding with no header or trailer at all. +

+We must check the return value of deflateInit() against the zlib constant +Z_OK to make sure that it was able to +allocate memory for the internal state, and that the provided arguments were valid. +deflateInit() will also check that the version of zlib that the zlib.h +file came from matches the version of zlib actually linked with the program. This +is especially important for environments in which zlib is a shared library. +

+Note that an application can initialize multiple, independent zlib streams, which can +operate in parallel. The state information maintained in the structure allows the zlib +routines to be reentrant. +


+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&strm, level);
+    if (ret != Z_OK)
+        return ret;
+
+With the pleasantries out of the way, now we can get down to business. The outer do-loop +reads all of the input file and exits at the bottom of the loop once end-of-file is reached. +This loop contains the only call of deflate(). So we must make sure that all of the +input data has been processed and that all of the output data has been generated and consumed +before we fall out of the loop at the bottom. +

+    /* compress until end of file */
+    do {
+
+We start off by reading data from the input file. The number of bytes read is put directly +into avail_in, and a pointer to those bytes is put into next_in. We also +check to see if end-of-file on the input has been reached. If we are at the end of file, then flush is set to the +zlib constant Z_FINISH, which is later passed to deflate() to +indicate that this is the last chunk of input data to compress. We need to use feof() +to check for end-of-file as opposed to seeing if fewer than CHUNK bytes have been read. The +reason is that if the input file length is an exact multiple of CHUNK, we will miss +the fact that we got to the end-of-file, and not know to tell deflate() to finish +up the compressed stream. If we are not yet at the end of the input, then the zlib +constant Z_NO_FLUSH will be passed to deflate to indicate that we are still +in the middle of the uncompressed data. +

+If there is an error in reading from the input file, the process is aborted with +deflateEnd() being called to free the allocated zlib state before returning +the error. We wouldn't want a memory leak, now would we? deflateEnd() can be called +at any time after the state has been initialized. Once that's done, deflateInit() (or +deflateInit2()) would have to be called to start a new compression process. There is +no point here in checking the deflateEnd() return code. The deallocation can't fail. +


+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+
+The inner do-loop passes our chunk of input data to deflate(), and then +keeps calling deflate() until it is done producing output. Once there is no more +new output, deflate() is guaranteed to have consumed all of the input, i.e., +avail_in will be zero. +

+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+
+Output space is provided to deflate() by setting avail_out to the number +of available output bytes and next_out to a pointer to that space. +

+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+
+Now we call the compression engine itself, deflate(). It takes as many of the +avail_in bytes at next_in as it can process, and writes as many as +avail_out bytes to next_out. Those counters and pointers are then +updated past the input data consumed and the output data written. It is the amount of +output space available that may limit how much input is consumed. +Hence the inner loop to make sure that +all of the input is consumed by providing more output space each time. Since avail_in +and next_in are updated by deflate(), we don't have to mess with those +between deflate() calls until it's all used up. +

+The parameters to deflate() are a pointer to the strm structure containing +the input and output information and the internal compression engine state, and a parameter +indicating whether and how to flush data to the output. Normally deflate will consume +several K bytes of input data before producing any output (except for the header), in order +to accumulate statistics on the data for optimum compression. It will then put out a burst of +compressed data, and proceed to consume more input before the next burst. Eventually, +deflate() +must be told to terminate the stream, complete the compression with provided input data, and +write out the trailer check value. deflate() will continue to compress normally as long +as the flush parameter is Z_NO_FLUSH. Once the Z_FINISH parameter is provided, +deflate() will begin to complete the compressed output stream. However depending on how +much output space is provided, deflate() may have to be called several times until it +has provided the complete compressed stream, even after it has consumed all of the input. The flush +parameter must continue to be Z_FINISH for those subsequent calls. +

+There are other values of the flush parameter that are used in more advanced applications. You can +force deflate() to produce a burst of output that encodes all of the input data provided +so far, even if it wouldn't have otherwise, for example to control data latency on a link with +compressed data. You can also ask that deflate() do that as well as erase any history up to +that point so that what follows can be decompressed independently, for example for random access +applications. Both requests will degrade compression by an amount depending on how often such +requests are made. +

+deflate() has a return value that can indicate errors, yet we do not check it here. Why +not? Well, it turns out that deflate() can do no wrong here. Let's go through +deflate()'s return values and dispense with them one by one. The possible values are +Z_OK, Z_STREAM_END, Z_STREAM_ERROR, or Z_BUF_ERROR. Z_OK +is, well, ok. Z_STREAM_END is also ok and will be returned for the last call of +deflate(). This is already guaranteed by calling deflate() with Z_FINISH +until it has no more output. Z_STREAM_ERROR is only possible if the stream is not +initialized properly, but we did initialize it properly. There is no harm in checking for +Z_STREAM_ERROR here, for example to check for the possibility that some +other part of the application inadvertently clobbered the memory containing the zlib state. +Z_BUF_ERROR will be explained further below, but +suffice it to say that this is simply an indication that deflate() could not consume +more input or produce more output. deflate() can be called again with more output space +or more available input, which it will be in this code. +


+            ret = deflate(&strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+
+Now we compute how much output deflate() provided on the last call, which is the +difference between how much space was provided before the call, and how much output space +is still available after the call. Then that data, if any, is written to the output file. +We can then reuse the output buffer for the next call of deflate(). Again if there +is a file i/o error, we call deflateEnd() before returning to avoid a memory leak. +

+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&strm);
+                return Z_ERRNO;
+            }
+
+The inner do-loop is repeated until the last deflate() call fails to fill the +provided output buffer. Then we know that deflate() has done as much as it can with +the provided input, and that all of that input has been consumed. We can then fall out of this +loop and reuse the input buffer. +

+The way we tell that deflate() has no more output is by seeing that it did not fill +the output buffer, leaving avail_out greater than zero. However suppose that +deflate() has no more output, but just so happened to exactly fill the output buffer! +avail_out is zero, and we can't tell that deflate() has done all it can. +As far as we know, deflate() +has more output for us. So we call it again. But now deflate() produces no output +at all, and avail_out remains unchanged as CHUNK. That deflate() call +wasn't able to do anything, either consume input or produce output, and so it returns +Z_BUF_ERROR. (See, I told you I'd cover this later.) However this is not a problem at +all. Now we finally have the desired indication that deflate() is really done, +and so we drop out of the inner loop to provide more input to deflate(). +

+With flush set to Z_FINISH, this final set of deflate() calls will +complete the output stream. Once that is done, subsequent calls of deflate() would return +Z_STREAM_ERROR if the flush parameter is not Z_FINISH, and do no more processing +until the state is reinitialized. +

+Some applications of zlib have two loops that call deflate() +instead of the single inner loop we have here. The first loop would call +without flushing and feed all of the data to deflate(). The second loop would call +deflate() with no more +data and the Z_FINISH parameter to complete the process. As you can see from this +example, that can be avoided by simply keeping track of the current flush state. +


+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+
+Now we check to see if we have already processed all of the input file. That information was +saved in the flush variable, so we see if that was set to Z_FINISH. If so, +then we're done and we fall out of the outer loop. We're guaranteed to get Z_STREAM_END +from the last deflate() call, since we ran it until the last chunk of input was +consumed and all of the output was generated. +

+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+
+The process is complete, but we still need to deallocate the state to avoid a memory leak +(or rather more like a memory hemorrhage if you didn't do this). Then +finally we can return with a happy return value. +

+    /* clean up and return */
+    (void)deflateEnd(&strm);
+    return Z_OK;
+}
+
+Now we do the same thing for decompression in the inf() routine. inf() +decompresses what is hopefully a valid zlib stream from the input file and writes the +uncompressed data to the output file. Much of the discussion above for def() +applies to inf() as well, so the discussion here will focus on the differences between +the two. +

+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+
+The local variables have the same functionality as they do for def(). The +only difference is that there is no flush variable, since inflate() +can tell from the zlib stream itself when the stream is complete. +

+    int ret;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+The initialization of the state is the same, except that there is no compression level, +of course, and two more elements of the structure are initialized. avail_in +and next_in must be initialized before calling inflateInit(). This +is because the application has the option to provide the start of the zlib stream in +order for inflateInit() to have access to information about the compression +method to aid in memory allocation. In the current implementation of zlib +(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of +inflate() anyway. However those fields must be initialized since later versions +of zlib that provide more compression methods may take advantage of this interface. +In any case, no decompression is performed by inflateInit(), so the +avail_out and next_out fields do not need to be initialized before calling. +

+Here avail_in is set to zero and next_in is set to Z_NULL to +indicate that no input data is being provided. +


+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);
+    if (ret != Z_OK)
+        return ret;
+
+The outer do-loop decompresses input until inflate() indicates +that it has reached the end of the compressed data and has produced all of the uncompressed +output. This is in contrast to def() which processes all of the input file. +If end-of-file is reached before the compressed data self-terminates, then the compressed +data is incomplete and an error is returned. +

+    /* decompress until deflate stream ends or end of file */
+    do {
+
+We read input data and set the strm structure accordingly. If we've reached the +end of the input file, then we leave the outer loop and report an error, since the +compressed data is incomplete. Note that we may read more data than is eventually consumed +by inflate(), if the input file continues past the zlib stream. +For applications where zlib streams are embedded in other data, this routine would +need to be modified to return the unused data, or at least indicate how much of the input +data was not used, so the application would know where to pick up after the zlib stream. +

+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+
+The inner do-loop has the same function it did in def(), which is to +keep calling inflate() until has generated all of the output it can with the +provided input. +

+        /* run inflate() on input until output buffer not full */
+        do {
+
+Just like in def(), the same output space is provided for each call of inflate(). +

+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+
+Now we run the decompression engine itself. There is no need to adjust the flush parameter, since +the zlib format is self-terminating. The main difference here is that there are +return values that we need to pay attention to. Z_DATA_ERROR +indicates that inflate() detected an error in the zlib compressed data format, +which means that either the data is not a zlib stream to begin with, or that the data was +corrupted somewhere along the way since it was compressed. The other error to be processed is +Z_MEM_ERROR, which can occur since memory allocation is deferred until inflate() +needs it, unlike deflate(), whose memory is allocated at the start by deflateInit(). +

+Advanced applications may use +deflateSetDictionary() to prime deflate() with a set of likely data to improve the +first 32K or so of compression. This is noted in the zlib header, so inflate() +requests that that dictionary be provided before it can start to decompress. Without the dictionary, +correct decompression is not possible. For this routine, we have no idea what the dictionary is, +so the Z_NEED_DICT indication is converted to a Z_DATA_ERROR. +

+inflate() can also return Z_STREAM_ERROR, which should not be possible here, +but could be checked for as noted above for def(). Z_BUF_ERROR does not need to be +checked for here, for the same reasons noted for def(). Z_STREAM_END will be +checked for later. +


+            ret = inflate(&strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&strm);
+                return ret;
+            }
+
+The output of inflate() is handled identically to that of deflate(). +

+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&strm);
+                return Z_ERRNO;
+            }
+
+The inner do-loop ends when inflate() has no more output as indicated +by not filling the output buffer, just as for deflate(). In this case, we cannot +assert that strm.avail_in will be zero, since the deflate stream may end before the file +does. +

+        } while (strm.avail_out == 0);
+
+The outer do-loop ends when inflate() reports that it has reached the +end of the input zlib stream, has completed the decompression and integrity +check, and has provided all of the output. This is indicated by the inflate() +return value Z_STREAM_END. The inner loop is guaranteed to leave ret +equal to Z_STREAM_END if the last chunk of the input file read contained the end +of the zlib stream. So if the return value is not Z_STREAM_END, the +loop continues to read more input. +

+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+
+At this point, decompression successfully completed, or we broke out of the loop due to no +more data being available from the input file. If the last inflate() return value +is not Z_STREAM_END, then the zlib stream was incomplete and a data error +is returned. Otherwise, we return with a happy return value. Of course, inflateEnd() +is called first to avoid a memory leak. +

+    /* clean up and return */
+    (void)inflateEnd(&strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+That ends the routines that directly use zlib. The following routines make this +a command-line program by running data through the above routines from stdin to +stdout, and handling any errors reported by def() or inf(). +

+zerr() is used to interpret the possible error codes from def() +and inf(), as detailed in their comments above, and print out an error message. +Note that these are only a subset of the possible return values from deflate() +and inflate(). +


+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+
+Here is the main() routine used to test def() and inf(). The +zpipe command is simply a compression pipe from stdin to stdout, if +no arguments are given, or it is a decompression pipe if zpipe -d is used. If any other +arguments are provided, no compression or decompression is performed. Instead a usage +message is displayed. Examples are zpipe < foo.txt > foo.txt.z to compress, and +zpipe -d < foo.txt.z > foo.txt to decompress. +

+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* avoid end-of-line conversions */
+    SET_BINARY_MODE(stdin);
+    SET_BINARY_MODE(stdout);
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
+        return 1;
+    }
+}
+
+
+Copyright (c) 2004, 2005 by Mark Adler
Last modified 11 December 2005
+ + diff --git a/src/external/zlib-1.2.11/examples/zpipe.c b/src/external/zlib-1.2.11/examples/zpipe.c new file mode 100644 index 000000000..83535d169 --- /dev/null +++ b/src/external/zlib-1.2.11/examples/zpipe.c @@ -0,0 +1,205 @@ +/* zpipe.c: example of proper use of zlib's inflate() and deflate() + Not copyrighted -- provided to the public domain + Version 1.4 11 December 2005 Mark Adler */ + +/* Version history: + 1.0 30 Oct 2004 First version + 1.1 8 Nov 2004 Add void casting for unused return values + Use switch statement for inflate() return values + 1.2 9 Nov 2004 Add assertions to document zlib guarantees + 1.3 6 Apr 2005 Remove incorrect assertion in inf() + 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions + Avoid some compiler warnings for input and output buffers + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define CHUNK 16384 + +/* Compress from file source to file dest until EOF on source. + def() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_STREAM_ERROR if an invalid compression + level is supplied, Z_VERSION_ERROR if the version of zlib.h and the + version of the library linked do not match, or Z_ERRNO if there is + an error reading or writing the files. */ +int def(FILE *source, FILE *dest, int level) +{ + int ret, flush; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK) + return ret; + + /* compress until end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)deflateEnd(&strm); + return Z_ERRNO; + } + flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; + strm.next_in = in; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = deflate(&strm, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)deflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); /* all input will be used */ + + /* done when last data in file processed */ + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); /* stream will be complete */ + + /* clean up and return */ + (void)deflateEnd(&strm); + return Z_OK; +} + +/* Decompress from file source to file dest until stream ends or EOF. + inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_DATA_ERROR if the deflate data is + invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and + the version of the library linked do not match, or Z_ERRNO if there + is an error reading or writing the files. */ +int inf(FILE *source, FILE *dest) +{ + int ret; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + return ret; + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + if (strm.avail_in == 0) + break; + strm.next_in = in; + + /* run inflate() on input until output buffer not full */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + + /* done when inflate() says it's done */ + } while (ret != Z_STREAM_END); + + /* clean up and return */ + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + +/* report a zlib or i/o error */ +void zerr(int ret) +{ + fputs("zpipe: ", stderr); + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + fputs("error reading stdin\n", stderr); + if (ferror(stdout)) + fputs("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); + } +} + +/* compress or decompress from stdin to stdout */ +int main(int argc, char **argv) +{ + int ret; + + /* avoid end-of-line conversions */ + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + /* do compression if no arguments */ + if (argc == 1) { + ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK) + zerr(ret); + return ret; + } + + /* do decompression if -d specified */ + else if (argc == 2 && strcmp(argv[1], "-d") == 0) { + ret = inf(stdin, stdout); + if (ret != Z_OK) + zerr(ret); + return ret; + } + + /* otherwise, report usage */ + else { + fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr); + return 1; + } +} diff --git a/src/external/zlib-1.2.11/examples/zran.c b/src/external/zlib-1.2.11/examples/zran.c new file mode 100644 index 000000000..4fec6594a --- /dev/null +++ b/src/external/zlib-1.2.11/examples/zran.c @@ -0,0 +1,409 @@ +/* zran.c -- example of zlib/gzip stream indexing and random access + * Copyright (C) 2005, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + Version 1.1 29 Sep 2012 Mark Adler */ + +/* Version History: + 1.0 29 May 2005 First version + 1.1 29 Sep 2012 Fix memory reallocation error + */ + +/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary() + for random access of a compressed file. A file containing a zlib or gzip + stream is provided on the command line. The compressed stream is decoded in + its entirety, and an index built with access points about every SPAN bytes + in the uncompressed output. The compressed file is left open, and can then + be read randomly, having to decompress on the average SPAN/2 uncompressed + bytes before getting to the desired block of data. + + An access point can be created at the start of any deflate block, by saving + the starting file offset and bit of that block, and the 32K bytes of + uncompressed data that precede that block. Also the uncompressed offset of + that block is saved to provide a referece for locating a desired starting + point in the uncompressed stream. build_index() works by decompressing the + input zlib or gzip stream a block at a time, and at the end of each block + deciding if enough uncompressed data has gone by to justify the creation of + a new access point. If so, that point is saved in a data structure that + grows as needed to accommodate the points. + + To use the index, an offset in the uncompressed data is provided, for which + the latest access point at or preceding that offset is located in the index. + The input file is positioned to the specified location in the index, and if + necessary the first few bits of the compressed data is read from the file. + inflate is initialized with those bits and the 32K of uncompressed data, and + the decompression then proceeds until the desired offset in the file is + reached. Then the decompression continues to read the desired uncompressed + data from the file. + + Another approach would be to generate the index on demand. In that case, + requests for random access reads from the compressed data would try to use + the index, but if a read far enough past the end of the index is required, + then further index entries would be generated and added. + + There is some fair bit of overhead to starting inflation for the random + access, mainly copying the 32K byte dictionary. So if small pieces of the + file are being accessed, it would make sense to implement a cache to hold + some lookahead and avoid many calls to extract() for small lengths. + + Another way to build an index would be to use inflateCopy(). That would + not be constrained to have access points at block boundaries, but requires + more memory per access point, and also cannot be saved to file due to the + use of pointers in the state. The approach here allows for storage of the + index in a file. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +#define SPAN 1048576L /* desired distance between access points */ +#define WINSIZE 32768U /* sliding window size */ +#define CHUNK 16384 /* file input buffer size */ + +/* access point entry */ +struct point { + off_t out; /* corresponding offset in uncompressed data */ + off_t in; /* offset in input file of first full byte */ + int bits; /* number of bits (1-7) from byte at in - 1, or 0 */ + unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */ +}; + +/* access point list */ +struct access { + int have; /* number of list entries filled in */ + int size; /* number of list entries allocated */ + struct point *list; /* allocated list */ +}; + +/* Deallocate an index built by build_index() */ +local void free_index(struct access *index) +{ + if (index != NULL) { + free(index->list); + free(index); + } +} + +/* Add an entry to the access point list. If out of memory, deallocate the + existing list and return NULL. */ +local struct access *addpoint(struct access *index, int bits, + off_t in, off_t out, unsigned left, unsigned char *window) +{ + struct point *next; + + /* if list is empty, create it (start with eight points) */ + if (index == NULL) { + index = malloc(sizeof(struct access)); + if (index == NULL) return NULL; + index->list = malloc(sizeof(struct point) << 3); + if (index->list == NULL) { + free(index); + return NULL; + } + index->size = 8; + index->have = 0; + } + + /* if list is full, make it bigger */ + else if (index->have == index->size) { + index->size <<= 1; + next = realloc(index->list, sizeof(struct point) * index->size); + if (next == NULL) { + free_index(index); + return NULL; + } + index->list = next; + } + + /* fill in entry and increment how many we have */ + next = index->list + index->have; + next->bits = bits; + next->in = in; + next->out = out; + if (left) + memcpy(next->window, window + WINSIZE - left, left); + if (left < WINSIZE) + memcpy(next->window + left, window, WINSIZE - left); + index->have++; + + /* return list, possibly reallocated */ + return index; +} + +/* Make one entire pass through the compressed stream and build an index, with + access points about every span bytes of uncompressed output -- span is + chosen to balance the speed of random access against the memory requirements + of the list, about 32K bytes per access point. Note that data after the end + of the first zlib or gzip stream in the file is ignored. build_index() + returns the number of access points on success (>= 1), Z_MEM_ERROR for out + of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a + file read error. On success, *built points to the resulting index. */ +local int build_index(FILE *in, off_t span, struct access **built) +{ + int ret; + off_t totin, totout; /* our own total counters to avoid 4GB limit */ + off_t last; /* totout value of last access point */ + struct access *index; /* access points being generated */ + z_stream strm; + unsigned char input[CHUNK]; + unsigned char window[WINSIZE]; + + /* initialize inflate */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, 47); /* automatic zlib or gzip decoding */ + if (ret != Z_OK) + return ret; + + /* inflate the input, maintain a sliding window, and build an index -- this + also validates the integrity of the compressed data using the check + information at the end of the gzip or zlib stream */ + totin = totout = last = 0; + index = NULL; /* will be allocated by first addpoint() */ + strm.avail_out = 0; + do { + /* get some compressed data from input file */ + strm.avail_in = fread(input, 1, CHUNK, in); + if (ferror(in)) { + ret = Z_ERRNO; + goto build_index_error; + } + if (strm.avail_in == 0) { + ret = Z_DATA_ERROR; + goto build_index_error; + } + strm.next_in = input; + + /* process all of that, or until end of stream */ + do { + /* reset sliding window if necessary */ + if (strm.avail_out == 0) { + strm.avail_out = WINSIZE; + strm.next_out = window; + } + + /* inflate until out of input, output, or at end of block -- + update the total input and output counters */ + totin += strm.avail_in; + totout += strm.avail_out; + ret = inflate(&strm, Z_BLOCK); /* return at end of block */ + totin -= strm.avail_in; + totout -= strm.avail_out; + if (ret == Z_NEED_DICT) + ret = Z_DATA_ERROR; + if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) + goto build_index_error; + if (ret == Z_STREAM_END) + break; + + /* if at end of block, consider adding an index entry (note that if + data_type indicates an end-of-block, then all of the + uncompressed data from that block has been delivered, and none + of the compressed data after that block has been consumed, + except for up to seven bits) -- the totout == 0 provides an + entry point after the zlib or gzip header, and assures that the + index always has at least one access point; we avoid creating an + access point after the last block by checking bit 6 of data_type + */ + if ((strm.data_type & 128) && !(strm.data_type & 64) && + (totout == 0 || totout - last > span)) { + index = addpoint(index, strm.data_type & 7, totin, + totout, strm.avail_out, window); + if (index == NULL) { + ret = Z_MEM_ERROR; + goto build_index_error; + } + last = totout; + } + } while (strm.avail_in != 0); + } while (ret != Z_STREAM_END); + + /* clean up and return index (release unused entries in list) */ + (void)inflateEnd(&strm); + index->list = realloc(index->list, sizeof(struct point) * index->have); + index->size = index->have; + *built = index; + return index->size; + + /* return error */ + build_index_error: + (void)inflateEnd(&strm); + if (index != NULL) + free_index(index); + return ret; +} + +/* Use the index to read len bytes from offset into buf, return bytes read or + negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past + the end of the uncompressed data, then extract() will return a value less + than len, indicating how much as actually read into buf. This function + should not return a data error unless the file was modified since the index + was generated. extract() may also return Z_ERRNO if there is an error on + reading or seeking the input file. */ +local int extract(FILE *in, struct access *index, off_t offset, + unsigned char *buf, int len) +{ + int ret, skip; + z_stream strm; + struct point *here; + unsigned char input[CHUNK]; + unsigned char discard[WINSIZE]; + + /* proceed only if something reasonable to do */ + if (len < 0) + return 0; + + /* find where in stream to start */ + here = index->list; + ret = index->have; + while (--ret && here[1].out <= offset) + here++; + + /* initialize file and inflate state to start there */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -15); /* raw inflate */ + if (ret != Z_OK) + return ret; + ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET); + if (ret == -1) + goto extract_ret; + if (here->bits) { + ret = getc(in); + if (ret == -1) { + ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR; + goto extract_ret; + } + (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits)); + } + (void)inflateSetDictionary(&strm, here->window, WINSIZE); + + /* skip uncompressed bytes until offset reached, then satisfy request */ + offset -= here->out; + strm.avail_in = 0; + skip = 1; /* while skipping to offset */ + do { + /* define where to put uncompressed data, and how much */ + if (offset == 0 && skip) { /* at offset now */ + strm.avail_out = len; + strm.next_out = buf; + skip = 0; /* only do this once */ + } + if (offset > WINSIZE) { /* skip WINSIZE bytes */ + strm.avail_out = WINSIZE; + strm.next_out = discard; + offset -= WINSIZE; + } + else if (offset != 0) { /* last skip */ + strm.avail_out = (unsigned)offset; + strm.next_out = discard; + offset = 0; + } + + /* uncompress until avail_out filled, or end of stream */ + do { + if (strm.avail_in == 0) { + strm.avail_in = fread(input, 1, CHUNK, in); + if (ferror(in)) { + ret = Z_ERRNO; + goto extract_ret; + } + if (strm.avail_in == 0) { + ret = Z_DATA_ERROR; + goto extract_ret; + } + strm.next_in = input; + } + ret = inflate(&strm, Z_NO_FLUSH); /* normal inflate */ + if (ret == Z_NEED_DICT) + ret = Z_DATA_ERROR; + if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) + goto extract_ret; + if (ret == Z_STREAM_END) + break; + } while (strm.avail_out != 0); + + /* if reach end of stream, then don't keep trying to get more */ + if (ret == Z_STREAM_END) + break; + + /* do until offset reached and requested data read, or stream ends */ + } while (skip); + + /* compute number of uncompressed bytes read after offset */ + ret = skip ? 0 : len - strm.avail_out; + + /* clean up and return bytes read or error */ + extract_ret: + (void)inflateEnd(&strm); + return ret; +} + +/* Demonstrate the use of build_index() and extract() by processing the file + provided on the command line, and the extracting 16K from about 2/3rds of + the way through the uncompressed output, and writing that to stdout. */ +int main(int argc, char **argv) +{ + int len; + off_t offset; + FILE *in; + struct access *index = NULL; + unsigned char buf[CHUNK]; + + /* open input file */ + if (argc != 2) { + fprintf(stderr, "usage: zran file.gz\n"); + return 1; + } + in = fopen(argv[1], "rb"); + if (in == NULL) { + fprintf(stderr, "zran: could not open %s for reading\n", argv[1]); + return 1; + } + + /* build index */ + len = build_index(in, SPAN, &index); + if (len < 0) { + fclose(in); + switch (len) { + case Z_MEM_ERROR: + fprintf(stderr, "zran: out of memory\n"); + break; + case Z_DATA_ERROR: + fprintf(stderr, "zran: compressed data error in %s\n", argv[1]); + break; + case Z_ERRNO: + fprintf(stderr, "zran: read error on %s\n", argv[1]); + break; + default: + fprintf(stderr, "zran: error %d while building index\n", len); + } + return 1; + } + fprintf(stderr, "zran: built index with %d access points\n", len); + + /* use index by reading some bytes from an arbitrary offset */ + offset = (index->list[index->have - 1].out << 1) / 3; + len = extract(in, index, offset, buf, CHUNK); + if (len < 0) + fprintf(stderr, "zran: extraction failed: %s error\n", + len == Z_MEM_ERROR ? "out of memory" : "input corrupted"); + else { + fwrite(buf, 1, len, stdout); + fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset); + } + + /* clean up and exit */ + free_index(index); + fclose(in); + return 0; +} diff --git a/src/external/zlib-1.2.11/gzclose.c b/src/external/zlib-1.2.11/gzclose.c new file mode 100644 index 000000000..caeb99a31 --- /dev/null +++ b/src/external/zlib-1.2.11/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/src/external/zlib-1.2.11/gzguts.h b/src/external/zlib-1.2.11/gzguts.h new file mode 100644 index 000000000..990a4d251 --- /dev/null +++ b/src/external/zlib-1.2.11/gzguts.h @@ -0,0 +1,218 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/src/external/zlib-1.2.11/gzlib.c b/src/external/zlib-1.2.11/gzlib.c new file mode 100644 index 000000000..4105e6aff --- /dev/null +++ b/src/external/zlib-1.2.11/gzlib.c @@ -0,0 +1,637 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + z_size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (z_size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef WIDECHAR + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/src/external/zlib-1.2.11/gzread.c b/src/external/zlib-1.2.11/gzread.c new file mode 100644 index 000000000..956b91ea7 --- /dev/null +++ b/src/external/zlib-1.2.11/gzread.c @@ -0,0 +1,654 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); +local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + unsigned get, max = ((unsigned)-1 >> 2) + 1; + + *have = 0; + do { + get = len - *have; + if (get > max) + get = max; + ret = read(state->fd, buf + *have, get); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +local z_size_t gz_read(state, buf, len) + gz_statep state; + voidp buf; + z_size_t len; +{ + z_size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = -1; + if (n > len) + n = len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfread(buf, size, nitems, file) + voidp buf; + z_size_t size; + z_size_t nitems; + gzFile file; +{ + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + ret = gz_read(state, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/src/external/zlib-1.2.11/gzwrite.c b/src/external/zlib-1.2.11/gzwrite.c new file mode 100644 index 000000000..c7b5651d7 --- /dev/null +++ b/src/external/zlib-1.2.11/gzwrite.c @@ -0,0 +1,665 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); +local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, writ; + unsigned have, put, max = ((unsigned)-1 >> 2) + 1; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + while (strm->avail_in) { + put = strm->avail_in > max ? max : strm->avail_in; + writ = write(state->fd, strm->next_in, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in -= (unsigned)writ; + strm->next_in += writ; + } + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + while (strm->next_out > state->x.next) { + put = strm->next_out - state->x.next > (int)max ? max : + (unsigned)(strm->next_out - state->x.next); + writ = write(state->fd, state->x.next, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + state->x.next += writ; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* Write len bytes from buf to file. Return the number of bytes written. If + the returned value is less than len, then there was an error. */ +local z_size_t gz_write(state, buf, len) + gz_statep state; + voidpc buf; + z_size_t len; +{ + z_size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const Bytef *)buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) + voidpc buf; + z_size_t size; + z_size_t nitems; + gzFile file; +{ + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(str); + ret = gz_write(state, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) +{ + int len; + unsigned left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(next, format, va); + for (len = 0; len < state->size; len++) + if (next[len] == 0) break; +# else + len = vsprintf(next, format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(next, state->size, format, va); + len = strlen(next); +# else + len = vsnprintf(next, state->size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memcpy(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + unsigned len, left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return Z_STREAM_ERROR; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->error; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->error; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(strm->next_in + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (next[len] == 0) + break; +# else + len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, + a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(next); +# else + len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memcpy(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return (int)len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/src/external/zlib-1.2.11/infback.c b/src/external/zlib-1.2.11/infback.c new file mode 100644 index 000000000..59679ecbf --- /dev/null +++ b/src/external/zlib-1.2.11/infback.c @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = (uInt)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/src/external/zlib-1.2.11/inffast.c b/src/external/zlib-1.2.11/inffast.c new file mode 100644 index 000000000..0dbd1dbc0 --- /dev/null +++ b/src/external/zlib-1.2.11/inffast.c @@ -0,0 +1,323 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - 5); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + *out++ = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = window; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } while (len > 2); + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/src/external/zlib-1.2.11/inffast.h b/src/external/zlib-1.2.11/inffast.h new file mode 100644 index 000000000..e5c1aa4ca --- /dev/null +++ b/src/external/zlib-1.2.11/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/src/external/zlib-1.2.11/inffixed.h b/src/external/zlib-1.2.11/inffixed.h new file mode 100644 index 000000000..d62832776 --- /dev/null +++ b/src/external/zlib-1.2.11/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/src/external/zlib-1.2.11/inflate.c b/src/external/zlib-1.2.11/inflate.c new file mode 100644 index 000000000..ac333e8c2 --- /dev/null +++ b/src/external/zlib-1.2.11/inflate.c @@ -0,0 +1,1561 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local int inflateStateCheck OF((z_streamp strm)); +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, + unsigned len)); + +local int inflateStateCheck(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, end, copy) +z_streamp strm; +const Bytef *end; +unsigned copy; +{ + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > 15 || len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +const unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + (void)subvert; + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int ZEXPORT inflateValidate(strm, check) +z_streamp strm; +int check; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) + return -(1L << 16); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long ZEXPORT inflateCodesUsed(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/src/external/zlib-1.2.11/inflate.h b/src/external/zlib-1.2.11/inflate.h new file mode 100644 index 000000000..a46cce6b6 --- /dev/null +++ b/src/external/zlib-1.2.11/inflate.h @@ -0,0 +1,125 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/src/external/zlib-1.2.11/inftrees.c b/src/external/zlib-1.2.11/inftrees.c new file mode 100644 index 000000000..2ea08fc13 --- /dev/null +++ b/src/external/zlib-1.2.11/inftrees.c @@ -0,0 +1,304 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/src/external/zlib-1.2.11/inftrees.h b/src/external/zlib-1.2.11/inftrees.h new file mode 100644 index 000000000..baa53a0b1 --- /dev/null +++ b/src/external/zlib-1.2.11/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/src/external/zlib-1.2.11/make_vms.com b/src/external/zlib-1.2.11/make_vms.com new file mode 100644 index 000000000..65e9d0cbc --- /dev/null +++ b/src/external/zlib-1.2.11/make_vms.com @@ -0,0 +1,867 @@ +$! make libz under VMS written by +$! Martin P.J. Zinser +$! +$! In case of problems with the install you might contact me at +$! zinser@zinser.no-ip.info(preferred) or +$! martin.zinser@eurexchange.com (work) +$! +$! Make procedure history for Zlib +$! +$!------------------------------------------------------------------------------ +$! Version history +$! 0.01 20060120 First version to receive a number +$! 0.02 20061008 Adapt to new Makefile.in +$! 0.03 20091224 Add support for large file check +$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite +$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in +$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples +$! subdir path, update module search in makefile.in +$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned +$! shared image creation +$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared +$! image +$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)). +$! "" -> automatic, preference: MMK, MMS, built-in. +$! +$ on error then goto err_exit +$! +$ true = 1 +$ false = 0 +$ tmpnam = "temp_" + f$getjpi("","pid") +$ tt = tmpnam + ".txt" +$ tc = tmpnam + ".c" +$ th = tmpnam + ".h" +$ define/nolog tconfig 'th' +$ its_decc = false +$ its_vaxc = false +$ its_gnuc = false +$ s_case = False +$! +$! Setup variables holding "config" information +$! +$ Make = "''p1'" +$ name = "Zlib" +$ version = "?.?.?" +$ v_string = "ZLIB_VERSION" +$ v_file = "zlib.h" +$ ccopt = "/include = []" +$ lopts = "" +$ dnsrl = "" +$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in" +$ conf_check_string = "" +$ linkonly = false +$ optfile = name + ".opt" +$ mapfile = name + ".map" +$ libdefs = "" +$ vax = f$getsyi("HW_MODEL").lt.1024 +$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096 +$ ia64 = f$getsyi("HW_MODEL").ge.4096 +$! +$! 2012-03-05 SMS. +$! Why is this needed? And if it is needed, why not simply ".not. vax"? +$! +$!!! if axp .or. ia64 then set proc/parse=extended +$! +$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL") +$ mydef = F$parse(whoami,,,"DEVICE") +$ mydir = f$parse(whoami,,,"DIRECTORY") - "][" +$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type") +$! +$! Check for MMK/MMS +$! +$ if (Make .eqs. "") +$ then +$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" +$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" +$ else +$ Make = f$edit( Make, "trim") +$ endif +$! +$ gosub find_version +$! +$ open/write topt tmp.opt +$ open/write optf 'optfile' +$! +$ gosub check_opts +$! +$! Look for the compiler used +$! +$ gosub check_compiler +$ close topt +$ close optf +$! +$ if its_decc +$ then +$ ccopt = "/prefix=all" + ccopt +$ if f$trnlnm("SYS") .eqs. "" +$ then +$ if axp +$ then +$ define sys sys$library: +$ else +$ ccopt = "/decc" + ccopt +$ define sys decc$library_include: +$ endif +$ endif +$! +$! 2012-03-05 SMS. +$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX? +$! +$ if axp .or. ia64 +$ then +$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)" +$ s_case = true +$ endif +$ endif +$ if its_vaxc .or. its_gnuc +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ endif +$! +$! Build a fake configure input header +$! +$ open/write conf_hin config.hin +$ write conf_hin "#undef _LARGEFILE64_SOURCE" +$ close conf_hin +$! +$! +$ i = 0 +$FIND_ACONF: +$ fname = f$element(i,"#",aconf_in_file) +$ if fname .eqs. "#" then goto AMISS_ERR +$ if f$search(fname) .eqs. "" +$ then +$ i = i + 1 +$ goto find_aconf +$ endif +$ open/read/err=aconf_err aconf_in 'fname' +$ open/write aconf zconf.h +$ACONF_LOOP: +$ read/end_of_file=aconf_exit aconf_in line +$ work = f$edit(line, "compress,trim") +$ if f$extract(0,6,work) .nes. "#undef" +$ then +$ if f$extract(0,12,work) .nes. "#cmakedefine" +$ then +$ write aconf line +$ endif +$ else +$ cdef = f$element(1," ",work) +$ gosub check_config +$ endif +$ goto aconf_loop +$ACONF_EXIT: +$ write aconf "" +$ write aconf "/* VMS specifics added by make_vms.com: */" +$ write aconf "#define VMS 1" +$ write aconf "#include " +$ write aconf "#include " +$ write aconf "#ifdef _LARGEFILE" +$ write aconf "# define off64_t __off64_t" +$ write aconf "# define fopen64 fopen" +$ write aconf "# define fseeko64 fseeko" +$ write aconf "# define lseek64 lseek" +$ write aconf "# define ftello64 ftell" +$ write aconf "#endif" +$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)" +$ write aconf "# define HAVE_VSNPRINTF" +$ write aconf "#endif" +$ close aconf_in +$ close aconf +$ if f$search("''th'") .nes. "" then delete 'th';* +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if make.eqs."" +$ then +$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;* +$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" - + gzclose.c zutil.h zlib.h zconf.h +$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" - + gzlib.c zutil.h zlib.h zconf.h +$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" - + gzread.c zutil.h zlib.h zconf.h +$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" - + gzwrite.c zutil.h zlib.h zconf.h +$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - + infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" - + [.test]example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" - + [.test]minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib" - + minigzip.obj libz.olb +$ else +$ gosub crea_mms +$ write sys$output "Make ''name' ''version' with ''Make' " +$ 'make' +$ endif +$! +$! Create shareable image +$! +$ gosub crea_olist +$ write sys$output "Creating libzshr.exe" +$ call map_2_shopt 'mapfile' 'optfile' +$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt +$ write sys$output "Zlib build completed" +$ delete/nolog tmp.opt;* +$ exit +$AMISS_ERR: +$ write sys$output "No source for config.hin found." +$ write sys$output "Tried any of ''aconf_in_file'" +$ goto err_exit +$CC_ERR: +$ write sys$output "C compiler required to build ''name'" +$ goto err_exit +$ERR_EXIT: +$ set message/facil/ident/sever/text +$ close/nolog optf +$ close/nolog topt +$ close/nolog aconf_in +$ close/nolog aconf +$ close/nolog out +$ close/nolog min +$ close/nolog mod +$ close/nolog h_in +$ write sys$output "Exiting..." +$ exit 2 +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ +$! +$! Check command line options and set symbols accordingly +$! +$!------------------------------------------------------------------------------ +$! Version history +$! 0.01 20041206 First version to receive a number +$! 0.02 20060126 Add new "HELP" target +$ CHECK_OPTS: +$ i = 1 +$ OPT_LOOP: +$ if i .lt. 9 +$ then +$ cparm = f$edit(p'i',"upcase") +$! +$! Check if parameter actually contains something +$! +$ if f$edit(cparm,"trim") .nes. "" +$ then +$ if cparm .eqs. "DEBUG" +$ then +$ ccopt = ccopt + "/noopt/deb" +$ lopts = lopts + "/deb" +$ endif +$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ ccopt = ccopt + f$extract(start,len,cparm) +$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - + then s_case = true +$ endif +$ if cparm .eqs. "LINK" then linkonly = true +$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ lopts = lopts + f$extract(start,len,cparm) +$ endif +$ if f$locate("CC=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ cc_com = f$extract(start,len,cparm) + if (cc_com .nes. "DECC") .and. - + (cc_com .nes. "VAXC") .and. - + (cc_com .nes. "GNUC") +$ then +$ write sys$output "Unsupported compiler choice ''cc_com' ignored" +$ write sys$output "Use DECC, VAXC, or GNUC instead" +$ else +$ if cc_com .eqs. "DECC" then its_decc = true +$ if cc_com .eqs. "VAXC" then its_vaxc = true +$ if cc_com .eqs. "GNUC" then its_gnuc = true +$ endif +$ endif +$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ mmks = f$extract(start,len,cparm) +$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") +$ then +$ make = mmks +$ else +$ write sys$output "Unsupported make choice ''mmks' ignored" +$ write sys$output "Use MMK or MMS instead" +$ endif +$ endif +$ if cparm .eqs. "HELP" then gosub bhelp +$ endif +$ i = i + 1 +$ goto opt_loop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Look for the compiler used +$! +$! Version history +$! 0.01 20040223 First version to receive a number +$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists +$! 0.03 20060202 Extend handling of GNU C +$! 0.04 20090402 Compaq -> hp +$CHECK_COMPILER: +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then +$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") +$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") +$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") +$ endif +$! +$! Exit if no compiler available +$! +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then goto CC_ERR +$ else +$ if its_decc +$ then +$ write sys$output "CC compiler check ... hp C" +$ if f$trnlnm("decc$no_rooted_search_lists") .nes. "" +$ then +$ dnrsl = f$trnlnm("decc$no_rooted_search_lists") +$ endif +$ define/nolog decc$no_rooted_search_lists 1 +$ else +$ if its_vaxc then write sys$output "CC compiler check ... VAX C" +$ if its_gnuc +$ then +$ write sys$output "CC compiler check ... GNU C" +$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib" +$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib" +$ cc = "gcc" +$ endif +$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share" +$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share" +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! If MMS/MMK are available dump out the descrip.mms if required +$! +$CREA_MMS: +$ write sys$output "Creating descrip.mms..." +$ create descrip.mms +$ open/append out descrip.mms +$ copy sys$input: out +$ deck +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser +# + +OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\ + gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, \ + inftrees.obj, inffast.obj + +$ eod +$ write out "CFLAGS=", ccopt +$ write out "LOPTS=", lopts +$ write out "all : example.exe minigzip.exe libz.olb" +$ copy sys$input: out +$ deck + @ write sys$output " Example applications available" + +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link $(LOPTS) example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link $(LOPTS) minigzip,libz.olb/lib + +clean : + delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* + + +# Other dependencies. +adler32.obj : adler32.c zutil.h zlib.h zconf.h +compress.obj : compress.c zlib.h zconf.h +crc32.obj : crc32.c zutil.h zlib.h zconf.h +deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h +example.obj : [.test]example.c zlib.h zconf.h +gzclose.obj : gzclose.c zutil.h zlib.h zconf.h +gzlib.obj : gzlib.c zutil.h zlib.h zconf.h +gzread.obj : gzread.c zutil.h zlib.h zconf.h +gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h +inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h +inflate.obj : inflate.c zutil.h zlib.h zconf.h +inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h +minigzip.obj : [.test]minigzip.c zlib.h zconf.h +trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h +uncompr.obj : uncompr.c zlib.h zconf.h +zutil.obj : zutil.c zutil.h zlib.h zconf.h +infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ eod +$ close out +$ return +$!------------------------------------------------------------------------------ +$! +$! Read list of core library sources from makefile.in and create options +$! needed to build shareable image +$! +$CREA_OLIST: +$ open/read min makefile.in +$ open/write mod modules.opt +$ src_check_list = "OBJZ =#OBJG =" +$MRLOOP: +$ read/end=mrdone min rec +$ i = 0 +$SRC_CHECK_LOOP: +$ src_check = f$element(i, "#", src_check_list) +$ i = i+1 +$ if src_check .eqs. "#" then goto mrloop +$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop +$ rec = rec - src_check +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop +$MRSLOOP: +$ read/end=mrdone min rec +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop +$MRDONE: +$ close min +$ close mod +$ return +$!------------------------------------------------------------------------------ +$! +$! Take record extracted in crea_olist and split it into single filenames +$! +$EXTRA_FILNAM: +$ myrec = f$edit(rec - "\", "trim,compress") +$ i = 0 +$FELOOP: +$ srcfil = f$element(i," ", myrec) +$ if (srcfil .nes. " ") +$ then +$ write mod f$parse(srcfil,,,"NAME"), ".obj" +$ i = i + 1 +$ goto feloop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Find current Zlib version number +$! +$FIND_VERSION: +$ open/read h_in 'v_file' +$hloop: +$ read/end=hdone h_in rec +$ rec = f$edit(rec,"TRIM") +$ if (f$extract(0,1,rec) .nes. "#") then goto hloop +$ rec = f$edit(rec - "#", "TRIM") +$ if f$element(0," ",rec) .nes. "define" then goto hloop +$ if f$element(1," ",rec) .eqs. v_string +$ then +$ version = 'f$element(2," ",rec)' +$ goto hdone +$ endif +$ goto hloop +$hdone: +$ close h_in +$ return +$!------------------------------------------------------------------------------ +$! +$CHECK_CONFIG: +$! +$ in_ldef = f$locate(cdef,libdefs) +$ if (in_ldef .lt. f$length(libdefs)) +$ then +$ write aconf "#define ''cdef' 1" +$ libdefs = f$extract(0,in_ldef,libdefs) + - + f$extract(in_ldef + f$length(cdef) + 1, - + f$length(libdefs) - in_ldef - f$length(cdef) - 1, - + libdefs) +$ else +$ if (f$type('cdef') .eqs. "INTEGER") +$ then +$ write aconf "#define ''cdef' ", 'cdef' +$ else +$ if (f$type('cdef') .eqs. "STRING") +$ then +$ write aconf "#define ''cdef' ", """", '''cdef'', """" +$ else +$ gosub check_cc_def +$ endif +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Check if this is a define relating to the properties of the C/C++ +$! compiler +$! +$ CHECK_CC_DEF: +$ if (cdef .eqs. "_LARGEFILE64_SOURCE") +$ then +$ copy sys$input: 'tc' +$ deck +#include "tconfig" +#define _LARGEFILE +#include + +int main(){ +FILE *fp; + fp = fopen("temp.txt","r"); + fseeko(fp,1,SEEK_SET); + fclose(fp); +} + +$ eod +$ test_inv = false +$ comm_h = false +$ gosub cc_prop_check +$ return +$ endif +$ write aconf "/* ", line, " */" +$ return +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler +$! +$! Version history +$! 0.01 20031020 First version to receive a number +$! 0.02 20031022 Added logic for defines with value +$! 0.03 20040309 Make sure local config file gets not deleted +$! 0.04 20041230 Also write include for configure run +$! 0.05 20050103 Add processing of "comment defines" +$CC_PROP_CHECK: +$ cc_prop = true +$ is_need = false +$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true) +$ if f$search(th) .eqs. "" then create 'th' +$ set message/nofac/noident/nosever/notext +$ on error then continue +$ cc 'tmpnam' +$ if .not. ($status) then cc_prop = false +$ on error then continue +$! The headers might lie about the capabilities of the RTL +$ link 'tmpnam',tmp.opt/opt +$ if .not. ($status) then cc_prop = false +$ set message/fac/ident/sever/text +$ on error then goto err_exit +$ delete/nolog 'tmpnam'.*;*/exclude='th' +$ if (cc_prop .and. .not. is_need) .or. - + (.not. cc_prop .and. is_need) +$ then +$ write sys$output "Checking for ''cdef'... yes" +$ if f$type('cdef_val'_yes) .nes. "" +$ then +$ if f$type('cdef_val'_yes) .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes) +$ if f$type('cdef_val'_yes) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes) +$ else +$ call write_config f$fao("#define !AS 1",cdef) +$ endif +$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. - + (cdef .eqs. "_LARGEFILE64_SOURCE") then - + call write_config f$string("#define _LARGEFILE 1") +$ else +$ write sys$output "Checking for ''cdef'... no" +$ if (comm_h) +$ then + call write_config f$fao("/* !AS */",line) +$ else +$ if f$type('cdef_val'_no) .nes. "" +$ then +$ if f$type('cdef_val'_no) .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no) +$ if f$type('cdef_val'_no) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no) +$ else +$ call write_config f$fao("#undef !AS",cdef) +$ endif +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler with multiple result values +$! +$! Version history +$! 0.01 20040127 First version +$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05 +$CC_MPROP_CHECK: +$ cc_prop = true +$ i = 1 +$ idel = 1 +$ MT_LOOP: +$ if f$type(result_'i') .eqs. "STRING" +$ then +$ set message/nofac/noident/nosever/notext +$ on error then continue +$ cc 'tmpnam'_'i' +$ if .not. ($status) then cc_prop = false +$ on error then continue +$! The headers might lie about the capabilities of the RTL +$ link 'tmpnam'_'i',tmp.opt/opt +$ if .not. ($status) then cc_prop = false +$ set message/fac/ident/sever/text +$ on error then goto err_exit +$ delete/nolog 'tmpnam'_'i'.*;* +$ if (cc_prop) +$ then +$ write sys$output "Checking for ''cdef'... ", mdef_'i' +$ if f$type(mdef_'i') .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,mdef_'i') +$ if f$type('cdef_val'_yes) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,mdef_'i') +$ goto msym_clean +$ else +$ i = i + 1 +$ goto mt_loop +$ endif +$ endif +$ write sys$output "Checking for ''cdef'... no" +$ call write_config f$fao("#undef !AS",cdef) +$ MSYM_CLEAN: +$ if (idel .le. msym_max) +$ then +$ delete/sym mdef_'idel' +$ idel = idel + 1 +$ goto msym_clean +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Write configuration to both permanent and temporary config file +$! +$! Version history +$! 0.01 20031029 First version to receive a number +$! +$WRITE_CONFIG: SUBROUTINE +$ write aconf 'p1' +$ open/append confh 'th' +$ write confh 'p1' +$ close confh +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ +$! +$! Analyze the project map file and create the symbol vector for a shareable +$! image from it +$! +$! Version history +$! 0.01 20120128 First version +$! 0.02 20120226 Add pre-load logic +$! +$ MAP_2_SHOPT: Subroutine +$! +$ SAY := "WRITE_ SYS$OUTPUT" +$! +$ IF F$SEARCH("''P1'") .EQS. "" +$ THEN +$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available" +$ goto exit_m2s +$ ENDIF +$ IF "''P2'" .EQS. "" +$ THEN +$ SAY "MAP_2_SHOPT: Error, no output file provided" +$ goto exit_m2s +$ ENDIF +$! +$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary" +$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread" +$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary" +$ module4 = "inflateSync#uncompress#zlibVersion#compress" +$ open/read map 'p1 +$ if axp .or. ia64 +$ then +$ open/write aopt a.opt +$ open/write bopt b.opt +$ write aopt " CASE_SENSITIVE=YES" +$ write bopt "SYMBOL_VECTOR= (-" +$ mod_sym_num = 1 +$ MOD_SYM_LOOP: +$ if f$type(module'mod_sym_num') .nes. "" +$ then +$ mod_in = 0 +$ MOD_SYM_IN: +$ shared_proc = f$element(mod_in, "#", module'mod_sym_num') +$ if shared_proc .nes. "#" +$ then +$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",- + f$edit(shared_proc,"upcase"),shared_proc) +$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc) +$ mod_in = mod_in + 1 +$ goto mod_sym_in +$ endif +$ mod_sym_num = mod_sym_num + 1 +$ goto mod_sym_loop +$ endif +$MAP_LOOP: +$ read/end=map_end map line +$ if (f$locate("{",line).lt. f$length(line)) .or. - + (f$locate("global:", line) .lt. f$length(line)) +$ then +$ proc = true +$ goto map_loop +$ endif +$ if f$locate("}",line).lt. f$length(line) then proc = false +$ if f$locate("local:", line) .lt. f$length(line) then proc = false +$ if proc +$ then +$ shared_proc = f$edit(line,"collapse") +$ chop_semi = f$locate(";", shared_proc) +$ if chop_semi .lt. f$length(shared_proc) then - + shared_proc = f$extract(0, chop_semi, shared_proc) +$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",- + f$edit(shared_proc,"upcase"),shared_proc) +$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc) +$ endif +$ goto map_loop +$MAP_END: +$ close/nolog aopt +$ close/nolog bopt +$ open/append libopt 'p2' +$ open/read aopt a.opt +$ open/read bopt b.opt +$ALOOP: +$ read/end=aloop_end aopt line +$ write libopt line +$ goto aloop +$ALOOP_END: +$ close/nolog aopt +$ sv = "" +$BLOOP: +$ read/end=bloop_end bopt svn +$ if (svn.nes."") +$ then +$ if (sv.nes."") then write libopt sv +$ sv = svn +$ endif +$ goto bloop +$BLOOP_END: +$ write libopt f$extract(0,f$length(sv)-2,sv), "-" +$ write libopt ")" +$ close/nolog bopt +$ delete/nolog/noconf a.opt;*,b.opt;* +$ else +$ if vax +$ then +$ open/append libopt 'p2' +$ mod_sym_num = 1 +$ VMOD_SYM_LOOP: +$ if f$type(module'mod_sym_num') .nes. "" +$ then +$ mod_in = 0 +$ VMOD_SYM_IN: +$ shared_proc = f$element(mod_in, "#", module'mod_sym_num') +$ if shared_proc .nes. "#" +$ then +$ write libopt f$fao("UNIVERSAL=!AS",- + f$edit(shared_proc,"upcase")) +$ mod_in = mod_in + 1 +$ goto vmod_sym_in +$ endif +$ mod_sym_num = mod_sym_num + 1 +$ goto vmod_sym_loop +$ endif +$VMAP_LOOP: +$ read/end=vmap_end map line +$ if (f$locate("{",line).lt. f$length(line)) .or. - + (f$locate("global:", line) .lt. f$length(line)) +$ then +$ proc = true +$ goto vmap_loop +$ endif +$ if f$locate("}",line).lt. f$length(line) then proc = false +$ if f$locate("local:", line) .lt. f$length(line) then proc = false +$ if proc +$ then +$ shared_proc = f$edit(line,"collapse") +$ chop_semi = f$locate(";", shared_proc) +$ if chop_semi .lt. f$length(shared_proc) then - + shared_proc = f$extract(0, chop_semi, shared_proc) +$ write libopt f$fao("UNIVERSAL=!AS",- + f$edit(shared_proc,"upcase")) +$ endif +$ goto vmap_loop +$VMAP_END: +$ else +$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)" +$ write sys$output "No options file created" +$ endif +$ endif +$ EXIT_M2S: +$ close/nolog map +$ close/nolog libopt +$ endsubroutine diff --git a/src/external/zlib-1.2.11/msdos/Makefile.bor b/src/external/zlib-1.2.11/msdos/Makefile.bor new file mode 100644 index 000000000..3d12a2c25 --- /dev/null +++ b/src/external/zlib-1.2.11/msdos/Makefile.bor @@ -0,0 +1,115 @@ +# Makefile for zlib +# Borland C++ +# Last updated: 15-Mar-2003 + +# To use, do "make -fmakefile.bor" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------ Turbo C++, Borland C++ ------------ + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# memory model: one of s, m, c, l (small, medium, compact, large) +MODEL=l + +# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version +CC=bcc +LD=bcc +AR=tlib + +# compiler flags +# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0 +CFLAGS=-O2 -Z -m$(MODEL) $(LOC) + +LDFLAGS=-m$(MODEL) -f- + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del zlib_*.bak + -del foo.gz diff --git a/src/external/zlib-1.2.11/msdos/Makefile.dj2 b/src/external/zlib-1.2.11/msdos/Makefile.dj2 new file mode 100644 index 000000000..59d2037d6 --- /dev/null +++ b/src/external/zlib-1.2.11/msdos/Makefile.dj2 @@ -0,0 +1,104 @@ +# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.dj2; make test -fmakefile.dj2 +# +# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: +# +# make install -fmakefile.dj2 +# +# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as +# in the sample below if the pattern of the DJGPP distribution is to +# be followed. Remember that, while 'es around <=> are ignored in +# makefiles, they are *not* in batch files or in djgpp.env. +# - - - - - +# [make] +# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include +# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib +# BUTT=-m486 +# - - - - - +# Alternately, these variables may be defined below, overriding the values +# in djgpp.env, as +# INCLUDE_PATH=c:\usr\include +# LIBRARY_PATH=c:\usr\lib + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DZLIB_DEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +check: test +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/src/external/zlib-1.2.11/msdos/Makefile.emx b/src/external/zlib-1.2.11/msdos/Makefile.emx new file mode 100644 index 000000000..e30f67bed --- /dev/null +++ b/src/external/zlib-1.2.11/msdos/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DZLIB_DEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/src/external/zlib-1.2.11/msdos/Makefile.msc b/src/external/zlib-1.2.11/msdos/Makefile.msc new file mode 100644 index 000000000..ae8378615 --- /dev/null +++ b/src/external/zlib-1.2.11/msdos/Makefile.msc @@ -0,0 +1,112 @@ +# Makefile for zlib +# Microsoft C 5.1 or later +# Last updated: 19-Mar-2003 + +# To use, do "make makefile.msc" +# To compile in small model, set below: MODEL=S + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of S, M, C, L (small, medium, compact, large) +MODEL=L + +CC=cl +CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC) +#-Ox generates bad code with MSC 5.1 +LIB_CFLAGS=-Zl $(CFLAGS) + +LD=link +LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode +# "/farcall/packcode" are only useful for `large code' memory models +# but should be a "no-op" for small code models. + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(LIB_CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: test/minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + if exist $(ZLIB_LIB) del $(ZLIB_LIB) + lib $(ZLIB_LIB) $(OBJ1); + lib $(ZLIB_LIB) $(OBJ2); + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB); + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB); + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del *.map + -del zlib_*.bak + -del foo.gz diff --git a/src/external/zlib-1.2.11/msdos/Makefile.tc b/src/external/zlib-1.2.11/msdos/Makefile.tc new file mode 100644 index 000000000..5aec82a9d --- /dev/null +++ b/src/external/zlib-1.2.11/msdos/Makefile.tc @@ -0,0 +1,100 @@ +# Makefile for zlib +# Turbo C 2.01, Turbo C++ 1.01 +# Last updated: 15-Mar-2003 + +# To use, do "make -fmakefile.tc" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------ +MODEL=l +CC=tcc +LD=tcc +AR=tlib +# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +CFLAGS=-O2 -G -Z -m$(MODEL) +LDFLAGS=-m$(MODEL) -f- + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del zlib_*.bak + -del foo.gz diff --git a/src/external/zlib-1.2.11/nintendods/Makefile b/src/external/zlib-1.2.11/nintendods/Makefile new file mode 100644 index 000000000..21337d01a --- /dev/null +++ b/src/external/zlib-1.2.11/nintendods/Makefile @@ -0,0 +1,126 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := ../../ +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork + +CFLAGS := -Wall -O2\ + -march=armv5te -mtune=arm946e-s \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM9 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions + +ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s +LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBNDS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/lib/libz.a + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + @[ -d $@ ] || mkdir -p include + @cp ../../*.h include + +lib: + @[ -d $@ ] || mkdir -p $@ + +$(BUILD): lib + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) lib + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT) : $(OFILES) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/src/external/zlib-1.2.11/nintendods/README b/src/external/zlib-1.2.11/nintendods/README new file mode 100644 index 000000000..ba7a37dbe --- /dev/null +++ b/src/external/zlib-1.2.11/nintendods/README @@ -0,0 +1,5 @@ +This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template. + +Eduardo Costa +January 3, 2009 + diff --git a/src/external/zlib-1.2.11/old/Makefile.emx b/src/external/zlib-1.2.11/old/Makefile.emx new file mode 100644 index 000000000..612b03791 --- /dev/null +++ b/src/external/zlib-1.2.11/old/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc -Zwin32 + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DZLIB_DEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/src/external/zlib-1.2.11/old/Makefile.riscos b/src/external/zlib-1.2.11/old/Makefile.riscos new file mode 100644 index 000000000..57e29d3fb --- /dev/null +++ b/src/external/zlib-1.2.11/old/Makefile.riscos @@ -0,0 +1,151 @@ +# Project: zlib_1_03 +# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 +# test works out-of-the-box, installs `somewhere' on demand + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + +# change the line below to where _you_ want the library installed. +libdest = lib:zlib + +# Final targets: +@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompr @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompr @.o.zutil +test: @.minigzip @.example @.lib + @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV + @echo running tests: hang on. + @/@.minigzip -f -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -f -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -1 libc + @/@.minigzip -d libc-gz + @diff @.lib @.libc + @echo that should have reported '@.lib and @.libc identical' if you have diff. + @/@.example @.fred @.fred + @echo that will have given lots of hello!'s. + +@.minigzip: @.o.minigzip @.lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs +@.example: @.o.example @.lib C:o.Stubs + Link $(Linkflags) @.o.example @.lib C:o.Stubs + +install: @.lib + cdir $(libdest) + cdir $(libdest).h + @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV + @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV + @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV + @echo okay, installed zlib in $(libdest) + +clean:; remove @.minigzip + remove @.example + remove @.libc + -wipe @.o.* F~r~cV + remove @.fred + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: + +# Dynamic dependencies: +o.example: c.example +o.example: h.zlib +o.example: h.zconf +o.minigzip: c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.adler32: c.adler32 +o.adler32: h.zlib +o.adler32: h.zconf +o.compress: c.compress +o.compress: h.zlib +o.compress: h.zconf +o.crc32: c.crc32 +o.crc32: h.zlib +o.crc32: h.zconf +o.deflate: c.deflate +o.deflate: h.deflate +o.deflate: h.zutil +o.deflate: h.zlib +o.deflate: h.zconf +o.gzio: c.gzio +o.gzio: h.zutil +o.gzio: h.zlib +o.gzio: h.zconf +o.infblock: c.infblock +o.infblock: h.zutil +o.infblock: h.zlib +o.infblock: h.zconf +o.infblock: h.infblock +o.infblock: h.inftrees +o.infblock: h.infcodes +o.infblock: h.infutil +o.infcodes: c.infcodes +o.infcodes: h.zutil +o.infcodes: h.zlib +o.infcodes: h.zconf +o.infcodes: h.inftrees +o.infcodes: h.infblock +o.infcodes: h.infcodes +o.infcodes: h.infutil +o.infcodes: h.inffast +o.inffast: c.inffast +o.inffast: h.zutil +o.inffast: h.zlib +o.inffast: h.zconf +o.inffast: h.inftrees +o.inffast: h.infblock +o.inffast: h.infcodes +o.inffast: h.infutil +o.inffast: h.inffast +o.inflate: c.inflate +o.inflate: h.zutil +o.inflate: h.zlib +o.inflate: h.zconf +o.inflate: h.infblock +o.inftrees: c.inftrees +o.inftrees: h.zutil +o.inftrees: h.zlib +o.inftrees: h.zconf +o.inftrees: h.inftrees +o.inftrees: h.inffixed +o.infutil: c.infutil +o.infutil: h.zutil +o.infutil: h.zlib +o.infutil: h.zconf +o.infutil: h.infblock +o.infutil: h.inftrees +o.infutil: h.infcodes +o.infutil: h.infutil +o.trees: c.trees +o.trees: h.deflate +o.trees: h.zutil +o.trees: h.zlib +o.trees: h.zconf +o.trees: h.trees +o.uncompr: c.uncompr +o.uncompr: h.zlib +o.uncompr: h.zconf +o.zutil: c.zutil +o.zutil: h.zutil +o.zutil: h.zlib +o.zutil: h.zconf diff --git a/src/external/zlib-1.2.11/old/README b/src/external/zlib-1.2.11/old/README new file mode 100644 index 000000000..800bf0798 --- /dev/null +++ b/src/external/zlib-1.2.11/old/README @@ -0,0 +1,3 @@ +This directory contains files that have not been updated for zlib 1.2.x + +(Volunteers are encouraged to help clean this up. Thanks.) diff --git a/src/external/zlib-1.2.11/old/descrip.mms b/src/external/zlib-1.2.11/old/descrip.mms new file mode 100644 index 000000000..7066da5b5 --- /dev/null +++ b/src/external/zlib-1.2.11/old/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/src/external/zlib-1.2.11/old/os2/Makefile.os2 b/src/external/zlib-1.2.11/old/os2/Makefile.os2 new file mode 100644 index 000000000..bb426c0d8 --- /dev/null +++ b/src/external/zlib-1.2.11/old/os2/Makefile.os2 @@ -0,0 +1,136 @@ +# Makefile for zlib under OS/2 using GCC (PGCC) +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# cp Makefile.os2 .. +# cd .. +# make -f Makefile.os2 test + +# This makefile will build a static library z.lib, a shared library +# z.dll and a import library zdll.lib. You can use either z.lib or +# zdll.lib by specifying either -lz or -lzdll on gcc's command line + +CC=gcc -Zomf -s + +CFLAGS=-O6 -Wall +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DZLIB_DEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +#################### BUG WARNING: ##################### +## infcodes.c hits a bug in pgcc-1.0, so you have to use either +## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem) +## This bug is reportedly fixed in pgcc >1.0, but this was not tested +CFLAGS+=-fno-force-mem + +LDFLAGS=-s -L. -lzdll -Zcrtdll +LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll + +VER=1.1.0 +ZLIB=z.lib +SHAREDLIB=z.dll +SHAREDLIBIMP=zdll.lib +LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP) + +AR=emxomfar cr +IMPLIB=emximp +RANLIB=echo +TAR=tar +SHELL=bash + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \ + algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \ + contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 + +all: example.exe minigzip.exe + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +$(ZLIB): $(OBJS) + $(AR) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +$(SHAREDLIB): $(OBJS) os2/z.def + $(LDSHARED) -o $@ $^ + +$(SHAREDLIBIMP): os2/z.def + $(IMPLIB) -o $@ $^ + +example.exe: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip.exe: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/src/external/zlib-1.2.11/old/os2/zlib.def b/src/external/zlib-1.2.11/old/os2/zlib.def new file mode 100644 index 000000000..4c753f1a3 --- /dev/null +++ b/src/external/zlib-1.2.11/old/os2/zlib.def @@ -0,0 +1,51 @@ +; +; Slightly modified version of ../nt/zlib.dnt :-) +; + +LIBRARY Z +DESCRIPTION "Zlib compression library for OS/2" +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 + compress + crc32 + deflate + deflateCopy + deflateEnd + deflateInit2_ + deflateInit_ + deflateParams + deflateReset + deflateSetDictionary + gzclose + gzdopen + gzerror + gzflush + gzopen + gzread + gzwrite + inflate + inflateEnd + inflateInit2_ + inflateInit_ + inflateReset + inflateSetDictionary + inflateSync + uncompress + zlibVersion + gzprintf + gzputc + gzgetc + gzseek + gzrewind + gztell + gzeof + gzsetparams + zError + inflateSyncPoint + get_crc_table + compress2 + gzputs + gzgets diff --git a/src/external/zlib-1.2.11/old/visual-basic.txt b/src/external/zlib-1.2.11/old/visual-basic.txt new file mode 100644 index 000000000..57efe5812 --- /dev/null +++ b/src/external/zlib-1.2.11/old/visual-basic.txt @@ -0,0 +1,160 @@ +See below some functions declarations for Visual Basic. + +Frequently Asked Question: + +Q: Each time I use the compress function I get the -5 error (not enough + room in the output buffer). + +A: Make sure that the length of the compressed buffer is passed by + reference ("as any"), not by value ("as long"). Also check that + before the call of compress this length is equal to the total size of + the compressed buffer and not zero. + + +From: "Jon Caruana" +Subject: Re: How to port zlib declares to vb? +Date: Mon, 28 Oct 1996 18:33:03 -0600 + +Got the answer! (I haven't had time to check this but it's what I got, and +looks correct): + +He has the following routines working: + compress + uncompress + gzopen + gzwrite + gzread + gzclose + +Declares follow: (Quoted from Carlos Rios , in Vb4 form) + +#If Win16 Then 'Use Win16 calls. +Declare Function compress Lib "ZLIB.DLL" (ByVal compr As + String, comprLen As Any, ByVal buf As String, ByVal buflen + As Long) As Integer +Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr + As String, uncomprLen As Any, ByVal compr As String, ByVal + lcompr As Long) As Integer +Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As + String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As + Long) As Integer +#Else +Declare Function compress Lib "ZLIB32.DLL" + (ByVal compr As String, comprLen As Any, ByVal buf As + String, ByVal buflen As Long) As Integer +Declare Function uncompress Lib "ZLIB32.DLL" + (ByVal uncompr As String, uncomprLen As Any, ByVal compr As + String, ByVal lcompr As Long) As Long +Declare Function gzopen Lib "ZLIB32.DLL" + (ByVal file As String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzwrite Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzclose Lib "ZLIB32.DLL" + (ByVal file As Long) As Long +#End If + +-Jon Caruana +jon-net@usa.net +Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member + + +Here is another example from Michael that he +says conforms to the VB guidelines, and that solves the problem of not +knowing the uncompressed size by storing it at the end of the file: + +'Calling the functions: +'bracket meaning: [optional] {Range of possible values} +'Call subCompressFile( [, , [level of compression {1..9}]]) +'Call subUncompressFile() + +Option Explicit +Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller' +Private Const SUCCESS As Long = 0 +Private Const strFilExt As String = ".cpr" +Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long, +ByVal level As Integer) As Long +Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) +As Long + +Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal +strargCprFilPth As String, Optional ByVal intLvl As Integer = 9) + Dim strCprPth As String + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim bytaryOri() As Byte + Dim bytaryCpr() As Byte + lngOriSiz = FileLen(strargOriFilPth) + ReDim bytaryOri(lngOriSiz - 1) + Open strargOriFilPth For Binary Access Read As #1 + Get #1, , bytaryOri() + Close #1 + strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth) +'Select file path and name + strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) = +strFilExt, "", strFilExt) 'Add file extension if not exists + lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit +more space then original file size + ReDim bytaryCpr(lngCprSiz - 1) + If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) = +SUCCESS Then + lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100 + ReDim Preserve bytaryCpr(lngCprSiz - 1) + Open strCprPth For Binary Access Write As #1 + Put #1, , bytaryCpr() + Put #1, , lngOriSiz 'Add the the original size value to the end +(last 4 bytes) + Close #1 + Else + MsgBox "Compression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub + +Public Sub subUncompressFile(ByVal strargFilPth As String) + Dim bytaryCpr() As Byte + Dim bytaryOri() As Byte + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim strOriPth As String + lngCprSiz = FileLen(strargFilPth) + ReDim bytaryCpr(lngCprSiz - 1) + Open strargFilPth For Binary Access Read As #1 + Get #1, , bytaryCpr() + Close #1 + 'Read the original file size value: + lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _ + + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _ + + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _ + + bytaryCpr(lngCprSiz - 4) + ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value + ReDim bytaryOri(lngOriSiz - 1) + If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS +Then + strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt)) + Open strOriPth For Binary Access Write As #1 + Put #1, , bytaryOri() + Close #1 + Else + MsgBox "Uncompression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub +Public Property Get lngPercentSmaller() As Long + lngPercentSmaller = lngpvtPcnSml +End Property diff --git a/src/external/zlib-1.2.11/os400/README400 b/src/external/zlib-1.2.11/os400/README400 new file mode 100644 index 000000000..4f98334f5 --- /dev/null +++ b/src/external/zlib-1.2.11/os400/README400 @@ -0,0 +1,48 @@ + ZLIB version 1.2.11 for OS/400 installation instructions + +1) Download and unpack the zlib tarball to some IFS directory. + (i.e.: /path/to/the/zlib/ifs/source/directory) + + If the installed IFS command suppors gzip format, this is straightforward, +else you have to unpack first to some directory on a system supporting it, +then move the whole directory to the IFS via the network (via SMB or FTP). + +2) Edit the configuration parameters in the compilation script. + + EDTF STMF('/path/to/the/zlib/ifs/source/directory/os400/make.sh') + +Tune the parameters according to your needs if not matching the defaults. +Save the file and exit after edition. + +3) Enter qshell, then work in the zlib OS/400 specific directory. + + QSH + cd /path/to/the/zlib/ifs/source/directory/os400 + +4) Compile and install + + sh make.sh + +The script will: +- create the libraries, objects and IFS directories for the zlib environment, +- compile all modules, +- create a service program, +- create a static and a dynamic binding directory, +- install header files for C/C++ and for ILE/RPG, both for compilation in + DB2 and IFS environments. + +That's all. + + +Notes: For OS/400 ILE RPG programmers, a /copy member defining the ZLIB + API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC). + In the ILE environment, the same definitions are available from + file zlib.inc located in the same IFS include directory as the + C/C++ header files. + Please read comments in this member for more information. + + Remember that most foreign textual data are ASCII coded: this + implementation does not handle conversion from/to ASCII, so + text data code conversions must be done explicitely. + + Mainly for the reason above, always open zipped files in binary mode. diff --git a/src/external/zlib-1.2.11/os400/bndsrc b/src/external/zlib-1.2.11/os400/bndsrc new file mode 100644 index 000000000..5e6e0a2f0 --- /dev/null +++ b/src/external/zlib-1.2.11/os400/bndsrc @@ -0,0 +1,119 @@ +STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB') + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.1.3 entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + EXPORT SYMBOL("adler32") + EXPORT SYMBOL("compress") + EXPORT SYMBOL("compress2") + EXPORT SYMBOL("crc32") + EXPORT SYMBOL("get_crc_table") + EXPORT SYMBOL("deflate") + EXPORT SYMBOL("deflateEnd") + EXPORT SYMBOL("deflateSetDictionary") + EXPORT SYMBOL("deflateCopy") + EXPORT SYMBOL("deflateReset") + EXPORT SYMBOL("deflateParams") + EXPORT SYMBOL("deflatePrime") + EXPORT SYMBOL("deflateInit_") + EXPORT SYMBOL("deflateInit2_") + EXPORT SYMBOL("gzopen") + EXPORT SYMBOL("gzdopen") + EXPORT SYMBOL("gzsetparams") + EXPORT SYMBOL("gzread") + EXPORT SYMBOL("gzwrite") + EXPORT SYMBOL("gzprintf") + EXPORT SYMBOL("gzputs") + EXPORT SYMBOL("gzgets") + EXPORT SYMBOL("gzputc") + EXPORT SYMBOL("gzgetc") + EXPORT SYMBOL("gzflush") + EXPORT SYMBOL("gzseek") + EXPORT SYMBOL("gzrewind") + EXPORT SYMBOL("gztell") + EXPORT SYMBOL("gzeof") + EXPORT SYMBOL("gzclose") + EXPORT SYMBOL("gzerror") + EXPORT SYMBOL("inflate") + EXPORT SYMBOL("inflateEnd") + EXPORT SYMBOL("inflateSetDictionary") + EXPORT SYMBOL("inflateSync") + EXPORT SYMBOL("inflateReset") + EXPORT SYMBOL("inflateInit_") + EXPORT SYMBOL("inflateInit2_") + EXPORT SYMBOL("inflateSyncPoint") + EXPORT SYMBOL("uncompress") + EXPORT SYMBOL("zlibVersion") + EXPORT SYMBOL("zError") + EXPORT SYMBOL("z_errmsg") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.1 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + EXPORT SYMBOL("compressBound") + EXPORT SYMBOL("deflateBound") + EXPORT SYMBOL("deflatePending") + EXPORT SYMBOL("gzungetc") + EXPORT SYMBOL("gzclearerr") + EXPORT SYMBOL("inflateBack") + EXPORT SYMBOL("inflateBackEnd") + EXPORT SYMBOL("inflateBackInit_") + EXPORT SYMBOL("inflateCopy") + EXPORT SYMBOL("zlibCompileFlags") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.4 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + EXPORT SYMBOL("adler32_combine") + EXPORT SYMBOL("adler32_combine64") + EXPORT SYMBOL("crc32_combine") + EXPORT SYMBOL("crc32_combine64") + EXPORT SYMBOL("deflateSetHeader") + EXPORT SYMBOL("deflateTune") + EXPORT SYMBOL("gzbuffer") + EXPORT SYMBOL("gzclose_r") + EXPORT SYMBOL("gzclose_w") + EXPORT SYMBOL("gzdirect") + EXPORT SYMBOL("gzoffset") + EXPORT SYMBOL("gzoffset64") + EXPORT SYMBOL("gzopen64") + EXPORT SYMBOL("gzseek64") + EXPORT SYMBOL("gztell64") + EXPORT SYMBOL("inflateGetHeader") + EXPORT SYMBOL("inflateMark") + EXPORT SYMBOL("inflatePrime") + EXPORT SYMBOL("inflateReset2") + EXPORT SYMBOL("inflateUndermine") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.6 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + EXPORT SYMBOL("deflateResetKeep") + EXPORT SYMBOL("gzgetc_") + EXPORT SYMBOL("inflateResetKeep") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.8 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + EXPORT SYMBOL("gzvprintf") + EXPORT SYMBOL("inflateGetDictionary") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.9 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + EXPORT SYMBOL("adler32_z") + EXPORT SYMBOL("crc32_z") + EXPORT SYMBOL("deflateGetDictionary") + EXPORT SYMBOL("gzfread") + EXPORT SYMBOL("gzfwrite") + EXPORT SYMBOL("inflateCodesUsed") + EXPORT SYMBOL("inflateValidate") + EXPORT SYMBOL("uncompress2") + +ENDPGMEXP diff --git a/src/external/zlib-1.2.11/os400/make.sh b/src/external/zlib-1.2.11/os400/make.sh new file mode 100644 index 000000000..19eec117a --- /dev/null +++ b/src/external/zlib-1.2.11/os400/make.sh @@ -0,0 +1,366 @@ +#!/bin/sh +# +# ZLIB compilation script for the OS/400. +# +# +# This is a shell script since make is not a standard component of OS/400. + + +################################################################################ +# +# Tunable configuration parameters. +# +################################################################################ + +TARGETLIB='ZLIB' # Target OS/400 program library +STATBNDDIR='ZLIB_A' # Static binding directory. +DYNBNDDIR='ZLIB' # Dynamic binding directory. +SRVPGM="ZLIB" # Service program. +IFSDIR='/zlib' # IFS support base directory. +TGTCCSID='500' # Target CCSID of objects +DEBUG='*NONE' # Debug level +OPTIMIZE='40' # Optimisation level +OUTPUT='*NONE' # Compilation output option. +TGTRLS='V6R1M0' # Target OS release + +export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM IFSDIR +export TGTCCSID DEBUG OPTIMIZE OUTPUT TGTRLS + + +################################################################################ +# +# OS/400 specific definitions. +# +################################################################################ + +LIBIFSNAME="/QSYS.LIB/${TARGETLIB}.LIB" + + +################################################################################ +# +# Procedures. +# +################################################################################ + +# action_needed dest [src] +# +# dest is an object to build +# if specified, src is an object on which dest depends. +# +# exit 0 (succeeds) if some action has to be taken, else 1. + +action_needed() + +{ + [ ! -e "${1}" ] && return 0 + [ "${2}" ] || return 1 + [ "${1}" -ot "${2}" ] && return 0 + return 1 +} + + +# make_module module_name source_name [additional_definitions] +# +# Compile source name into module if needed. +# As side effect, append the module name to variable MODULES. +# Set LINK to "YES" if the module has been compiled. + +make_module() + +{ + MODULES="${MODULES} ${1}" + MODIFSNAME="${LIBIFSNAME}/${1}.MODULE" + CSRC="`basename \"${2}\"`" + + if action_needed "${MODIFSNAME}" "${2}" + then : + elif [ ! "`sed -e \"//,/<\\\\/source>/!d\" \ + -e '/ tmphdrfile + + # Need to translate to target CCSID. + + CMD="CPY OBJ('`pwd`/tmphdrfile') TOOBJ('${DEST}')" + CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)" + system "${CMD}" + # touch -r "${HFILE}" "${DEST}" + rm -f tmphdrfile + fi + + IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`" + + if action_needed "${IFSFILE}" "${DEST}" + then rm -f "${IFSFILE}" + ln -s "${DEST}" "${IFSFILE}" + fi +done + + +# Install the ILE/RPG header file. + + +HFILE="${SCRIPTDIR}/zlib.inc" +DEST="${SRCPF}/ZLIB.INC.MBR" + +if action_needed "${DEST}" "${HFILE}" +then CMD="CPY OBJ('${HFILE}') TOOBJ('${DEST}')" + CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)" + system "${CMD}" + # touch -r "${HFILE}" "${DEST}" +fi + +IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`" + +if action_needed "${IFSFILE}" "${DEST}" +then rm -f "${IFSFILE}" + ln -s "${DEST}" "${IFSFILE}" +fi + + +# Create and compile the identification source file. + +echo '#pragma comment(user, "ZLIB version '"${VERSION}"'")' > os400.c +echo '#pragma comment(user, __DATE__)' >> os400.c +echo '#pragma comment(user, __TIME__)' >> os400.c +echo '#pragma comment(copyright, "Copyright (C) 1995-2017 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c +make_module OS400 os400.c +LINK= # No need to rebuild service program yet. +MODULES= + + +# Get source list. + +CSOURCES=`sed -e '/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Library + + Medium + + 2.0 + + + + zlib + zlib + alain.bonnefoy@icbt.com + Public + public + www.gzip.org/zlib + + + Jean-Loup Gailly,Mark Adler + www.gzip.org/zlib + + zlib@gzip.org + + + A massively spiffy yet delicately unobtrusive compression library. + zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system. + http://www.gzip.org/zlib + + + + + 1.2.11 + Medium + Stable + + + + + + + No License + + + + Software Development/Libraries and Extensions/C Libraries + zlib,compression + qnx6 + qnx6 + None + Developer + + + + + + + + + + + + + + Install + Post + No + Ignore + + No + Optional + + + + + + + + + + + + + InstallOver + zlib + + + + + + + + + + + + + InstallOver + zlib-dev + + + + + + + + + diff --git a/src/external/zlib-1.2.11/test/example.c b/src/external/zlib-1.2.11/test/example.c new file mode 100644 index 000000000..eee17ce7c --- /dev/null +++ b/src/external/zlib-1.2.11/test/example.c @@ -0,0 +1,602 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" +#include + +#ifdef STDC +# include +# include +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static z_const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +static const char dictionary[] = "hello"; +static uLong dictId; /* Adler32 value of the dictionary */ + +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + + +#ifdef Z_SOLO + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + (void)q; + return calloc(n, m); +} + +void myfree(void *q, void *p) +{ + (void)q; + free(p); +} + +static alloc_func zalloc = myalloc; +static free_func zfree = myfree; + +#else /* !Z_SOLO */ + +static alloc_func zalloc = (alloc_func)0; +static free_func zfree = (free_func)0; + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *fname, + Byte *uncompr, uLong uncomprLen)); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = (uLong)strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(fname, uncompr, uncomprLen) + const char *fname; /* compressed file name */ + Byte *uncompr; + uLong uncomprLen; +{ +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + int len = (int)strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(fname, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(fname, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + strcpy((char*)uncompr, "garbage"); + + if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char*)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + if (gzungetc(' ', file) != ' ') { + fprintf(stderr, "gzungetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) { /* " hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello + 6)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + } + + gzclose(file); +#endif +} + +#endif /* Z_SOLO */ + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uLong len = (uLong)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uInt len = (uInt)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + err = inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, (int)sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + (int)sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", + ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + +#ifdef Z_SOLO + (void)argc; + (void)argv; +#else + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); +#endif + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/src/external/zlib-1.2.11/test/infcover.c b/src/external/zlib-1.2.11/test/infcover.c new file mode 100644 index 000000000..2be01646c --- /dev/null +++ b/src/external/zlib-1.2.11/test/infcover.c @@ -0,0 +1,671 @@ +/* infcover.c -- test zlib's inflate routines with full code coverage + * Copyright (C) 2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* to use, do: ./configure --cover && make cover */ + +#include +#include +#include +#include +#include "zlib.h" + +/* get definition of internal structure so we can mess with it (see pull()), + and so we can call inflate_trees() (see cover5()) */ +#define ZLIB_INTERNAL +#include "inftrees.h" +#include "inflate.h" + +#define local static + +/* -- memory tracking routines -- */ + +/* + These memory tracking routines are provided to zlib and track all of zlib's + allocations and deallocations, check for LIFO operations, keep a current + and high water mark of total bytes requested, optionally set a limit on the + total memory that can be allocated, and when done check for memory leaks. + + They are used as follows: + + z_stream strm; + mem_setup(&strm) initializes the memory tracking and sets the + zalloc, zfree, and opaque members of strm to use + memory tracking for all zlib operations on strm + mem_limit(&strm, limit) sets a limit on the total bytes requested -- a + request that exceeds this limit will result in an + allocation failure (returns NULL) -- setting the + limit to zero means no limit, which is the default + after mem_setup() + mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used + mem_high(&strm, "msg") prints to stderr "msg" and the high water mark + mem_done(&strm, "msg") ends memory tracking, releases all allocations + for the tracking as well as leaked zlib blocks, if + any. If there was anything unusual, such as leaked + blocks, non-FIFO frees, or frees of addresses not + allocated, then "msg" and information about the + problem is printed to stderr. If everything is + normal, nothing is printed. mem_done resets the + strm members to Z_NULL to use the default memory + allocation routines on the next zlib initialization + using strm. + */ + +/* these items are strung together in a linked list, one for each allocation */ +struct mem_item { + void *ptr; /* pointer to allocated memory */ + size_t size; /* requested size of allocation */ + struct mem_item *next; /* pointer to next item in list, or NULL */ +}; + +/* this structure is at the root of the linked list, and tracks statistics */ +struct mem_zone { + struct mem_item *first; /* pointer to first item in list, or NULL */ + size_t total, highwater; /* total allocations, and largest total */ + size_t limit; /* memory allocation limit, or 0 if no limit */ + int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ +}; + +/* memory allocation routine to pass to zlib */ +local void *mem_alloc(void *mem, unsigned count, unsigned size) +{ + void *ptr; + struct mem_item *item; + struct mem_zone *zone = mem; + size_t len = count * (size_t)size; + + /* induced allocation failure */ + if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) + return NULL; + + /* perform allocation using the standard library, fill memory with a + non-zero value to make sure that the code isn't depending on zeros */ + ptr = malloc(len); + if (ptr == NULL) + return NULL; + memset(ptr, 0xa5, len); + + /* create a new item for the list */ + item = malloc(sizeof(struct mem_item)); + if (item == NULL) { + free(ptr); + return NULL; + } + item->ptr = ptr; + item->size = len; + + /* insert item at the beginning of the list */ + item->next = zone->first; + zone->first = item; + + /* update the statistics */ + zone->total += item->size; + if (zone->total > zone->highwater) + zone->highwater = zone->total; + + /* return the allocated memory */ + return ptr; +} + +/* memory free routine to pass to zlib */ +local void mem_free(void *mem, void *ptr) +{ + struct mem_item *item, *next; + struct mem_zone *zone = mem; + + /* if no zone, just do a free */ + if (zone == NULL) { + free(ptr); + return; + } + + /* point next to the item that matches ptr, or NULL if not found -- remove + the item from the linked list if found */ + next = zone->first; + if (next) { + if (next->ptr == ptr) + zone->first = next->next; /* first one is it, remove from list */ + else { + do { /* search the linked list */ + item = next; + next = item->next; + } while (next != NULL && next->ptr != ptr); + if (next) { /* if found, remove from linked list */ + item->next = next->next; + zone->notlifo++; /* not a LIFO free */ + } + + } + } + + /* if found, update the statistics and free the item */ + if (next) { + zone->total -= next->size; + free(next); + } + + /* if not found, update the rogue count */ + else + zone->rogue++; + + /* in any case, do the requested free with the standard library function */ + free(ptr); +} + +/* set up a controlled memory allocation space for monitoring, set the stream + parameters to the controlled routines, with opaque pointing to the space */ +local void mem_setup(z_stream *strm) +{ + struct mem_zone *zone; + + zone = malloc(sizeof(struct mem_zone)); + assert(zone != NULL); + zone->first = NULL; + zone->total = 0; + zone->highwater = 0; + zone->limit = 0; + zone->notlifo = 0; + zone->rogue = 0; + strm->opaque = zone; + strm->zalloc = mem_alloc; + strm->zfree = mem_free; +} + +/* set a limit on the total memory allocation, or 0 to remove the limit */ +local void mem_limit(z_stream *strm, size_t limit) +{ + struct mem_zone *zone = strm->opaque; + + zone->limit = limit; +} + +/* show the current total requested allocations in bytes */ +local void mem_used(z_stream *strm, char *prefix) +{ + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total); +} + +/* show the high water allocation in bytes */ +local void mem_high(z_stream *strm, char *prefix) +{ + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater); +} + +/* release the memory allocation zone -- if there are any surprises, notify */ +local void mem_done(z_stream *strm, char *prefix) +{ + int count = 0; + struct mem_item *item, *next; + struct mem_zone *zone = strm->opaque; + + /* show high water mark */ + mem_high(strm, prefix); + + /* free leftover allocations and item structures, if any */ + item = zone->first; + while (item != NULL) { + free(item->ptr); + next = item->next; + free(item); + item = next; + count++; + } + + /* issue alerts about anything unexpected */ + if (count || zone->total) + fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n", + prefix, zone->total, count); + if (zone->notlifo) + fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); + if (zone->rogue) + fprintf(stderr, "** %s: %d frees not recognized\n", + prefix, zone->rogue); + + /* free the zone and delete from the stream */ + free(zone); + strm->opaque = Z_NULL; + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; +} + +/* -- inflate test routines -- */ + +/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This + decodes liberally, in that hex digits can be adjacent, in which case two in + a row writes a byte. Or they can be delimited by any non-hex character, + where the delimiters are ignored except when a single hex digit is followed + by a delimiter, where that single digit writes a byte. The returned data is + allocated and must eventually be freed. NULL is returned if out of memory. + If the length is not needed, then len can be NULL. */ +local unsigned char *h2b(const char *hex, unsigned *len) +{ + unsigned char *in, *re; + unsigned next, val; + + in = malloc((strlen(hex) + 1) >> 1); + if (in == NULL) + return NULL; + next = 0; + val = 1; + do { + if (*hex >= '0' && *hex <= '9') + val = (val << 4) + *hex - '0'; + else if (*hex >= 'A' && *hex <= 'F') + val = (val << 4) + *hex - 'A' + 10; + else if (*hex >= 'a' && *hex <= 'f') + val = (val << 4) + *hex - 'a' + 10; + else if (val != 1 && val < 32) /* one digit followed by delimiter */ + val += 240; /* make it look like two digits */ + if (val > 255) { /* have two digits */ + in[next++] = val & 0xff; /* save the decoded byte */ + val = 1; /* start over */ + } + } while (*hex++); /* go through the loop with the terminating null */ + if (len != NULL) + *len = next; + re = realloc(in, next); + return re == NULL ? in : re; +} + +/* generic inflate() run, where hex is the hexadecimal input data, what is the + text to include in an error message, step is how much input data to feed + inflate() on each call, or zero to feed it all, win is the window bits + parameter to inflateInit2(), len is the size of the output buffer, and err + is the error code expected from the first inflate() call (the second + inflate() call is expected to return Z_STREAM_END). If win is 47, then + header information is collected with inflateGetHeader(). If a zlib stream + is looking for a dictionary, then an empty dictionary is provided. + inflate() is run until all of the input data is consumed. */ +local void inf(char *hex, char *what, unsigned step, int win, unsigned len, + int err) +{ + int ret; + unsigned have; + unsigned char *in, *out; + z_stream strm, copy; + gz_header head; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, win); + if (ret != Z_OK) { + mem_done(&strm, what); + return; + } + out = malloc(len); assert(out != NULL); + if (win == 47) { + head.extra = out; + head.extra_max = len; + head.name = out; + head.name_max = len; + head.comment = out; + head.comm_max = len; + ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK); + } + in = h2b(hex, &have); assert(in != NULL); + if (step == 0 || step > have) + step = have; + strm.avail_in = step; + have -= step; + strm.next_in = in; + do { + strm.avail_out = len; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err); + if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) + break; + if (ret == Z_NEED_DICT) { + ret = inflateSetDictionary(&strm, in, 1); + assert(ret == Z_DATA_ERROR); + mem_limit(&strm, 1); + ret = inflateSetDictionary(&strm, out, 0); + assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ((struct inflate_state *)strm.state)->mode = DICT; + ret = inflateSetDictionary(&strm, out, 0); + assert(ret == Z_OK); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR); + } + ret = inflateCopy(©, &strm); assert(ret == Z_OK); + ret = inflateEnd(©); assert(ret == Z_OK); + err = 9; /* don't care next time around */ + have += strm.avail_in; + strm.avail_in = step > have ? have : step; + have -= strm.avail_in; + } while (strm.avail_in); + free(in); + free(out); + ret = inflateReset2(&strm, -8); assert(ret == Z_OK); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, what); +} + +/* cover all of the lines in inflate.c up to inflate() */ +local void cover_support(void) +{ + int ret; + z_stream strm; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); assert(ret == Z_OK); + mem_used(&strm, "inflate init"); + ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK); + ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK); + ret = inflateSetDictionary(&strm, Z_NULL, 0); + assert(ret == Z_STREAM_ERROR); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "prime"); + + inf("63 0", "force window allocation", 0, -15, 1, Z_OK); + inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); + inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); + inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); + inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream)); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); + + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); assert(ret == Z_OK); + ret = inflateEnd(&strm); assert(ret == Z_OK); + fputs("inflate built-in memory routines\n", stderr); +} + +/* cover all inflate() header and trailer cases and code after inflate() */ +local void cover_wrap(void) +{ + int ret; + z_stream strm, copy; + unsigned char dict[257]; + + ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); + ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflate bad parameters\n", stderr); + + inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); + inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); + inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); + inf("8 99", "set window size from header", 0, 0, 0, Z_OK); + inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); + inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); + inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, + Z_DATA_ERROR); + inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", + 0, 47, 0, Z_STREAM_END); + inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); + inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); + inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -8); + strm.avail_in = 2; + strm.next_in = (void *)"\x63"; + strm.avail_out = 1; + strm.next_out = (void *)&ret; + mem_limit(&strm, 1); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + memset(dict, 0, 257); + ret = inflateSetDictionary(&strm, dict, 257); + assert(ret == Z_OK); + mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); + ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x80"; + ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); + strm.avail_in = 4; + strm.next_in = (void *)"\0\0\xff\xff"; + ret = inflateSync(&strm); assert(ret == Z_OK); + (void)inflateSyncPoint(&strm); + ret = inflateCopy(©, &strm); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR); + (void)inflateMark(&strm); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "miscellaneous, force memory errors"); +} + +/* input and output functions for inflateBack() */ +local unsigned pull(void *desc, unsigned char **buf) +{ + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; + struct inflate_state *state; + + if (desc == Z_NULL) { + next = 0; + return 0; /* no input (already provided at next_in) */ + } + state = (void *)((z_stream *)desc)->state; + if (state != Z_NULL) + state->mode = SYNC; /* force an otherwise impossible situation */ + return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; +} + +local int push(void *desc, unsigned char *buf, unsigned len) +{ + buf += len; + return desc != Z_NULL; /* force error if desc not null */ +} + +/* cover inflateBack() up to common deflate data cases and after those */ +local void cover_back(void) +{ + int ret; + z_stream strm; + unsigned char win[32768]; + + ret = inflateBackInit_(Z_NULL, 0, win, 0, 0); + assert(ret == Z_VERSION_ERROR); + ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR); + ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL); + assert(ret == Z_STREAM_ERROR); + ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflateBack bad parameters\n", stderr); + + mem_setup(&strm); + ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x03"; + ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); + assert(ret == Z_STREAM_END); + /* force output error */ + strm.avail_in = 3; + strm.next_in = (void *)"\x63\x00"; + ret = inflateBack(&strm, pull, Z_NULL, push, &strm); + assert(ret == Z_BUF_ERROR); + /* force mode error by mucking with state */ + ret = inflateBack(&strm, pull, &strm, push, Z_NULL); + assert(ret == Z_STREAM_ERROR); + ret = inflateBackEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "inflateBack bad state"); + + ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); + ret = inflateBackEnd(&strm); assert(ret == Z_OK); + fputs("inflateBack built-in memory routines\n", stderr); +} + +/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ +local int try(char *hex, char *id, int err) +{ + int ret; + unsigned len, size; + unsigned char *in, *out, *win; + char *prefix; + z_stream strm; + + /* convert to hex */ + in = h2b(hex, &len); + assert(in != NULL); + + /* allocate work areas */ + size = len << 3; + out = malloc(size); + assert(out != NULL); + win = malloc(32768); + assert(win != NULL); + prefix = malloc(strlen(id) + 6); + assert(prefix != NULL); + + /* first with inflate */ + strcpy(prefix, id); + strcat(prefix, "-late"); + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, err < 0 ? 47 : -15); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + do { + strm.avail_out = size; + strm.next_out = out; + ret = inflate(&strm, Z_TREES); + assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); + if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) + break; + } while (strm.avail_in || strm.avail_out == 0); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + inflateEnd(&strm); + mem_done(&strm, prefix); + + /* then with inflateBack */ + if (err >= 0) { + strcpy(prefix, id); + strcat(prefix, "-back"); + mem_setup(&strm); + ret = inflateBackInit(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); + assert(ret != Z_STREAM_ERROR); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + inflateBackEnd(&strm); + mem_done(&strm, prefix); + } + + /* clean up */ + free(prefix); + free(win); + free(out); + free(in); + return ret; +} + +/* cover deflate data cases in both inflate() and inflateBack() */ +local void cover_inflate(void) +{ + try("0 0 0 0 0", "invalid stored block lengths", 1); + try("3 0", "fixed", 0); + try("6", "invalid block type", 1); + try("1 1 0 fe ff 0", "stored", 0); + try("fc 0 0", "too many length or distance symbols", 1); + try("4 0 fe ff", "invalid code lengths set", 1); + try("4 0 24 49 0", "invalid bit length repeat", 1); + try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); + try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); + try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", + "invalid literal/lengths set", 1); + try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); + try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); + try("2 7e ff ff", "invalid distance code", 1); + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); + + /* also trailer mismatch just in inflate() */ + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", + "incorrect length check", -1); + try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); + try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", + "long code", 0); + try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); + try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", + "long distance and extra", 0); + try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); + inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, + Z_STREAM_END); + inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); +} + +/* cover remaining lines in inftrees.c */ +local void cover_trees(void) +{ + int ret; + unsigned bits; + unsigned short lens[16], work[16]; + code *next, table[ENOUGH_DISTS]; + + /* we need to call inflate_table() directly in order to manifest not- + enough errors, since zlib insures that enough is always enough */ + for (bits = 0; bits < 15; bits++) + lens[bits] = (unsigned short)(bits + 1); + lens[15] = 15; + next = table; + bits = 15; + ret = inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + next = table; + bits = 1; + ret = inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + fputs("inflate_table not enough errors\n", stderr); +} + +/* cover remaining inffast.c decoding and window copying */ +local void cover_fast(void) +{ + inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" + " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); + inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" + " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, + Z_DATA_ERROR); + inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, + Z_DATA_ERROR); + inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, + Z_DATA_ERROR); + inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", + "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); + inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); + inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", + "contiguous and wrap around window", 6, -8, 259, Z_OK); + inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, + Z_STREAM_END); +} + +int main(void) +{ + fprintf(stderr, "%s\n", zlibVersion()); + cover_support(); + cover_wrap(); + cover_back(); + cover_inflate(); + cover_trees(); + cover_fast(); + return 0; +} diff --git a/src/external/zlib-1.2.11/test/minigzip.c b/src/external/zlib-1.2.11/test/minigzip.c new file mode 100644 index 000000000..e22fb08c0 --- /dev/null +++ b/src/external/zlib-1.2.11/test/minigzip.c @@ -0,0 +1,651 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* @(#) $Id$ */ + +#include "zlib.h" +#include + +#ifdef STDC +# include +# include +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# ifdef UNDER_CE +# include +# endif +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +#ifdef Z_SOLO +/* for Z_SOLO, create simplified gz* functions using deflate and inflate */ + +#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) +# include /* for unlink() */ +#endif + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + (void)q; + return calloc(n, m); +} + +void myfree(q, p) + void *q, *p; +{ + (void)q; + free(p); +} + +typedef struct gzFile_s { + FILE *file; + int write; + int err; + char *msg; + z_stream strm; +} *gzFile; + +gzFile gzopen OF((const char *, const char *)); +gzFile gzdopen OF((int, const char *)); +gzFile gz_open OF((const char *, int, const char *)); + +gzFile gzopen(path, mode) +const char *path; +const char *mode; +{ + return gz_open(path, -1, mode); +} + +gzFile gzdopen(fd, mode) +int fd; +const char *mode; +{ + return gz_open(NULL, fd, mode); +} + +gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gzFile gz; + int ret; + + gz = malloc(sizeof(struct gzFile_s)); + if (gz == NULL) + return NULL; + gz->write = strchr(mode, 'w') != NULL; + gz->strm.zalloc = myalloc; + gz->strm.zfree = myfree; + gz->strm.opaque = Z_NULL; + if (gz->write) + ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); + else { + gz->strm.next_in = 0; + gz->strm.avail_in = Z_NULL; + ret = inflateInit2(&(gz->strm), 15 + 16); + } + if (ret != Z_OK) { + free(gz); + return NULL; + } + gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : + fopen(path, gz->write ? "wb" : "rb"); + if (gz->file == NULL) { + gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); + free(gz); + return NULL; + } + gz->err = 0; + gz->msg = ""; + return gz; +} + +int gzwrite OF((gzFile, const void *, unsigned)); + +int gzwrite(gz, buf, len) + gzFile gz; + const void *buf; + unsigned len; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL || !gz->write) + return 0; + strm = &(gz->strm); + strm->next_in = (void *)buf; + strm->avail_in = len; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_NO_FLUSH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + return len; +} + +int gzread OF((gzFile, void *, unsigned)); + +int gzread(gz, buf, len) + gzFile gz; + void *buf; + unsigned len; +{ + int ret; + unsigned got; + unsigned char in[1]; + z_stream *strm; + + if (gz == NULL || gz->write) + return 0; + if (gz->err) + return 0; + strm = &(gz->strm); + strm->next_out = (void *)buf; + strm->avail_out = len; + do { + got = fread(in, 1, 1, gz->file); + if (got == 0) + break; + strm->next_in = in; + strm->avail_in = 1; + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_DATA_ERROR) { + gz->err = Z_DATA_ERROR; + gz->msg = strm->msg; + return 0; + } + if (ret == Z_STREAM_END) + inflateReset(strm); + } while (strm->avail_out); + return len - strm->avail_out; +} + +int gzclose OF((gzFile)); + +int gzclose(gz) + gzFile gz; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL) + return Z_STREAM_ERROR; + strm = &(gz->strm); + if (gz->write) { + strm->next_in = Z_NULL; + strm->avail_in = 0; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_FINISH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + deflateEnd(strm); + } + else + inflateEnd(strm); + fclose(gz->file); + free(gz); + return Z_OK; +} + +const char *gzerror OF((gzFile, int *)); + +const char *gzerror(gz, err) + gzFile gz; + int *err; +{ + *err = gz->err; + return gz->msg; +} + +#endif + +static char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); +#else + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); +#endif + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + unsigned len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf, sizeof(buf), "%s", file); +#else + strcpy(buf, file); +#endif + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); +#else + strcat(infile, GZ_SUFFIX); +#endif + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -r : compress with Z_RLE + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int copyout = 0; + int uncompr = 0; + gzFile file; + char *bname, outmode[20]; + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outmode, sizeof(outmode), "%s", "wb6 "); +#else + strcpy(outmode, "wb6 "); +#endif + + prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; + argc--, argv++; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + while (argc > 0) { + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if (strcmp(*argv, "-r") == 0) + outmode[3] = 'R'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (outmode[3] == ' ') + outmode[3] = 0; + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } + } else { + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } + } + } while (argv++, --argc); + } + return 0; +} diff --git a/src/external/zlib-1.2.11/treebuild.xml b/src/external/zlib-1.2.11/treebuild.xml new file mode 100644 index 000000000..fd75525f9 --- /dev/null +++ b/src/external/zlib-1.2.11/treebuild.xml @@ -0,0 +1,116 @@ + + + + zip compression library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/external/zlib-1.2.11/trees.c b/src/external/zlib-1.2.11/trees.c new file mode 100644 index 000000000..50cf4b457 --- /dev/null +++ b/src/external/zlib-1.2.11/trees.c @@ -0,0 +1,1203 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2017 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef ZLIB_DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local const static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local const static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local const static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef ZLIB_DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* !ZLIB_DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef ZLIB_DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !ZLIB_DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = (int)value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* ZLIB_DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef ZLIB_DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); + } + if (overflow == 0) return; + + Tracev((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2*16; + s->bits_sent += stored_len<<3; +#endif +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef ZLIB_DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef ZLIB_DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} diff --git a/src/external/zlib-1.2.11/trees.h b/src/external/zlib-1.2.11/trees.h new file mode 100644 index 000000000..d35639d82 --- /dev/null +++ b/src/external/zlib-1.2.11/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/src/external/zlib-1.2.11/uncompr.c b/src/external/zlib-1.2.11/uncompr.c new file mode 100644 index 000000000..f03a1a865 --- /dev/null +++ b/src/external/zlib-1.2.11/uncompr.c @@ -0,0 +1,93 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong *sourceLen; +{ + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong len, left; + Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } + else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (uLong)max ? max : (uInt)len; + len -= stream.avail_in; + } + err = inflate(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + inflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return uncompress2(dest, destLen, source, &sourceLen); +} diff --git a/src/external/zlib-1.2.11/watcom/watcom_f.mak b/src/external/zlib-1.2.11/watcom/watcom_f.mak new file mode 100644 index 000000000..37f4d74c1 --- /dev/null +++ b/src/external/zlib-1.2.11/watcom/watcom_f.mak @@ -0,0 +1,43 @@ +# Makefile for zlib +# OpenWatcom flat model +# Last updated: 28-Dec-2005 + +# To use, do "wmake -f watcom_f.mak" + +C_SOURCE = adler32.c compress.c crc32.c deflate.c & + gzclose.c gzlib.c gzread.c gzwrite.c & + infback.c inffast.c inflate.c inftrees.c & + trees.c uncompr.c zutil.c + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj & + gzclose.obj gzlib.obj gzread.obj gzwrite.obj & + infback.obj inffast.obj inflate.obj inftrees.obj & + trees.obj uncompr.obj zutil.obj + +CC = wcc386 +LINKER = wcl386 +CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx +ZLIB_LIB = zlib_f.lib + +.C.OBJ: + $(CC) $(CFLAGS) $[@ + +all: $(ZLIB_LIB) example.exe minigzip.exe + +$(ZLIB_LIB): $(OBJS) + wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj + wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj + wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj + wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj + wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj + +example.exe: $(ZLIB_LIB) example.obj + $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB) + +minigzip.exe: $(ZLIB_LIB) minigzip.obj + $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) + +clean: .SYMBOLIC + del *.obj + del $(ZLIB_LIB) + @echo Cleaning done diff --git a/src/external/zlib-1.2.11/watcom/watcom_l.mak b/src/external/zlib-1.2.11/watcom/watcom_l.mak new file mode 100644 index 000000000..193eed7b3 --- /dev/null +++ b/src/external/zlib-1.2.11/watcom/watcom_l.mak @@ -0,0 +1,43 @@ +# Makefile for zlib +# OpenWatcom large model +# Last updated: 28-Dec-2005 + +# To use, do "wmake -f watcom_l.mak" + +C_SOURCE = adler32.c compress.c crc32.c deflate.c & + gzclose.c gzlib.c gzread.c gzwrite.c & + infback.c inffast.c inflate.c inftrees.c & + trees.c uncompr.c zutil.c + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj & + gzclose.obj gzlib.obj gzread.obj gzwrite.obj & + infback.obj inffast.obj inflate.obj inftrees.obj & + trees.obj uncompr.obj zutil.obj + +CC = wcc +LINKER = wcl +CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx +ZLIB_LIB = zlib_l.lib + +.C.OBJ: + $(CC) $(CFLAGS) $[@ + +all: $(ZLIB_LIB) example.exe minigzip.exe + +$(ZLIB_LIB): $(OBJS) + wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj + wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj + wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj + wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj + wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj + +example.exe: $(ZLIB_LIB) example.obj + $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB) + +minigzip.exe: $(ZLIB_LIB) minigzip.obj + $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) + +clean: .SYMBOLIC + del *.obj + del $(ZLIB_LIB) + @echo Cleaning done diff --git a/src/external/zlib-1.2.11/win32/DLL_FAQ.txt b/src/external/zlib-1.2.11/win32/DLL_FAQ.txt new file mode 100644 index 000000000..12c009018 --- /dev/null +++ b/src/external/zlib-1.2.11/win32/DLL_FAQ.txt @@ -0,0 +1,397 @@ + + Frequently Asked Questions about ZLIB1.DLL + + +This document describes the design, the rationale, and the usage +of the official DLL build of zlib, named ZLIB1.DLL. If you have +general questions about zlib, you should see the file "FAQ" found +in the zlib distribution, or at the following location: + http://www.gzip.org/zlib/zlib_faq.html + + + 1. What is ZLIB1.DLL, and how can I get it? + + - ZLIB1.DLL is the official build of zlib as a DLL. + (Please remark the character '1' in the name.) + + Pointers to a precompiled ZLIB1.DLL can be found in the zlib + web site at: + http://www.zlib.net/ + + Applications that link to ZLIB1.DLL can rely on the following + specification: + + * The exported symbols are exclusively defined in the source + files "zlib.h" and "zlib.def", found in an official zlib + source distribution. + * The symbols are exported by name, not by ordinal. + * The exported names are undecorated. + * The calling convention of functions is "C" (CDECL). + * The ZLIB1.DLL binary is linked to MSVCRT.DLL. + + The archive in which ZLIB1.DLL is bundled contains compiled + test programs that must run with a valid build of ZLIB1.DLL. + It is recommended to download the prebuilt DLL from the zlib + web site, instead of building it yourself, to avoid potential + incompatibilities that could be introduced by your compiler + and build settings. If you do build the DLL yourself, please + make sure that it complies with all the above requirements, + and it runs with the precompiled test programs, bundled with + the original ZLIB1.DLL distribution. + + If, for any reason, you need to build an incompatible DLL, + please use a different file name. + + + 2. Why did you change the name of the DLL to ZLIB1.DLL? + What happened to the old ZLIB.DLL? + + - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required + compilation settings that were incompatible to those used by + a static build. The DLL settings were supposed to be enabled + by defining the macro ZLIB_DLL, before including "zlib.h". + Incorrect handling of this macro was silently accepted at + build time, resulting in two major problems: + + * ZLIB_DLL was missing from the old makefile. When building + the DLL, not all people added it to the build options. In + consequence, incompatible incarnations of ZLIB.DLL started + to circulate around the net. + + * When switching from using the static library to using the + DLL, applications had to define the ZLIB_DLL macro and + to recompile all the sources that contained calls to zlib + functions. Failure to do so resulted in creating binaries + that were unable to run with the official ZLIB.DLL build. + + The only possible solution that we could foresee was to make + a binary-incompatible change in the DLL interface, in order to + remove the dependency on the ZLIB_DLL macro, and to release + the new DLL under a different name. + + We chose the name ZLIB1.DLL, where '1' indicates the major + zlib version number. We hope that we will not have to break + the binary compatibility again, at least not as long as the + zlib-1.x series will last. + + There is still a ZLIB_DLL macro, that can trigger a more + efficient build and use of the DLL, but compatibility no + longer dependents on it. + + + 3. Can I build ZLIB.DLL from the new zlib sources, and replace + an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? + + - In principle, you can do it by assigning calling convention + keywords to the macros ZEXPORT and ZEXPORTVA. In practice, + it depends on what you mean by "an old ZLIB.DLL", because the + old DLL exists in several mutually-incompatible versions. + You have to find out first what kind of calling convention is + being used in your particular ZLIB.DLL build, and to use the + same one in the new build. If you don't know what this is all + about, you might be better off if you would just leave the old + DLL intact. + + + 4. Can I compile my application using the new zlib interface, and + link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or + earlier? + + - The official answer is "no"; the real answer depends again on + what kind of ZLIB.DLL you have. Even if you are lucky, this + course of action is unreliable. + + If you rebuild your application and you intend to use a newer + version of zlib (post- 1.1.4), it is strongly recommended to + link it to the new ZLIB1.DLL. + + + 5. Why are the zlib symbols exported by name, and not by ordinal? + + - Although exporting symbols by ordinal is a little faster, it + is risky. Any single glitch in the maintenance or use of the + DEF file that contains the ordinals can result in incompatible + builds and frustrating crashes. Simply put, the benefits of + exporting symbols by ordinal do not justify the risks. + + Technically, it should be possible to maintain ordinals in + the DEF file, and still export the symbols by name. Ordinals + exist in every DLL, and even if the dynamic linking performed + at the DLL startup is searching for names, ordinals serve as + hints, for a faster name lookup. However, if the DEF file + contains ordinals, the Microsoft linker automatically builds + an implib that will cause the executables linked to it to use + those ordinals, and not the names. It is interesting to + notice that the GNU linker for Win32 does not suffer from this + problem. + + It is possible to avoid the DEF file if the exported symbols + are accompanied by a "__declspec(dllexport)" attribute in the + source files. You can do this in zlib by predefining the + ZLIB_DLL macro. + + + 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling + convention. Why not use the STDCALL convention? + STDCALL is the standard convention in Win32, and I need it in + my Visual Basic project! + + (For readability, we use CDECL to refer to the convention + triggered by the "__cdecl" keyword, STDCALL to refer to + the convention triggered by "__stdcall", and FASTCALL to + refer to the convention triggered by "__fastcall".) + + - Most of the native Windows API functions (without varargs) use + indeed the WINAPI convention (which translates to STDCALL in + Win32), but the standard C functions use CDECL. If a user + application is intrinsically tied to the Windows API (e.g. + it calls native Windows API functions such as CreateFile()), + sometimes it makes sense to decorate its own functions with + WINAPI. But if ANSI C or POSIX portability is a goal (e.g. + it calls standard C functions such as fopen()), it is not a + sound decision to request the inclusion of , or to + use non-ANSI constructs, for the sole purpose to make the user + functions STDCALL-able. + + The functionality offered by zlib is not in the category of + "Windows functionality", but is more like "C functionality". + + Technically, STDCALL is not bad; in fact, it is slightly + faster than CDECL, and it works with variable-argument + functions, just like CDECL. It is unfortunate that, in spite + of using STDCALL in the Windows API, it is not the default + convention used by the C compilers that run under Windows. + The roots of the problem reside deep inside the unsafety of + the K&R-style function prototypes, where the argument types + are not specified; but that is another story for another day. + + The remaining fact is that CDECL is the default convention. + Even if an explicit convention is hard-coded into the function + prototypes inside C headers, problems may appear. The + necessity to expose the convention in users' callbacks is one + of these problems. + + The calling convention issues are also important when using + zlib in other programming languages. Some of them, like Ada + (GNAT) and Fortran (GNU G77), have C bindings implemented + initially on Unix, and relying on the C calling convention. + On the other hand, the pre- .NET versions of Microsoft Visual + Basic require STDCALL, while Borland Delphi prefers, although + it does not require, FASTCALL. + + In fairness to all possible uses of zlib outside the C + programming language, we choose the default "C" convention. + Anyone interested in different bindings or conventions is + encouraged to maintain specialized projects. The "contrib/" + directory from the zlib distribution already holds a couple + of foreign bindings, such as Ada, C++, and Delphi. + + + 7. I need a DLL for my Visual Basic project. What can I do? + + - Define the ZLIB_WINAPI macro before including "zlib.h", when + building both the DLL and the user application (except that + you don't need to define anything when using the DLL in Visual + Basic). The ZLIB_WINAPI macro will switch on the WINAPI + (STDCALL) convention. The name of this DLL must be different + than the official ZLIB1.DLL. + + Gilles Vollant has contributed a build named ZLIBWAPI.DLL, + with the ZLIB_WINAPI macro turned on, and with the minizip + functionality built in. For more information, please read + the notes inside "contrib/vstudio/readme.txt", found in the + zlib distribution. + + + 8. I need to use zlib in my Microsoft .NET project. What can I + do? + + - Henrik Ravn has contributed a .NET wrapper around zlib. Look + into contrib/dotzlib/, inside the zlib distribution. + + + 9. If my application uses ZLIB1.DLL, should I link it to + MSVCRT.DLL? Why? + + - It is not required, but it is recommended to link your + application to MSVCRT.DLL, if it uses ZLIB1.DLL. + + The executables (.EXE, .DLL, etc.) that are involved in the + same process and are using the C run-time library (i.e. they + are calling standard C functions), must link to the same + library. There are several libraries in the Win32 system: + CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. + Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that + depend on it should also be linked to MSVCRT.DLL. + + +10. Why are you saying that ZLIB1.DLL and my application should + be linked to the same C run-time (CRT) library? I linked my + application and my DLLs to different C libraries (e.g. my + application to a static library, and my DLLs to MSVCRT.DLL), + and everything works fine. + + - If a user library invokes only pure Win32 API (accessible via + and the related headers), its DLL build will work + in any context. But if this library invokes standard C API, + things get more complicated. + + There is a single Win32 library in a Win32 system. Every + function in this library resides in a single DLL module, that + is safe to call from anywhere. On the other hand, there are + multiple versions of the C library, and each of them has its + own separate internal state. Standalone executables and user + DLLs that call standard C functions must link to a C run-time + (CRT) library, be it static or shared (DLL). Intermixing + occurs when an executable (not necessarily standalone) and a + DLL are linked to different CRTs, and both are running in the + same process. + + Intermixing multiple CRTs is possible, as long as their + internal states are kept intact. The Microsoft Knowledge Base + articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 + "HOWTO: Link with the Correct C Run-Time (CRT) Library" + mention the potential problems raised by intermixing. + + If intermixing works for you, it's because your application + and DLLs are avoiding the corruption of each of the CRTs' + internal states, maybe by careful design, or maybe by fortune. + + Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such + as those provided by Borland, raises similar problems. + + +11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? + + - MSVCRT.DLL exists on every Windows 95 with a new service pack + installed, or with Microsoft Internet Explorer 4 or later, and + on all other Windows 4.x or later (Windows 98, Windows NT 4, + or later). It is freely distributable; if not present in the + system, it can be downloaded from Microsoft or from other + software provider for free. + + The fact that MSVCRT.DLL does not exist on a virgin Windows 95 + is not so problematic. Windows 95 is scarcely found nowadays, + Microsoft ended its support a long time ago, and many recent + applications from various vendors, including Microsoft, do not + even run on it. Furthermore, no serious user should run + Windows 95 without a proper update installed. + + +12. Why are you not linking ZLIB1.DLL to + <> ? + + - We considered and abandoned the following alternatives: + + * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or + LIBCMT.LIB) is not a good option. People are using the DLL + mainly to save disk space. If you are linking your program + to a static C library, you may as well consider linking zlib + in statically, too. + + * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because + CRTDLL.DLL is present on every Win32 installation. + Unfortunately, it has a series of problems: it does not + work properly with Microsoft's C++ libraries, it does not + provide support for 64-bit file offsets, (and so on...), + and Microsoft discontinued its support a long time ago. + + * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied + with the Microsoft .NET platform, and Visual C++ 7.0/7.1, + raises problems related to the status of ZLIB1.DLL as a + system component. According to the Microsoft Knowledge Base + article KB326922 "INFO: Redistribution of the Shared C + Runtime Component in Visual C++ .NET", MSVCR70.DLL and + MSVCR71.DLL are not supposed to function as system DLLs, + because they may clash with MSVCRT.DLL. Instead, the + application's installer is supposed to put these DLLs + (if needed) in the application's private directory. + If ZLIB1.DLL depends on a non-system runtime, it cannot + function as a redistributable system component. + + * Linking ZLIB1.DLL to non-Microsoft runtimes, such as + Borland's, or Cygwin's, raises problems related to the + reliable presence of these runtimes on Win32 systems. + It's easier to let the DLL build of zlib up to the people + who distribute these runtimes, and who may proceed as + explained in the answer to Question 14. + + +13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, + how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 + (Visual Studio .NET) or newer? + + - Due to the problems explained in the Microsoft Knowledge Base + article KB326922 (see the previous answer), the C runtime that + comes with the VC7 environment is no longer considered a + system component. That is, it should not be assumed that this + runtime exists, or may be installed in a system directory. + Since ZLIB1.DLL is supposed to be a system component, it may + not depend on a non-system component. + + In order to link ZLIB1.DLL and your application to MSVCRT.DLL + in VC7, you need the library of Visual C++ 6.0 or older. If + you don't have this library at hand, it's probably best not to + use ZLIB1.DLL. + + We are hoping that, in the future, Microsoft will provide a + way to build applications linked to a proper system runtime, + from the Visual C++ environment. Until then, you have a + couple of alternatives, such as linking zlib in statically. + If your application requires dynamic linking, you may proceed + as explained in the answer to Question 14. + + +14. I need to link my own DLL build to a CRT different than + MSVCRT.DLL. What can I do? + + - Feel free to rebuild the DLL from the zlib sources, and link + it the way you want. You should, however, clearly state that + your build is unofficial. You should give it a different file + name, and/or install it in a private directory that can be + accessed by your application only, and is not visible to the + others (i.e. it's neither in the PATH, nor in the SYSTEM or + SYSTEM32 directories). Otherwise, your build may clash with + applications that link to the official build. + + For example, in Cygwin, zlib is linked to the Cygwin runtime + CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. + + +15. May I include additional pieces of code that I find useful, + link them in ZLIB1.DLL, and export them? + + - No. A legitimate build of ZLIB1.DLL must not include code + that does not originate from the official zlib source code. + But you can make your own private DLL build, under a different + file name, as suggested in the previous answer. + + For example, zlib is a part of the VCL library, distributed + with Borland Delphi and C++ Builder. The DLL build of VCL + is a redistributable file, named VCLxx.DLL. + + +16. May I remove some functionality out of ZLIB1.DLL, by enabling + macros like NO_GZCOMPRESS or NO_GZIP at compile time? + + - No. A legitimate build of ZLIB1.DLL must provide the complete + zlib functionality, as implemented in the official zlib source + code. But you can make your own private DLL build, under a + different file name, as suggested in the previous answer. + + +17. I made my own ZLIB1.DLL build. Can I test it for compliance? + + - We prefer that you download the official DLL from the zlib + web site. If you need something peculiar from this DLL, you + can send your suggestion to the zlib mailing list. + + However, in case you do rebuild the DLL yourself, you can run + it with the test programs found in the DLL distribution. + Running these test programs is not a guarantee of compliance, + but a failure can imply a detected problem. + +** + +This document is written and maintained by +Cosmin Truta diff --git a/src/external/zlib-1.2.11/win32/Makefile.bor b/src/external/zlib-1.2.11/win32/Makefile.bor new file mode 100644 index 000000000..d152bbb7f --- /dev/null +++ b/src/external/zlib-1.2.11/win32/Makefile.bor @@ -0,0 +1,110 @@ +# Makefile for zlib +# Borland C++ for Win32 +# +# Usage: +# make -f win32/Makefile.bor +# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj + +# ------------ Borland C++ ------------ + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or +# added to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +CC = bcc32 +AS = bcc32 +LD = bcc32 +AR = tlib +CFLAGS = -a -d -k- -O2 $(LOC) +ASFLAGS = $(LOC) +LDFLAGS = $(LOC) + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +#OBJA = +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj +#OBJPA= + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $< + +.asm.obj: + $(AS) -c $(ASFLAGS) $< + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + $(AR) $(ZLIB_LIB) $(OBJPA) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del $(ZLIB_LIB) + -del *.obj + -del *.exe + -del *.tds + -del zlib.bak + -del foo.gz diff --git a/src/external/zlib-1.2.11/win32/Makefile.gcc b/src/external/zlib-1.2.11/win32/Makefile.gcc new file mode 100644 index 000000000..305be50af --- /dev/null +++ b/src/external/zlib-1.2.11/win32/Makefile.gcc @@ -0,0 +1,182 @@ +# Makefile for zlib, derived from Makefile.dj2. +# Modified for mingw32 by C. Spieler, 6/16/98. +# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003. +# Last updated: Mar 2012. +# Tested under Cygwin and MinGW. + +# Copyright (C) 1995-2003 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type from the top level zlib directory: +# +# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc +# +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc +# +# To install libz.a, zconf.h and zlib.h in the system directories, type: +# +# make install -fwin32/Makefile.gcc +# +# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set. +# +# To install the shared lib, append SHARED_MODE=1 to the make command : +# +# make install -fwin32/Makefile.gcc SHARED_MODE=1 + +# Note: +# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN), +# the DLL name should be changed from "zlib1.dll". + +STATICLIB = libz.a +SHAREDLIB = zlib1.dll +IMPLIB = libz.dll.a + +# +# Set to 1 if shared object needs to be installed +# +SHARED_MODE=0 + +#LOC = -DASMV +#LOC = -DZLIB_DEBUG -g + +PREFIX = +CC = $(PREFIX)gcc +CFLAGS = $(LOC) -O3 -Wall + +AS = $(CC) +ASFLAGS = $(LOC) -Wall + +LD = $(CC) +LDFLAGS = $(LOC) + +AR = $(PREFIX)ar +ARFLAGS = rcs + +RC = $(PREFIX)windres +RCFLAGS = --define GCC_WINDRES + +STRIP = $(PREFIX)strip + +CP = cp -fp +# If GNU install is available, replace $(CP) with install. +INSTALL = $(CP) +RM = rm -f + +prefix ?= /usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o +OBJA = + +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe + +test: example.exe minigzip.exe + ./example + echo hello world | ./minigzip | ./minigzip -d + +testdll: example_d.exe minigzip_d.exe + ./example_d + echo hello world | ./minigzip_d | ./minigzip_d -d + +.c.o: + $(CC) $(CFLAGS) -c -o $@ $< + +.S.o: + $(AS) $(ASFLAGS) -c -o $@ $< + +$(STATICLIB): $(OBJS) $(OBJA) + $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o + $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \ + -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o + $(STRIP) $@ + +example.exe: example.o $(STATICLIB) + $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB) + $(STRIP) $@ + +minigzip.exe: minigzip.o $(STATICLIB) + $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB) + $(STRIP) $@ + +example_d.exe: example.o $(IMPLIB) + $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB) + $(STRIP) $@ + +minigzip_d.exe: minigzip.o $(IMPLIB) + $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB) + $(STRIP) $@ + +example.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/example.c + +minigzip.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c + +zlibrc.o: win32/zlib1.rc + $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc + +.PHONY: install uninstall clean + +install: zlib.h zconf.h $(STATICLIB) $(IMPLIB) + @if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \ + echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \ + exit 1; \ + fi + -@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)' + -@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig + -if [ "$(SHARED_MODE)" = "1" ]; then \ + mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \ + $(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \ + $(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \ + fi + -$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)' + -$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)' + -$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)' + sed \ + -e 's|@prefix@|${prefix}|g' \ + -e 's|@exec_prefix@|${exec_prefix}|g' \ + -e 's|@libdir@|$(LIBRARY_PATH)|g' \ + -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \ + -e 's|@includedir@|$(INCLUDE_PATH)|g' \ + -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \ + zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc + +uninstall: + -if [ "$(SHARED_MODE)" = "1" ]; then \ + $(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \ + $(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \ + fi + -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h + -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h + -$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB) + +clean: + -$(RM) $(STATICLIB) + -$(RM) $(SHAREDLIB) + -$(RM) $(IMPLIB) + -$(RM) *.o + -$(RM) *.exe + -$(RM) foo.gz + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +gzclose.o: zlib.h zconf.h gzguts.h +gzlib.o: zlib.h zconf.h gzguts.h +gzread.o: zlib.h zconf.h gzguts.h +gzwrite.o: zlib.h zconf.h gzguts.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/src/external/zlib-1.2.11/win32/Makefile.msc b/src/external/zlib-1.2.11/win32/Makefile.msc new file mode 100644 index 000000000..6831882de --- /dev/null +++ b/src/external/zlib-1.2.11/win32/Makefile.msc @@ -0,0 +1,163 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.msc (standard build) +# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) +# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \ +# OBJA="inffas32.obj match686.obj" (use ASM code, x86) +# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \ +# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib + +CC = cl +AS = ml +LD = link +AR = lib +RC = rc +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE +ASFLAGS = -coff -Zi $(LOC) +LDFLAGS = -nologo -debug -incremental:no -opt:ref +ARFLAGS = -nologo +RCFLAGS = /dWIN32 /r + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \ + gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj +OBJA = + + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +$(STATICLIB): $(OBJS) $(OBJA) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res + $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/contrib/masmx64}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/contrib/masmx64}.asm.obj: + $(AS) -c $(ASFLAGS) $< + +{$(TOP)/contrib/masmx86}.asm.obj: + $(AS) -c $(ASFLAGS) $< + +adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h + +compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h + +crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h + +deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h + +gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ + $(TOP)/inffast.h $(TOP)/inffixed.h + +inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ + $(TOP)/inffast.h + +inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ + $(TOP)/inffast.h $(TOP)/inffixed.h + +inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h + +trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h + +uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h + +zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h + +gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm + +inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm + +inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \ + $(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h + +inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm + +match686.obj: $(TOP)/contrib\masmx86\match686.asm + +example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h + +zlib1.res: $(TOP)/win32/zlib1.rc + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + -del foo.gz diff --git a/src/external/zlib-1.2.11/win32/README-WIN32.txt b/src/external/zlib-1.2.11/win32/README-WIN32.txt new file mode 100644 index 000000000..df7ab7f4b --- /dev/null +++ b/src/external/zlib-1.2.11/win32/README-WIN32.txt @@ -0,0 +1,103 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.11 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled +examples are distributed in this package, example and minigzip. The example_d +and minigzip_d flavors validate that the zlib1.dll file is working correctly. + +Questions about zlib should be sent to . The zlib home page +is http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html +before asking for help. + + +Manifest: + +The package zlib-1.2.11-win32-x86.zip will contain the following files: + + README-WIN32.txt This document + ChangeLog Changes since previous zlib packages + DLL_FAQ.txt Frequently asked questions about zlib1.dll + zlib.3.pdf Documentation of this library in Adobe Acrobat format + + example.exe A statically-bound example (using zlib.lib, not the dll) + example.pdb Symbolic information for debugging example.exe + + example_d.exe A zlib1.dll bound example (using zdll.lib) + example_d.pdb Symbolic information for debugging example_d.exe + + minigzip.exe A statically-bound test program (using zlib.lib, not the dll) + minigzip.pdb Symbolic information for debugging minigzip.exe + + minigzip_d.exe A zlib1.dll bound test program (using zdll.lib) + minigzip_d.pdb Symbolic information for debugging minigzip_d.exe + + zlib.h Install these files into the compilers' INCLUDE path to + zconf.h compile programs which use zlib.lib or zdll.lib + + zdll.lib Install these files into the compilers' LIB path if linking + zdll.exp a compiled program to the zlib1.dll binary + + zlib.lib Install these files into the compilers' LIB path to link zlib + zlib.pdb into compiled programs, without zlib1.dll runtime dependency + (zlib.pdb provides debugging info to the compile time linker) + + zlib1.dll Install this binary shared library into the system PATH, or + the program's runtime directory (where the .exe resides) + zlib1.pdb Install in the same directory as zlib1.dll, in order to debug + an application crash using WinDbg or similar tools. + +All .pdb files above are entirely optional, but are very useful to a developer +attempting to diagnose program misbehavior or a crash. Many additional +important files for developers can be found in the zlib127.zip source package +available from http://zlib.net/ - review that package's README file for details. + + +Acknowledgments: + +The deflate format used by zlib was defined by Phil Katz. The deflate and +zlib specifications were written by L. Peter Deutsch. Thanks to all the +people who reported problems and suggested various improvements in zlib; they +are too numerous to cite here. + + +Copyright notice: + + (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/src/external/zlib-1.2.11/win32/VisualC.txt b/src/external/zlib-1.2.11/win32/VisualC.txt new file mode 100644 index 000000000..1005b2194 --- /dev/null +++ b/src/external/zlib-1.2.11/win32/VisualC.txt @@ -0,0 +1,3 @@ + +To build zlib using the Microsoft Visual C++ environment, +use the appropriate project from the contrib/vstudio/ directory. diff --git a/src/external/zlib-1.2.11/win32/zlib.def b/src/external/zlib-1.2.11/win32/zlib.def new file mode 100644 index 000000000..a2188b000 --- /dev/null +++ b/src/external/zlib-1.2.11/win32/zlib.def @@ -0,0 +1,94 @@ +; zlib data compression library +EXPORTS +; basic functions + zlibVersion + deflate + deflateEnd + inflate + inflateEnd +; advanced functions + deflateSetDictionary + deflateGetDictionary + deflateCopy + deflateReset + deflateParams + deflateTune + deflateBound + deflatePending + deflatePrime + deflateSetHeader + inflateSetDictionary + inflateGetDictionary + inflateSync + inflateCopy + inflateReset + inflateReset2 + inflatePrime + inflateMark + inflateGetHeader + inflateBack + inflateBackEnd + zlibCompileFlags +; utility functions + compress + compress2 + compressBound + uncompress + uncompress2 + gzopen + gzdopen + gzbuffer + gzsetparams + gzread + gzfread + gzwrite + gzfwrite + gzprintf + gzvprintf + gzputs + gzgets + gzputc + gzgetc + gzungetc + gzflush + gzseek + gzrewind + gztell + gzoffset + gzeof + gzdirect + gzclose + gzclose_r + gzclose_w + gzerror + gzclearerr +; large file functions + gzopen64 + gzseek64 + gztell64 + gzoffset64 + adler32_combine64 + crc32_combine64 +; checksum functions + adler32 + adler32_z + crc32 + crc32_z + adler32_combine + crc32_combine +; various hacks, don't look :) + deflateInit_ + deflateInit2_ + inflateInit_ + inflateInit2_ + inflateBackInit_ + gzgetc_ + zError + inflateSyncPoint + get_crc_table + inflateUndermine + inflateValidate + inflateCodesUsed + inflateResetKeep + deflateResetKeep + gzopen_w diff --git a/src/external/zlib-1.2.11/win32/zlib1.rc b/src/external/zlib-1.2.11/win32/zlib1.rc new file mode 100644 index 000000000..234e641c3 --- /dev/null +++ b/src/external/zlib-1.2.11/win32/zlib1.rc @@ -0,0 +1,40 @@ +#include +#include "../zlib.h" + +#ifdef GCC_WINDRES +VS_VERSION_INFO VERSIONINFO +#else +VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE +#endif + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit http://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/src/external/zlib-1.2.11/zconf.h.cmakein b/src/external/zlib-1.2.11/zconf.h.cmakein new file mode 100644 index 000000000..a7f24cce6 --- /dev/null +++ b/src/external/zlib-1.2.11/zconf.h.cmakein @@ -0,0 +1,536 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +#cmakedefine Z_PREFIX +#cmakedefine Z_HAVE_UNISTD_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO + typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/external/zlib-1.2.11/zconf.h.in b/src/external/zlib-1.2.11/zconf.h.in new file mode 100644 index 000000000..5e1d68a00 --- /dev/null +++ b/src/external/zlib-1.2.11/zconf.h.in @@ -0,0 +1,534 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO + typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/external/zlib-1.2.11/zlib.3 b/src/external/zlib-1.2.11/zlib.3 new file mode 100644 index 000000000..bda4eb073 --- /dev/null +++ b/src/external/zlib-1.2.11/zlib.3 @@ -0,0 +1,149 @@ +.TH ZLIB 3 "15 Jan 2017" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe, assuming that the standard library functions +used are thread safe, such as memory allocation routines. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms may be added later +with the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in the case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I test/example.c +and +.IR test/minigzip.c, +as well as other examples in the +.IR examples/ +directory. +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source. +.LP +.I zlib +is built in to many languages and operating systems, including but not limited to +Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. +.LP +An experimental package to read and write files in the .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/minizip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +source distribution. +.SH "SEE ALSO" +The +.I zlib +web site can be found at: +.IP +http://zlib.net/ +.LP +The data format used by the +.I zlib +library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) +.br +http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) +.br +http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) +.LP +Mark Nelson wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://marknelson.us/1997/01/01/zlib-engine/ +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://zlib.net/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS AND LICENSE +Version 1.2.11 +.LP +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler +.LP +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. +.LP +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: +.LP +.nr step 1 1 +.IP \n[step]. 3 +The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +.IP \n+[step]. +Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +.IP \n+[step]. +This notice may not be removed or altered from any source distribution. +.LP +Jean-loup Gailly Mark Adler +.br +jloup@gzip.org madler@alumni.caltech.edu +.LP +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/src/external/zlib-1.2.11/zlib.h b/src/external/zlib-1.2.11/zlib.h new file mode 100644 index 000000000..f09cdaf1e --- /dev/null +++ b/src/external/zlib-1.2.11/zlib.h @@ -0,0 +1,1912 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.11, January 15th, 2017 + + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.11" +#define ZLIB_VERNUM 0x12b0 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 11 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte will go here */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more ouput + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if any input has been consumed in a previous + deflate() call, then the input available so far is compressed with the old + level and strategy using deflate(strm, Z_BLOCK). There are three approaches + for the compression levels 0, 1..3, and 4..9 respectively. The new level + and strategy will take effect at the next call of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will not automatically decode concatenated gzip streams. + inflate() will return Z_STREAM_END at the end of the gzip stream. The state + would need to be reset to continue decoding a subsequent gzip stream. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + +ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen)); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Three times that size in buffer space is allocated. A larger buffer + size of, for example, 64K or 128K bytes will noticeably increase the speed + of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. Previously provided + data is flushed before the parameter change. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, + gzFile file)); +/* + Read up to nitems items of size size from file to buf, otherwise operating + as gzread() does. This duplicates the interface of stdio's fread(), with + size_t request and return types. If the library defines size_t, then + z_size_t is identical to size_t. If not, then z_size_t is an unsigned + integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevetheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, reseting and retrying on end-of-file, when size is not 1. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, + z_size_t nitems, gzFile file)); +/* + gzfwrite() writes nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/src/external/zlib-1.2.11/zlib.map b/src/external/zlib-1.2.11/zlib.map new file mode 100644 index 000000000..82ce98cf7 --- /dev/null +++ b/src/external/zlib-1.2.11/zlib.map @@ -0,0 +1,94 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + inflate_fast; + inflate_table; + zcalloc; + zcfree; + z_errmsg; + gz_error; + gz_intmax; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; + +ZLIB_1.2.9 { + inflateCodesUsed; + inflateValidate; + uncompress2; + gzfread; + gzfwrite; + deflateGetDictionary; + adler32_z; + crc32_z; +} ZLIB_1.2.7.1; diff --git a/src/external/zlib-1.2.11/zlib.pc.cmakein b/src/external/zlib-1.2.11/zlib.pc.cmakein new file mode 100644 index 000000000..a5e642938 --- /dev/null +++ b/src/external/zlib-1.2.11/zlib.pc.cmakein @@ -0,0 +1,13 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@INSTALL_LIB_DIR@ +sharedlibdir=@INSTALL_LIB_DIR@ +includedir=@INSTALL_INC_DIR@ + +Name: zlib +Description: zlib compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} diff --git a/src/external/zlib-1.2.11/zlib.pc.in b/src/external/zlib-1.2.11/zlib.pc.in new file mode 100644 index 000000000..7e5acf9c7 --- /dev/null +++ b/src/external/zlib-1.2.11/zlib.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib +Description: zlib compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} diff --git a/src/external/zlib-1.2.11/zlib2ansi b/src/external/zlib-1.2.11/zlib2ansi new file mode 100644 index 000000000..15e3e165f --- /dev/null +++ b/src/external/zlib-1.2.11/zlib2ansi @@ -0,0 +1,152 @@ +#!/usr/bin/perl + +# Transform K&R C function definitions into ANSI equivalent. +# +# Author: Paul Marquess +# Version: 1.0 +# Date: 3 October 2006 + +# TODO +# +# Asumes no function pointer parameters. unless they are typedefed. +# Assumes no literal strings that look like function definitions +# Assumes functions start at the beginning of a line + +use strict; +use warnings; + +local $/; +$_ = <>; + +my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments + +my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; +my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; +my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; + + +while (s/^ + ( # Start $1 + ( # Start $2 + .*? # Minimal eat content + ( ^ \w [\w\s\*]+ ) # $3 -- function name + \s* # optional whitespace + ) # $2 - Matched up to before parameter list + + \( \s* # Literal "(" + optional whitespace + ( [^\)]+ ) # $4 - one or more anythings except ")" + \s* \) # optional whitespace surrounding a Literal ")" + + ( (?: $dList )+ ) # $5 + + $sp ^ { # literal "{" at start of line + ) # Remember to $1 + //xsom + ) +{ + my $all = $1 ; + my $prefix = $2; + my $param_list = $4 ; + my $params = $5; + + StripComments($params); + StripComments($param_list); + $param_list =~ s/^\s+//; + $param_list =~ s/\s+$//; + + my $i = 0 ; + my %pList = map { $_ => $i++ } + split /\s*,\s*/, $param_list; + my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; + + my @params = split /\s*;\s*/, $params; + my @outParams = (); + foreach my $p (@params) + { + if ($p =~ /,/) + { + my @bits = split /\s*,\s*/, $p; + my $first = shift @bits; + $first =~ s/^\s*//; + push @outParams, $first; + $first =~ /^(\w+\s*)/; + my $type = $1 ; + push @outParams, map { $type . $_ } @bits; + } + else + { + $p =~ s/^\s+//; + push @outParams, $p; + } + } + + + my %tmp = map { /$pMatch/; $_ => $pList{$1} } + @outParams ; + + @outParams = map { " $_" } + sort { $tmp{$a} <=> $tmp{$b} } + @outParams ; + + print $prefix ; + print "(\n" . join(",\n", @outParams) . ")\n"; + print "{" ; + +} + +# Output any trailing code. +print ; +exit 0; + + +sub StripComments +{ + + no warnings; + + # Strip C & C++ coments + # From the perlfaq + $_[0] =~ + + s{ + /\* ## Start of /* ... */ comment + [^*]*\*+ ## Non-* followed by 1-or-more *'s + ( + [^/*][^*]*\*+ + )* ## 0-or-more things which don't start with / + ## but do end with '*' + / ## End of /* ... */ comment + + | ## OR C++ Comment + // ## Start of C++ comment // + [^\n]* ## followed by 0-or-more non end of line characters + + | ## OR various things which aren't comments: + + ( + " ## Start of " ... " string + ( + \\. ## Escaped char + | ## OR + [^"\\] ## Non "\ + )* + " ## End of " ... " string + + | ## OR + + ' ## Start of ' ... ' string + ( + \\. ## Escaped char + | ## OR + [^'\\] ## Non '\ + )* + ' ## End of ' ... ' string + + | ## OR + + . ## Anything other char + [^/"'\\]* ## Chars which doesn't start a comment, string or escape + ) + }{$2}gxs; + +} diff --git a/src/external/zlib-1.2.11/zutil.c b/src/external/zlib-1.2.11/zutil.c new file mode 100644 index 000000000..a76c6b0c7 --- /dev/null +++ b/src/external/zlib-1.2.11/zutil.c @@ -0,0 +1,325 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +z_const char * const z_errmsg[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +#include +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf; + ulg bsize = (ulg)items*size; + + (void)opaque; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + + (void)opaque; + + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + (void)opaque; + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + (void)opaque; + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + (void)opaque; + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + (void)opaque; + free(ptr); +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/src/external/zlib-1.2.11/zutil.h b/src/external/zlib-1.2.11/zutil.h new file mode 100644 index 000000000..b079ea6a8 --- /dev/null +++ b/src/external/zlib-1.2.11/zutil.h @@ -0,0 +1,271 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 2 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 7 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/src/headers/agent_op.h b/src/headers/agent_op.h new file mode 100644 index 000000000..232cce48d --- /dev/null +++ b/src/headers/agent_op.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __AGENT_OP_H +#define __AGENT_OP_H + +/* Check if syscheck is to be executed/restarted + * Returns 1 on success or 0 on failure (shouldn't be executed now) + */ +int os_check_restart_syscheck(void); + +/* Set syscheck to be restarted + * Returns 1 on success or 0 on failure + */ +int os_set_restart_syscheck(void); + +/* Read the agent name for the current agent + * Returns NULL on error + */ +char *os_read_agent_name(void); + +/* Read the agent IP for the current agent + * Returns NULL on error + */ +char *os_read_agent_ip(void); + +/* Read the agent ID for the current agent + * Returns NULL on error + */ +char *os_read_agent_id(void); + +/* Read the agent profile name for the current agent + * Returns NULL on error + */ +char *os_read_agent_profile(void); + +/* Write the agent info inside the queue, for the other processes to read + * Returns 1 on success or <= 0 on failure + */ +int os_write_agent_info(const char *agent_name, const char *agent_ip, const char *agent_id, + const char *cfg_profile_name) __attribute__((nonnull(1, 3))); + +#endif /* __AGENT_OP_H */ + diff --git a/src/headers/ar.h b/src/headers/ar.h new file mode 100644 index 000000000..2b6de25d4 --- /dev/null +++ b/src/headers/ar.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Active Response shared headers */ + +#ifndef __AR_H +#define __AR_H + +/* Recipient agents */ +#define ALL_AGENTS 0000001 +#define REMOTE_AGENT 0000002 +#define SPECIFIC_AGENT 0000004 +#define AS_ONLY 0000010 + +/* We now also support non Active Response messages in here */ +#define NO_AR_MSG 0000020 + +#define ALL_AGENTS_C 'A' +#define REMOTE_AGENT_C 'R' +#define SPECIFIC_AGENT_C 'S' +#define NONE_C 'N' +#define NO_AR_C '!' + +/* AR Queues to use */ +#define REMOTE_AR 00001 +#define LOCAL_AR 00002 + +/* Expected values */ +#define FILENAME 0000010 +#define SRCIP 0000004 +#define DSTIP 0000002 +#define USERNAME 0000001 + +#endif /* __AR_H */ + diff --git a/src/headers/custom_output_search.h b/src/headers/custom_output_search.h new file mode 100644 index 000000000..b80358394 --- /dev/null +++ b/src/headers/custom_output_search.h @@ -0,0 +1,15 @@ +#ifndef CUSTOM_OUTPUT_SEARCH_H_ +#define CUSTOM_OUTPUT_SEARCH_H_ + +/* Search for 'search' in string and replaces it by value + * Returns NULL on error, otherwise returns the orig string with the replacements + */ +char *searchAndReplace(const char *orig, const char *search, const char *value) __attribute__((nonnull)); + +/* Escape the newline characters + * Returns NULL on error, otherwise returns a newly allocated string + */ +char *escape_newlines(const char *orig) __attribute__((nonnull)); + +#endif /* CUSTOM_OUTPUT_SEARCH_H_ */ + diff --git a/src/headers/debug_op.h b/src/headers/debug_op.h new file mode 100644 index 000000000..238560de8 --- /dev/null +++ b/src/headers/debug_op.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions to generate debug/verbose/err reports + * + * We have two debug levels (1 and 2), a verbose mode and an error function + * + * To see these messages, use the "-d","-v" options (or "-d" twice to see debug2) + * The merror is printed by default when an important error occurs + */ + +#ifndef __DEBUG_H +#define __DEBUG_H + +#ifndef __GNUC__ +#define __attribute__(x) +#endif + +void debug1(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +void debug2(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +void merror(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +void verbose(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +void print_out(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +void log2file(const char *msg, ... ) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +void ErrorExit(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)) __attribute__ ((noreturn)); + +/* Use these three functions to set when you + * enter in debug, chroot or daemon mode + */ +void nowDebug(void); +void nowChroot(void); +void nowDaemon(void); + +int isChroot(void); + +/* Debug analysisd */ +#ifdef DEBUGAD +#define DEBUG_MSG(x,y,z) verbose(x,y,z) +#else +#define DEBUG_MSG(x,y,z) +#endif /* end debug analysisd */ + +#endif /* __DEBUG_H */ + diff --git a/src/headers/defs.h b/src/headers/defs.h new file mode 100644 index 000000000..5d9014302 --- /dev/null +++ b/src/headers/defs.h @@ -0,0 +1,317 @@ +/* Copyright (C) 2009-2019 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Global Definitions */ + +#ifndef __OS_HEADERS +#define __OS_HEADERS + +#define TRUE 1 +#define FALSE 0 + +#define READ 1 +#define WRITE 2 + +#define OS_BINARY 0 +#define OS_TEXT 1 + +/* Size limit control */ +#define OS_SIZE_8192 8192 +#define OS_SIZE_6144 6144 +#define OS_SIZE_4096 4096 +#define OS_SIZE_2048 2048 +#define OS_SIZE_1024 1024 +#define OS_SIZE_256 256 +#define OS_SIZE_128 128 + +#define OS_MAXSTR OS_SIZE_6144 /* Size for logs, sockets, etc */ +#define OS_BUFFER_SIZE OS_SIZE_2048 /* Size of general buffers */ +#define OS_FLSIZE OS_SIZE_256 /* Maximum file size */ +#define OS_HEADER_SIZE OS_SIZE_128 /* Maximum header size */ +#define OS_LOG_HEADER OS_SIZE_256 /* Maximum log header size */ +#define IPSIZE INET6_ADDRSTRLEN /* IP Address size */ + +/* Some global names */ +#define __openarmor_name "openarmor HIDS" +#define __openarmor_version "v3.8.0" +#define __author "openarmor Foundation" +#define __contact "contact@theopenarmor.org" +#define __site "https://www.theopenarmor.org" +#define __license "\ +This program is free software; you can redistribute it and/or modify\n\ +it under the terms of the GNU General Public License (version 2) as \n\ +published by the Free Software Foundation. For more details, go to \n\ +http://www.theopenarmor.org/main/license/\n" + +/* Maximum allowed PID */ +#ifdef SOLARIS +#define MAX_PID 29999 +#else +#define MAX_PID 32768 +#endif + +/* Limit of 256 agents */ +#ifndef MAX_AGENTS +#define MAX_AGENTS 256 +#endif + +/* First ID assigned by authd */ +#ifndef AUTHD_FIRST_ID +#define AUTHD_FIRST_ID 1024 +#endif + +/* Notify the manager */ +#define NOTIFY_TIME 600 /* ... every 600 seconds (10 minutes) */ + +/* User Configuration */ +#ifndef MAILUSER +#define MAILUSER "openarmorm" +#endif + +#ifndef USER +#define USER "openarmor" +#endif + +#ifndef REMUSER +#define REMUSER "openarmorr" +#endif + +#ifndef GROUPGLOBAL +#define GROUPGLOBAL "openarmor" +#endif + +#ifndef DEFAULTDIR +#define DEFAULTDIR "/var/openarmor" +#endif + +/* Default queue */ +#define DEFAULTQUEUE "/queue/openarmor/queue" + +/* Active Response files */ +#ifndef WIN32 +#define DEFAULTAR "/etc/shared/ar.conf" +#define AR_BINDIR "/active-response/bin" +#define AGENTCONFIGINT "/etc/shared/agent.conf" +#define AGENTCONFIG DEFAULTDIR "/etc/shared/agent.conf" +#else +#define DEFAULTAR "shared/ar.conf" +#define AR_BINDIR "active-response/bin" +#define AGENTCONFIG "shared/agent.conf" +#define AGENTCONFIGINT "shared/agent.conf" +#endif + +/* Exec queue */ +#define EXECQUEUE "/queue/alerts/execq" + +/* Active Response queue */ +#define ARQUEUE "/queue/alerts/ar" + +/* Decoder file */ +#define XML_DECODER "/etc/decoder.xml" +#define XML_LDECODER "/etc/local_decoder.xml" + +/* Agent information location */ +#define AGENTINFO_DIR "/queue/agent-info" + +/* Syscheck directory */ +#define SYSCHECK_DIR "/queue/syscheck" + +/* Rootcheck directory */ +#define ROOTCHECK_DIR "/queue/rootcheck" + +/* Diff queue */ +#define DIFF_DIR "/queue/diff" +#define DIFF_DIR_PATH DEFAULTDIR DIFF_DIR +#define DIFF_NEW_FILE "new-entry" +#define DIFF_LAST_FILE "last-entry" + +/* Syscheck data */ +#define SYSCHECK "syscheck" +#define SYSCHECK_REG "syscheck-registry" + +/* Rule path */ +#define RULEPATH "/rules" + +/* Wait file */ +#ifndef WIN32 +#define WAIT_FILE "/queue/openarmor/.wait" +#else +#define WAIT_FILE ".wait" +#endif + +/* Agent information file */ +#ifndef WIN32 +#define AGENT_INFO_FILE "/queue/openarmor/.agent_info" +#define AGENT_INFO_FILEP DEFAULTDIR AGENT_INFO_FILE +#else +#define AGENT_INFO_FILE ".agent_info" +#define AGENT_INFO_FILEP AGENT_INFO_FILE +#endif + +/* Syscheck restart */ +#ifndef WIN32 +#define SYSCHECK_RESTART "/var/run/.syscheck_run" +#define SYSCHECK_RESTART_PATH DEFAULTDIR SYSCHECK_RESTART +#else +#define SYSCHECK_RESTART "syscheck/.syscheck_run" +#define SYSCHECK_RESTART_PATH "syscheck/.syscheck_run" +#endif + +/* Agentless directories */ +#define AGENTLESSDIR "/agentless" +#define AGENTLESSPASS "/agentless/.passlist" +#define AGENTLESS_ENTRYDIR "/queue/agentless" + +/* Internal definitions files */ +#ifndef WIN32 +#define openarmor_DEFINES "/etc/internal_options.conf" +#define openarmor_LDEFINES "/etc/local_internal_options.conf" +#else +#define openarmor_DEFINES "internal_options.conf" +#define openarmor_LDEFINES "local_internal_options.conf" +#endif + +/* Log directories */ +#define EVENTS "/logs/archives" +#define EVENTS_DAILY "/logs/archives/archives.log" +#define ALERTS "/logs/alerts" +#define ALERTS_PATH DEFAULTDIR ALERTS +#define ALERTS_DAILY "/logs/alerts/alerts.log" +#define ALERTSJSON_DAILY "/logs/alerts/alerts.json" +#define FWLOGS "/logs/firewall" +#define FWLOGS_DAILY "/logs/firewall/firewall.log" +#define EVENTSJSON_DAILY "/logs/archives/archives.json" + +/* Stats directories */ +#define STATWQUEUE "/stats/weekly-average" +#define STATQUEUE "/stats/hourly-average" +#define STATSAVED "/stats/totals" + +/* Authentication keys file */ +#ifndef WIN32 +#define KEYS_FILE "/etc/client.keys" +#define AUTHD_PASS "/etc/authd.pass" +#define KEYSFILE_PATH DEFAULTDIR KEYS_FILE +#define AUTHDPASS_PATH DEFAULTDIR AUTHD_PASS +#else +#define KEYS_FILE "client.keys" +#define KEYSFILE_PATH KEYS_FILE +#define AUTHD_PASS "authd.pass" +#define AUTHDPASS_PATH AUTHD_PASS +#endif + +#ifndef AUTH_FILE +#define AUTH_FILE KEYS_FILE +#endif + +/* Shared config directory */ +#ifndef WIN32 +#define SHAREDCFG_DIR "/etc/shared" +#else +#define SHAREDCFG_DIR "shared" +#endif + +/* Built-in defines */ +#define DEFAULTQPATH DEFAULTDIR DEFAULTQUEUE + +#ifndef WIN32 +#define openarmorCONF "/etc/openarmor.conf" +#define DEFAULTCPATH DEFAULTDIR openarmorCONF +#else +#define openarmorCONF "openarmor.conf" +#define DEFAULTCPATH "openarmor.conf" +#endif + +#ifndef WIN32 +#define DEFAULTARPATH DEFAULTDIR DEFAULTAR +#define AR_BINDIRPATH DEFAULTDIR AR_BINDIR +#define AGENTLESSDIRPATH DEFAULTDIR AGENTLESSDIR +#define AGENTLESSPASSPATH DEFAULTDIR AGENTLESSPASS +#define AGENTLESS_ENTRYDIRPATH DEFAULTDIR AGENTLESS_ENTRYDIR +#else +#define DEFAULTARPATH "shared/ar.conf" +#define AR_BINDIRPATH "active-response/bin" +#define AGENTLESSDIRPATH AGENTLESSDIR +#define AGENTLESSPASSPATH AGENTLESSPASS +#define AGENTLESS_ENTRYDIRPATH AGENTLESS_ENTRYDIR +#endif +#define EXECQUEUEPATH DEFAULTDIR EXECQUEUE + +#ifdef WIN32 +#define SHAREDCFG_DIRPATH SHAREDCFG_DIR +#else +#define SHAREDCFG_DIRPATH DEFAULTDIR SHAREDCFG_DIR +#endif + +#define SHAREDCFG_FILE SHAREDCFG_DIR "/merged.mg" +#define SHAREDCFG_FILEPATH SHAREDCFG_DIRPATH "/merged.mg" +#define SHAREDCFG_FILENAME "merged.mg" + +#define WAIT_FILE_PATH DEFAULTDIR WAIT_FILE + +#define TMP_DIR "tmp" + +/* Windows COMSPEC */ +#define COMSPEC "C:\\Windows\\System32\\cmd.exe" + +/* Default ports */ +#ifndef DEFAULT_SECURE +#define DEFAULT_SECURE "1514" /* Default encrypted */ +#endif + +#ifndef DEFAULT_SYSLOG +#define DEFAULT_SYSLOG "514" /* Default syslog port - udp */ +#endif + +/* XML global elements */ +#ifndef xml_global +#define xml_global "global" +#endif + +#ifndef xml_alerts +#define xml_alerts "alerts" +#endif + +#ifndef xml_rules +#define xml_rules "rules" +#endif + +#ifndef xml_localfile +#define xml_localfile "localfile" +#endif + +#ifndef xml_remote +#define xml_remote "remote" +#endif + +#ifndef xml_client +#define xml_client "client" +#endif + +#ifndef xml_execd +#define xml_execd "execd" +#endif + +#ifndef xml_syscheck +#define xml_syscheck "syscheck" +#endif + +#ifndef xml_rootcheck +#define xml_rootcheck "rootcheck" +#endif + +#ifndef xml_command +#define xml_command "command" +#endif + +#ifndef xml_ar +#define xml_ar "active-response" +#endif + +#endif /* __OS_HEADERS */ diff --git a/src/headers/dirtree_op.h b/src/headers/dirtree_op.h new file mode 100644 index 000000000..77f16f9b3 --- /dev/null +++ b/src/headers/dirtree_op.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common API for dealing with directory trees */ + +#ifndef _OS_DIRTREE +#define _OS_DIRTREE + +typedef struct _OSDirTree OSDirTree; + +typedef struct _OSTreeNode { + struct _OSTreeNode *next; + OSDirTree *child; + + char *value; + void *data; +} OSTreeNode; + +struct _OSDirTree { + OSTreeNode *first_node; + OSTreeNode *last_node; +}; + +OSDirTree *OSDirTree_Create(void); +void OSDirTree_AddToTree(OSDirTree *tree, const char *str, void *data, char sep) __attribute__((nonnull(1, 2))); +void *OSDirTree_SearchTree(const OSDirTree *tree, const char *str, char sep) __attribute__((nonnull)); + +OSTreeNode *OSDirTree_GetFirstNode(OSDirTree *tree) __attribute__((nonnull)); + +#endif /* _OS_DIRTREE */ + diff --git a/src/headers/file-queue.h b/src/headers/file-queue.h new file mode 100644 index 000000000..80c3e6e64 --- /dev/null +++ b/src/headers/file-queue.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CFQUEUE_H +#define __CFQUEUE_H + +#define MAX_FQUEUE 256 +#define FQ_TIMEOUT 5 + +/* File queue */ +typedef struct _file_queue { + time_t last_change; + int year; + int day; + int flags; + + char mon[4]; + char file_name[MAX_FQUEUE + 1]; + + FILE *fp; + struct stat f_status; +} file_queue; + +#include "read-alert.h" +int Init_FileQueue(file_queue *fileq, const struct tm *p, int flags) __attribute__((nonnull)); + +alert_data *Read_FileMon(file_queue *fileq, const struct tm *p, unsigned int timeout) __attribute__((nonnull)); + +#endif /* __CFQUEUE_H */ + diff --git a/src/headers/file_op.h b/src/headers/file_op.h new file mode 100644 index 000000000..e1d94134b --- /dev/null +++ b/src/headers/file_op.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions to handle operation with files */ + +#ifndef __FILE_H +#define __FILE_H + +#include +#include +#define OS_PIDFILE "/var/run" + +/* Set the program name - must be done before *anything* else */ +void OS_SetName(const char *name) __attribute__((nonnull)); + +time_t File_DateofChange(const char *file) __attribute__((nonnull)); + +int IsDir(const char *file) __attribute__((nonnull)); + +int CreatePID(const char *name, int pid) __attribute__((nonnull)); + +char *GetRandomNoise(); + +int DeletePID(const char *name) __attribute__((nonnull)); + +int MergeFiles(const char *finalpath, char **files) __attribute__((nonnull)); + +int MergeAppendFile(const char *finalpath, const char *files) __attribute__((nonnull(1))); + +int UnmergeFiles(const char *finalpath, const char *optdir) __attribute__((nonnull(1))); + +/* Daemonize a process */ +void goDaemon(void); + +/* Daemonize a process without closing stdin/stdout/stderr */ +void goDaemonLight(void); + +/* Not really a file operation, but returns the uname */ +char *getuname(void); + +/* Return basename of path */ +char *basename_ex(char *path) __attribute__((nonnull)); + +/* Rename file or directory */ +int rename_ex(const char *source, const char *destination) __attribute__((nonnull)); + +/* Create temporary file */ +int mkstemp_ex(char *tmp_path) __attribute__((nonnull)); + +/* Checks for Windows Vista */ +#ifdef WIN32 +int checkVista(); +int isVista; +#endif + +int w_ref_parent_folder(const char *path); + +void remove_control_characters(char *str); + +bool is_control_character(char c); +#endif /* __FILE_H */ diff --git a/src/headers/fs_op.h b/src/headers/fs_op.h new file mode 100644 index 000000000..91de9d892 --- /dev/null +++ b/src/headers/fs_op.h @@ -0,0 +1,52 @@ +/* @(#) $Id: ./src/headers/dirtree_op.h, 2011/09/08 dcid Exp $ + */ + +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + * + * License details at the LICENSE file included with openarmor or + * online at: http://www.theopenarmor.org/en/licensing.html + */ + +/* Common API for dealing with file system information */ + + +#ifndef _OS_FS +#define _OS_FS + +#ifndef WIN32 + +#ifdef Linux +#include +#endif + +#ifdef FreeBSD +#include +#include +#endif + +#endif + +struct file_system_type { + const char *name; +#ifdef WIN32 + const unsigned __int32 f_type; +#else + const uint32_t f_type; +#endif + const int flag; +}; + +extern const struct file_system_type network_file_systems[]; + +short IsNFS(const char *file) __attribute__((nonnull)); +short skipFS(const char *file) __attribute__((nonnull)); + +#endif + +/* EOF */ diff --git a/src/headers/hash_op.h b/src/headers/hash_op.h new file mode 100644 index 000000000..8b27ad0ac --- /dev/null +++ b/src/headers/hash_op.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common API for dealing with hash operations */ + +#ifndef _OS_HASHOP +#define _OS_HASHOP + +/* Node structure */ +typedef struct _OSHashNode { + struct _OSHashNode *next; + + char *key; + void *data; +} OSHashNode; + +typedef struct _OSHash { + unsigned int rows; + unsigned int initial_seed; + unsigned int constant; + + OSHashNode **table; +} OSHash; + +/* Prototypes */ + +/* Create and initialize hash */ +OSHash *OSHash_Create(void); + +/* Free the memory used by the hash */ +void *OSHash_Free(OSHash *self) __attribute__((nonnull)); + +/* Returns 0 on error + * Returns 1 on duplicated key (not added) + * Returns 2 on success + * Key must not be NULL + */ +int OSHash_Add(OSHash *hash, const char *key, void *data) __attribute__((nonnull(1, 2))); +int OSHash_Update(OSHash *hash, const char *key, void *data) __attribute__((nonnull(1, 2))); +void *OSHash_Delete(OSHash *self, const char *key) __attribute__((nonnull)); + +/* Returns NULL on error (key not found) + * Returns the key otherwise + * Key must not be NULL + */ +void *OSHash_Get(const OSHash *self, const char *key) __attribute__((nonnull)); + +int OSHash_setSize(OSHash *self, unsigned int new_size) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/help.h b/src/headers/help.h new file mode 100644 index 000000000..9aa23ddfd --- /dev/null +++ b/src/headers/help.h @@ -0,0 +1,19 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Help Function */ + +#ifndef __HELP_H +#define __HELP_H + +void print_header(void); +void print_version(void) __attribute__((noreturn)); + +#endif + diff --git a/src/headers/list_op.h b/src/headers/list_op.h new file mode 100644 index 000000000..27d56089c --- /dev/null +++ b/src/headers/list_op.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Common list API */ + +#ifndef _OS_LIST +#define _OS_LIST + +typedef struct _OSListNode { + struct _OSListNode *next; + struct _OSListNode *prev; + void *data; +} OSListNode; + +typedef struct _OSList { + OSListNode *first_node; + OSListNode *last_node; + OSListNode *cur_node; + + int currently_size; + int max_size; + + void (*free_data_function)(void *data); +} OSList; + +OSList *OSList_Create(void); + +int OSList_SetMaxSize(OSList *list, int max_size); +int OSList_SetFreeDataPointer(OSList *list, void (free_data_function)(void *)); + +OSListNode *OSList_GetFirstNode(OSList *) __attribute__((nonnull)); +OSListNode *OSList_GetLastNode(OSList *) __attribute__((nonnull)); +OSListNode *OSList_GetPrevNode(OSList *) __attribute__((nonnull)); +OSListNode *OSList_GetNextNode(OSList *) __attribute__((nonnull)); +OSListNode *OSList_GetCurrentlyNode(OSList *list) __attribute__((nonnull)); + +void OSList_DeleteCurrentlyNode(OSList *list) __attribute__((nonnull)); +void OSList_DeleteThisNode(OSList *list, OSListNode *thisnode) __attribute__((nonnull(1))); +void OSList_DeleteOldestNode(OSList *list) __attribute__((nonnull)); + +int OSList_AddData(OSList *list, void *data) __attribute__((nonnull(1))); + +#endif + diff --git a/src/headers/math_op.h b/src/headers/math_op.h new file mode 100644 index 000000000..365a8d912 --- /dev/null +++ b/src/headers/math_op.h @@ -0,0 +1,19 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef H_MATHOP_OS +#define H_MATHOP_OS + +/* Get the first available prime after the provided value + * Returns 0 on error + */ +unsigned int os_getprime(unsigned int val); + +#endif + diff --git a/src/headers/mem_op.h b/src/headers/mem_op.h new file mode 100644 index 000000000..17e43ea5f --- /dev/null +++ b/src/headers/mem_op.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __MEM_H +#define __MEM_H + +#include + +void **os_AddPtArray(void *pt, void **array); +char **os_AddStrArray(const char *str, char **array); +void os_FreeArray(char *ch1, char **ch2); +int os_IsStrOnArray(const char *str, char **array); +char *os_LoadString(char *at, const char *str) __attribute__((nonnull(2))); +void *memset_secure(void *v, int c, size_t n) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/mq_op.h b/src/headers/mq_op.h new file mode 100644 index 000000000..b425c53c1 --- /dev/null +++ b/src/headers/mq_op.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _MQ__H +#define _MQ__H + +/* Default queues */ +#define LOCALFILE_MQ '1' +#define SYSLOG_MQ '2' +#define HOSTINFO_MQ '3' +#define SECURE_MQ '4' +#define SYSCHECK_MQ '8' +#define ROOTCHECK_MQ '9' + +/* Queues for additional log types */ +#define MYSQL_MQ 'a' +#define POSTGRESQL_MQ 'b' + +int StartMQ(const char *key, short int type) __attribute__((nonnull)); + +int SendMSG(int queue, const char *message, const char *locmsg, char loc) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/os_err.h b/src/headers/os_err.h new file mode 100644 index 000000000..8a5db3cfb --- /dev/null +++ b/src/headers/os_err.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Basic error codes */ + +#ifndef __OS_ERR +#define __OS_ERR + +#define OS_SUCCESS 0 /* Success */ +#define OS_INVALID -1 /* Invalid entry */ +#define OS_NOTFOUND -2 /* Entry not found */ +#define OS_FILERR -3 /* Error in the file */ +#define OS_SIZELIM -4 /* Size limit problem */ +#define OS_CFGERR -5 /* Configuration error */ +#define OS_SOCKTERR -6 /* Socket error */ +#define OS_MISVALUE -7 /* There are values missing */ +#define OS_CONNERR -8 /* Connection failed */ +#define OS_UNDEF -9 /* Uknown error */ +#define OS_MEMERR -10 /* Memory Error */ +#define OS_SOCKBUSY -11 /* Socket busy -- try again */ + +#define OS_ENDFILE -20 /* End of file */ +#define OS_FINISH -21 /* Finished this task */ + +#endif /* __OS_ERR */ + diff --git a/src/headers/privsep_op.h b/src/headers/privsep_op.h new file mode 100644 index 000000000..069e42549 --- /dev/null +++ b/src/headers/privsep_op.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions for privilege separation */ + +#ifndef __PRIV_H +#define __PRIV_H + +#include "shared.h" + +uid_t Privsep_GetUser(const char *name) __attribute__((nonnull)); + +gid_t Privsep_GetGroup(const char *name) __attribute__((nonnull)); + +int Privsep_SetUser(uid_t uid); + +int Privsep_SetGroup(gid_t gid); + +int Privsep_Chroot(const char *path) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/pthreads_op.h b/src/headers/pthreads_op.h new file mode 100644 index 000000000..2287b0a76 --- /dev/null +++ b/src/headers/pthreads_op.h @@ -0,0 +1,18 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef PTHREADS_OP_H +#define PTHREADS_OP_H + +#ifndef WIN32 +int CreateThread(void *function_pointer(void *data), void *data) __attribute__((nonnull(1))); +#endif + +#endif + diff --git a/src/headers/randombytes.h b/src/headers/randombytes.h new file mode 100644 index 000000000..9c69de3f5 --- /dev/null +++ b/src/headers/randombytes.h @@ -0,0 +1,8 @@ +#ifndef __RANDOMBYTES_H +#define __RANDOMBYTES_H + +void randombytes(void *ptr, size_t length); +void srandom_init(void); + +#endif + diff --git a/src/headers/rc.h b/src/headers/rc.h new file mode 100644 index 000000000..2cb750c2b --- /dev/null +++ b/src/headers/rc.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Remote Control shared headers */ + +#ifndef __RC_H +#define __RC_H + +/* Global headers */ +#define CONTROL_HEADER "#!-" + +#define IsValidHeader(str) ((str[0] == '#') && \ + (str[1] == '!') && \ + (str[2] == '-') && \ + (str+=3) ) + +#define EXECD_HEADER "execd " +#define FILE_UPDATE_HEADER "up file " +#define FILE_CLOSE_HEADER "close file " +#define HC_STARTUP "agent startup " +#define HC_ACK "agent ack " +#define HC_SK_DB_COMPLETED "syscheck-db-completed" +#define HC_SK_RESTART "syscheck restart" + +#endif + diff --git a/src/headers/read-agents.h b/src/headers/read-agents.h new file mode 100644 index 000000000..a89748dda --- /dev/null +++ b/src/headers/read-agents.h @@ -0,0 +1,91 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CRAGENT_H +#define __CRAGENT_H + +#include + + +/* Unique key for each agent */ +typedef struct _agent_info { + char *last_keepalive; + char *syscheck_time; + char *syscheck_endtime; + char *rootcheck_time; + char *rootcheck_endtime; + char *os; + char *version; +} agent_info; + +/* Print syscheck db (of modified files) */ +int print_syscheck(const char *sk_name, const char *sk_ip, const char *fname, int print_registry, + int all_files, int csv_output, cJSON *json_output, int update_counter); + +/* Print rootcheck db */ +int print_rootcheck(const char *sk_name, const char *sk_ip, const char *fname, int resolved, + int csv_output, cJSON *json_output, int show_last); + + +/* Delete syscheck db */ +int delete_syscheck(const char *sk_name, const char *sk_ip, int full_delete) __attribute__((nonnull)); + +/* Delete rootcheck db */ +int delete_rootcheck(const char *sk_name, const char *sk_ip, int full_delete) __attribute__((nonnull)); + +/* Delete agent information */ +int delete_agentinfo(const char *name) __attribute__((nonnull)); + +/* Get all available agents */ +char **get_agents(int flag); + +/* Get all available agents with specified timeout */ +char **get_agents_with_timeout(int flag, int timeout); + +/* Free the agent list */ +void free_agents(char **agent_list); + +/* Print the text representation of the agent status */ +const char *print_agent_status(int status); + +/* Gets the status of an agent, based on the name/IP address */ +int get_agent_status(const char *agent_name, const char *agent_ip); + +/* Get information from an agent */ +agent_info *get_agent_info(const char *agent_name, const char *agent_ip) __attribute__((nonnull(2))); + +/* Connect to remoted to be able to send messages to the agents + * Returns the socket on success or -1 on failure + */ +int connect_to_remoted(void); + +#ifndef WIN32 +/* Return the unix permission string based on the syscheck db perm string + * agentless logs octal permissions, local syscheck decimal st_mode + * Returns a pointer to a local static array + */ +const char *agent_file_perm(char *perm); +#endif + +/* Sends a message to an agent + * Returns -1 on error + */ +int send_msg_to_agent(int msocket, const char *msg, const char *agt_id, const char *exec) __attribute__((nonnull(2))); + +#define GA_NOTACTIVE 2 +#define GA_ACTIVE 3 +#define GA_ALL 5 +#define GA_ALL_WSTATUS 7 + +/* Status */ +#define GA_STATUS_ACTIVE 12 +#define GA_STATUS_NACTIVE 13 +#define GA_STATUS_INV 14 + +#endif diff --git a/src/headers/read-alert.h b/src/headers/read-alert.h new file mode 100644 index 000000000..ff9b71f96 --- /dev/null +++ b/src/headers/read-alert.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __CRALERT_H +#define __CRALERT_H + +#define CRALERT_MAIL_SET 0x001 +#define CRALERT_EXEC_SET 0x002 +#define CRALERT_READ_ALL 0x004 +#define CRALERT_FP_SET 0x010 + +/* File queue */ +typedef struct _alert_data { + unsigned int rule; + unsigned int level; + char *alertid; + char *date; + char *location; + char *comment; + char *group; + char *srcip; + int srcport; + char *dstip; + int dstport; + char *user; + char *filename; + char *old_md5; + char *new_md5; + char *old_sha1; + char *new_sha1; + char **log; + char *srcgeoip; + char *dstgeoip; + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + char *file_size; + char *owner_chg; + char *group_chg; + char *perm_chg; + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ +} alert_data; + +alert_data *GetAlertData(int flag, FILE *fp) __attribute__((nonnull)); +void FreeAlertData(alert_data *al_data) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/regex_op.h b/src/headers/regex_op.h new file mode 100644 index 000000000..e2ea9c501 --- /dev/null +++ b/src/headers/regex_op.h @@ -0,0 +1,17 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef OS_REGEX_OP_H +#define OS_REGEX_OP_H + +/* POSIX regex pattern matching */ +int OS_PRegex(const char *str, const char *regex); + +#endif + diff --git a/src/headers/report_op.h b/src/headers/report_op.h new file mode 100644 index 000000000..882bf02e9 --- /dev/null +++ b/src/headers/report_op.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __REPORT_OP_H +#define __REPORT_OP_H + +#define REPORT_RELATED 1 +#define REPORT_FILTER 2 + +#define REPORT_REL_USER 0x001 +#define REPORT_REL_SRCIP 0x002 +#define REPORT_REL_LEVEL 0x004 +#define REPORT_REL_RULE 0x010 +#define REPORT_REL_GROUP 0x020 +#define REPORT_REL_LOCATION 0x040 +#define REPORT_TYPE_DAILY 0x100 +#define REPORT_REL_FILE 0x200 + +typedef struct _report_filter { + const char *report_name; + + const char *group; + const char *rule; + const char *level; + const char *location; + const char *user; + const char *srcip; + const char *files; + char *filename; + + OSStore *top_user; + OSStore *top_srcip; + OSStore *top_level; + OSStore *top_rule; + OSStore *top_group; + OSStore *top_location; + OSStore *top_files; + + int related_user; + int related_file; + int related_srcip; + int related_level; + int related_rule; + int related_group; + int related_location; + + int report_type; + int show_alerts; + FILE *fp; + +} report_filter; + +int os_report_configfilter(const char *filter_by, const char *filter_value, + report_filter *r_filter, int arg_type) __attribute__((nonnull(3))); +void os_report_printtop(void *topstore, const char *hname, int print_related) __attribute__((nonnull)); +void os_ReportdStart(report_filter *r_filter) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/rules_op.h b/src/headers/rules_op.h new file mode 100644 index 000000000..6cf777b5b --- /dev/null +++ b/src/headers/rules_op.h @@ -0,0 +1,158 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common API for dealing with rules */ + +#ifndef _OS_RULESOP_H +#define _OS_RULESOP_H + +#include "shared.h" + +/* Event context - stored in a uint8 */ +#define SAME_USER 0x001 /* 1 */ +#define SAME_SRCIP 0x002 /* 2 */ +#define SAME_ID 0x004 /* 4 */ +#define SAME_LOCATION 0x008 /* 8 */ +#define DIFFERENT_URL 0x010 +#define DIFFERENT_SRCIP 0x200 +#define DIFFERENT_SRCGEOIP 0x400 +#define SAME_SRCPORT 0x020 +#define SAME_DSTPORT 0x040 +#define SAME_DODIFF 0x100 +#define NOT_SAME_USER 0xffe /* 0xfff - 0x001 */ +#define NOT_SAME_SRCIP 0xffd /* 0xfff - 0x002 */ +#define NOT_SAME_ID 0xffb /* 0xfff - 0x004 */ +#define NOT_SAME_AGENT 0xff7 /* 0xfff - 0x008 */ + +/* Alert options - stored in a uint8 */ +#define DO_FTS 0x001 +#define DO_MAILALERT 0x002 +#define DO_LOGALERT 0x004 +#define NO_AR 0x008 +#define NO_ALERT 0x010 +#define DO_OVERWRITE 0x020 +#define DO_PACKETINFO 0x040 +#define DO_EXTRAINFO 0x100 +#define SAME_EXTRAINFO 0x200 + +/* Types of events (from decoders) */ +#define UNKNOWN 0 /* Unknown */ +#define SYSLOG 1 /* syslog message */ +#define IDS 2 /* IDS alert */ +#define FIREWALL 3 /* Firewall event */ +#define WEBLOG 7 /* Apache log */ +#define SQUID 8 /* Squid log */ +#define DECODER_WINDOWS 9 /* Windows log */ +#define HOST_INFO 10 /* Host information log (from nmap or similar) */ +#define openarmor_RL 11 /* openarmor rule */ + +/* FTS allowed values */ +#define FTS_NAME 001000 +#define FTS_USER 002000 +#define FTS_DSTUSER 004000 +#define FTS_SRCIP 000100 +#define FTS_DSTIP 000200 +#define FTS_LOCATION 000400 +#define FTS_ID 000010 +#define FTS_DATA 000020 +#define FTS_SYSTEMNAME 000040 + +typedef struct _RuleInfo { + int sigid; /* id attribute -- required */ + int level; /* level attribute --required */ + int maxsize; + int frequency; + int timeframe; + + u_int8_t context; /* Not a user option */ + + int firedtimes; /* Not a user option */ + int time_ignored; /* Not a user option */ + int ignore_time; + int ignore; + int ckignore; + int group_prev_matched_sz; + + int __frequency; + char **last_events; + + /* Not an option in the rule */ + u_int16_t alert_opts; + + /* Context options */ + u_int16_t context_opts; + + /* Category */ + u_int8_t category; + + /* Decoded as */ + u_int16_t decoded_as; + + /* List of previously matched events */ + OSList *sid_prev_matched; + + /* Pointer to a list (points to sid_prev_matched of if_matched_sid */ + OSList *sid_search; + + /* List of previously matched events in this group + * + * Every rule that has if_matched_group will have this list. Every rule that + * matches this group, is going to have a pointer to it (group_search). + */ + OSList **group_prev_matched; + + /* Pointer to group_prev_matched */ + OSList *group_search; + + /* Function pointer to the event_search */ + void *(*event_search)(void *lf, void *rule); + + char *group; + OSMatch *match; + OSRegex *regex; + + /* Policy-based rules */ + char *day_time; + char *week_day; + + os_ip **srcip; + os_ip **dstip; + OSMatch *srcport; + OSMatch *dstport; + OSMatch *user; + OSMatch *url; + OSMatch *id; + OSMatch *status; + OSMatch *hostname; + OSMatch *program_name; + OSMatch *extra_data; + char *action; + + char *comment; /* Description in the xml */ + char *info; + char *cve; + + char *if_sid; + char *if_level; + char *if_group; + + OSRegex *if_matched_regex; + OSMatch *if_matched_group; + int if_matched_sid; + + void **ar; + +} RuleInfo; + +int OS_ReadXMLRules(const char *rulefile, + void *(*ruleact_function)(RuleInfo *rule_1, void *data_1), + void *data) __attribute__((nonnull(1, 2))); + +#endif + diff --git a/src/headers/sec.h b/src/headers/sec.h new file mode 100644 index 000000000..017de0840 --- /dev/null +++ b/src/headers/sec.h @@ -0,0 +1,111 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __SEC_H +#define __SEC_H + +#include + +/* Unique key for each agent */ +typedef struct _keyentry { + time_t rcvd; + unsigned int local; + unsigned int keyid; + unsigned int global; + + char *id; + char *key; + char *name; + + os_ip *ip; + struct sockaddr_storage peer_info; + FILE *fp; +} keyentry; + +/* Key storage */ +typedef struct _keystore { + /* Array with all the keys */ + keyentry **keyentries; + + /* Hashes, based on the ID/IP to look up the keys */ + OSHash *keyhash_id; + OSHash *keyhash_ip; + + /* Total key size */ + unsigned int keysize; + + /* Key file stat */ + time_t file_change; +} keystore; + +/** Function prototypes -- key management **/ + +/* Check if the authentication keys are present */ +int OS_CheckKeys(void); + +void OS_PassEmptyKeyfile(void); + +/* Read the keys */ +void OS_ReadKeys(keystore *keys) __attribute((nonnull)); + +/* Free the auth keys */ +void OS_FreeKeys(keystore *keys) __attribute((nonnull)); + +/* Check if key changed */ +int OS_CheckUpdateKeys(const keystore *keys) __attribute((nonnull)); + +/* Update the keys if they changed on the system */ +int OS_UpdateKeys(keystore *keys) __attribute((nonnull)); + +/* Start counter for all agents */ +void OS_StartCounter(keystore *keys) __attribute((nonnull)); + +/* Remove counter for id */ +void OS_RemoveCounter(const char *id) __attribute((nonnull)); + +/* Configure to pass if keys file is empty */ +void OS_PassEmptyKeyfile(); + +/** Function prototypes -- agent authorization **/ + +/* Check if the IP is allowed */ +int OS_IsAllowedIP(keystore *keys, const char *srcip) __attribute((nonnull(1))); + +/* Check if the ID is allowed */ +int OS_IsAllowedID(keystore *keys, const char *id) __attribute((nonnull(1))); + +/* Check if the name is valid */ +int OS_IsAllowedName(const keystore *keys, const char *name) __attribute((nonnull)); + +/* Check if the id is valid and dynamic */ +int OS_IsAllowedDynamicID(keystore *keys, const char *id, const char *srcip) __attribute((nonnull(1))); + + +/** Function prototypes -- send/recv messages **/ + +/* Decrypt and decompress a remote message */ +char *ReadSecMSG(keystore *keys, char *buffer, char *cleartext, + int id, unsigned int buffer_size) __attribute((nonnull)); + +/* Create an openarmor message (encrypt and compress) */ +size_t CreateSecMSG(const keystore *keys, const char *msg, char *msg_encrypted, unsigned int id) __attribute((nonnull)); + + +/** Remote IDs directories and internal definitions */ +#ifndef WIN32 +#define RIDS_DIR "/queue/rids" +#else +#define RIDS_DIR "rids" +#endif + +#define SENDER_COUNTER "sender_counter" +#define KEYSIZE 128 + +#endif /* __SEC_H */ + diff --git a/src/headers/shared.h b/src/headers/shared.h new file mode 100644 index 000000000..40e4d3885 --- /dev/null +++ b/src/headers/shared.h @@ -0,0 +1,221 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* + * The stack smashing protector defeats some BoF via: gcc -fstack-protector + * Reference: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/cpp.pdf + */ + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) && (__GNUC_PATCHLEVEL__ >= 2)) || \ + ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || \ + (__GNUC__ >= 5)) + +/* Heuristically enable the stack protector on sensitive functions */ +#define __SSP__ 1 + +/* FORTIFY_SOURCE is RedHat / Fedora specific */ +#define FORTIFY_SOURCE +#endif + +#ifndef __SHARED_H +#define __SHARED_H + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif + +/* Global headers */ +#include +#include +#include +#include + +#ifdef __OpenBSD__ +#include +#endif + +#ifndef WIN32 +#include + +/* HPUX does not have select.h */ +#ifndef HPUX +#include +#endif + +#include +#endif /* WIN32 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The mingw32 builder used by travis.ci can't find glob.h + * Yet glob must work on actual win32. + */ +#ifndef __MINGW32__ +#include +#endif + +#ifndef WIN32 +#include +#include +#include +#include +#include +#else +/* WINVER needs to be 0x0501 or higher to pull in IPv6 functions */ +#ifndef WINVER +#define WINVER 0x0501 +#endif +#include +#include +#include +#include +#include +#endif + +#include +#include + +#include "defs.h" +#include "help.h" + +#include "os_err.h" + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif + +/* Global portability code */ + +#ifdef SOLARIS +#include +typedef uint32_t u_int32_t; +typedef uint16_t u_int16_t; +typedef uint8_t u_int8_t; + +#ifndef va_copy +#define va_copy __va_copy +#endif + +#endif /* SOLARIS */ + +#if defined HPUX +#include +typedef uint32_t u_int32_t; +typedef uint16_t u_int16_t; +typedef uint8_t u_int8_t; + +#define MSG_DONTWAIT 0 +#endif + +#ifdef Darwin +typedef int sock2len_t; +#endif + +#ifndef WIN32 +#define CloseSocket(x) close(x) +#endif + +#ifdef WIN32 +typedef int uid_t; +typedef int gid_t; +typedef int socklen_t; +#define sleep(x) Sleep(x * 1000) +#define srandom(x) srand(x) +#define random(x) rand(x) +#define lstat(x,y) stat(x,y) +#define CloseSocket(x) closesocket(x) +void WinSetError(); +typedef unsigned short int u_int16_t; +typedef unsigned char u_int8_t; + +#define MSG_DONTWAIT 0 + +#ifndef PROCESSOR_ARCHITECTURE_AMD64 +#define PROCESSOR_ARCHITECTURE_AMD64 9 +#endif +#endif /* WIN32 */ + +#ifdef AIX +#define MSG_DONTWAIT MSG_NONBLOCK +#endif + +/* Local name */ +extern const char *__local_name; + +/*** Global prototypes ***/ +/*** These functions will exit on error. No need to check return code ***/ + +/* for calloc: x = calloc(4,sizeof(char)) -> os_calloc(4,sizeof(char),x) */ +#define os_calloc(x,y,z) ((z = (__typeof__(z)) calloc(x,y)))?(void)1:ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)) + +#define os_strdup(x,y) ((y = strdup(x)))?(void)1:ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)) + +#define os_malloc(x,y) ((y = (__typeof__(y)) malloc(x)))?(void)1:ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)) + +#define os_free(x) (x)?free(x):merror("free a null") + +#define os_realloc(x,y,z) ((z = (__typeof__(z))realloc(x,y)))?(void)1:ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)) + +#define os_clearnl(x,p) if((p = strrchr(x, '\n')))*p = '\0'; + +#ifdef CLIENT +#define isAgent 1 +#else +#define isAgent 0 +#endif + +#include "debug_op.h" +#include "wait_op.h" +#include "agent_op.h" +#include "file_op.h" +#include "fs_op.h" +#include "mem_op.h" +#include "math_op.h" +#include "mq_op.h" +#include "privsep_op.h" +#include "pthreads_op.h" +#include "regex_op.h" +#include "sig_op.h" +#include "list_op.h" +#include "dirtree_op.h" +#include "hash_op.h" +#include "store_op.h" +#include "rc.h" +#include "ar.h" +#include "validate_op.h" +#include "file-queue.h" +#include "read-agents.h" +#include "report_op.h" +#include "string_op.h" +#include "randombytes.h" + +#include "os_xml/os_xml.h" +#include "os_regex/os_regex.h" + +#include "error_messages/error_messages.h" +#include "custom_output_search.h" + +#endif /* __SHARED_H */ + diff --git a/src/headers/sig_op.h b/src/headers/sig_op.h new file mode 100644 index 000000000..6bb81c2af --- /dev/null +++ b/src/headers/sig_op.h @@ -0,0 +1,25 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions to handle signal manipulation */ + +#ifndef __SIG_H +#define __SIG_H + +void HandleSIG(int sig) __attribute__((noreturn)); +void HandleSIGPIPE(int sig); + +/* Start signal manipulation */ +void StartSIG(const char *process_name) __attribute__((nonnull)); + +/* Start signal manipulation -- function as an argument */ +void StartSIG2(const char *process_name, void (*func)(int)) __attribute__((nonnull)); + +#endif + diff --git a/src/headers/store_op.h b/src/headers/store_op.h new file mode 100644 index 000000000..da77c414e --- /dev/null +++ b/src/headers/store_op.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Common list API */ + +#ifndef _OS_STORE +#define _OS_STORE + +/* Store node */ +typedef struct _OSStoreNode { + struct _OSStoreNode *next; + struct _OSStoreNode *prev; + void *data; + char *key; + size_t key_size; +} OSStoreNode; + +/* Store list */ +typedef struct _OSStore { + OSStoreNode *first_node; + OSStoreNode *last_node; + OSStoreNode *cur_node; + + int currently_size; + int max_size; + + void (*free_data_function)(void *data); +} OSStore; + +OSStore *OSStore_Create(void); +OSStore *OSStore_Free(OSStore *list) __attribute__((nonnull)); + +int OSStore_Put(OSStore *list, const char *key, void *data) __attribute__((nonnull(1, 2))); +int OSStore_Check(OSStore *list, const char *key) __attribute__((nonnull)); +int OSStore_NCheck(OSStore *list, const char *key) __attribute__((nonnull)); +int OSStore_NCaseCheck(OSStore *list, const char *key) __attribute__((nonnull)); +int OSStore_GetPosition(OSStore *list, const char *key) __attribute__((nonnull)); +void *OSStore_Get(OSStore *list, const char *key) __attribute__((nonnull)); +OSStoreNode *OSStore_GetFirstNode(OSStore *list) __attribute__((nonnull)); +int OSStore_Sort(OSStore *list, void *(sort_data_function)(void *d1, void *d2)) __attribute__((nonnull)); + +int OSStore_SetMaxSize(OSStore *list, int max_size); +int OSStore_SetFreeDataPointer(OSStore *list, void (free_data_function)(void *)); + +#endif + diff --git a/src/headers/string_op.h b/src/headers/string_op.h new file mode 100644 index 000000000..44e30b10c --- /dev/null +++ b/src/headers/string_op.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef H_STRINGOP_OS +#define H_STRINGOP_OS + +/* Trim the CR and/or LF from the last positions of a string */ +void os_trimcrlf(char *str) __attribute__((nonnull)); + +/* Similiar to Perl's substr() function */ +int os_substr(char *dest, const char *src, size_t position, ssize_t length) __attribute__((nonnull(1))); + +/* Remove a character from a string */ +char *os_strip_char(const char *source, char remove) __attribute__((nonnull)); + +/* Escape a list of characters with a backslash */ +char *os_shell_escape(const char *src); + +#endif + diff --git a/src/headers/validate_op.h b/src/headers/validate_op.h new file mode 100644 index 000000000..e16a11aff --- /dev/null +++ b/src/headers/validate_op.h @@ -0,0 +1,94 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __VALIDATE_H +#define __VALIDATE_H + +/* IP structure */ +typedef struct _os_ip { + char *ip; + struct sockaddr_storage ss; + unsigned int prefixlength; +}os_ip; + +/* Run-time definitions */ +int getDefine_Int(const char *high_name, const char *low_name, int min, int max) __attribute__((nonnull)); + +/* Check if IP_address is present at that_ip + * Returns 1 on success or 0 on failure + */ +int OS_IPFound(const char *ip_address, const os_ip *that_ip) __attribute__((nonnull)); + +/* Check if IP_address is present in the list_of_ips + * Returns 1 on success or 0 on failure. + * The list MUST be NULL terminated + */ +int OS_IPFoundList(const char *ip_address, os_ip **list_of_ips) __attribute__((nonnull)); + +/* Validate if an IP address is in the right format + * Returns 0 if doesn't match or 1 if it does (or 2 if it has a CIDR) + * WARNING: On success this function may modify the value of IP_address + */ +int OS_IsValidIP(const char *ip_address, os_ip *final_ip); + +/** int sacmp(struct sockaddr *sa1, struct sockaddr *sa2, int prefixlength) + * Compares two sockaddrs up to prefixlength. + * Returns 0 if doesn't match or 1 if they do. + */ +int sacmp(struct sockaddr *sa1, struct sockaddr *sa2, int prefixlength); + +/** Time range validations **/ + +/* Validate if a time is in an acceptable format for openarmor + * Returns 0 if doesn't match or a valid string for openarmor usage in success. + * WARNING: On success this function may modify the value of date + * + * Acceptable formats: + * hh:mm - hh:mm (24 hour format) + * !hh:mm -hh:mm (24 hour format) + * hh - hh (24 hour format) + * hh:mm am - hh:mm pm (12 hour format) + * hh am - hh pm (12 hour format) + */ +char *OS_IsValidTime(const char *time_str); + +/* Same as above, but only accepts a unique time, not a range */ +char *OS_IsValidUniqueTime(const char *time_str) __attribute__((nonnull)); + +/* Must be a valid string, called after OS_IsValidTime + * Returns 1 on success or 0 on failure + */ +int OS_IsonTime(const char *time_str, const char *openarmor_time) __attribute__((nonnull)); + +/* Same as above, but checks if time is the same or has passed a specified one */ +int OS_IsAfterTime(const char *time_str, const char *openarmor_time) __attribute__((nonnull)); + +/** Day validations **/ + +/* Check if the specified week day is in the range */ +int OS_IsonDay(int week_day, const char *openarmor_day) __attribute__((nonnull)); + +/* Validate if a day is in an acceptable format for openarmor + * Returns 0 if doesn't match or a valid string for openarmor usage in success + * WARNING: On success this function may modify the value of date + * + * Acceptable formats: + * weekdays, weekends, monday, tuesday, thursday,.. + * monday,tuesday + * mon,tue wed + */ +char *OS_IsValidDay(const char *day_str); + +/* Macros */ + +/* Check if the IP is a single host, not a network with a netmask */ +#define isSingleHost(x) ((x->ss.ss_family == AF_INET) ? (x->prefixlength == 32) : (x->prefixlength == 128)) + +#endif + diff --git a/src/headers/wait_op.h b/src/headers/wait_op.h new file mode 100644 index 000000000..562bb8b13 --- /dev/null +++ b/src/headers/wait_op.h @@ -0,0 +1,18 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __WAIT_OP_H +#define __WAIT_OP_H + +void os_setwait(void); +void os_delwait(void); +void os_wait(void); + +#endif + diff --git a/src/init/adduser.sh b/src/init/adduser.sh new file mode 100644 index 000000000..11f9d66e8 --- /dev/null +++ b/src/init/adduser.sh @@ -0,0 +1,120 @@ +#!/bin/sh + +set -e +set -u + +if ! [ $# -eq 5 ]; then + echo "Usage: ${0} USERNAME_DEFAULT USERNAME_MAIL USERNAME_REMOTE GROUPNAME DIRECTORY."; + exit 1; +fi + +echo "Wait for success..." + +USER=$1 +USER_MAIL=$2 +USER_REM=$3 +GROUP=$4 +DIR=$5 + +UNAME=$(uname); + +# Thanks Chuck L. for the mac addusers +if [ "$UNAME" = "Darwin" ]; then + if ! id -u "${USER}" > /dev/null 2>&1; then + + # Creating for <= 10.4 + if /usr/bin/sw_vers 2>/dev/null| grep "ProductVersion" | grep -E "10.2.|10.3|10.4" > /dev/null 2>&1; then + chmod +x ./init/darwin-addusers.pl + ./init/darwin-addusers.pl + else + chmod +x ./init/osx105-addusers.sh + ./init/osx105-addusers.sh + fi + fi + +else + if [ "$UNAME" = "FreeBSD" -o "$UNAME" = "DragonFly" ]; then + GROUPADD="/usr/sbin/pw groupadd" + USERADD="/usr/sbin/pw useradd" + OSMYSHELL="/sbin/nologin" + elif [ "$UNAME" = "SunOS" ]; then + GROUPADD="/usr/sbin/groupadd" + USERADD="/usr/sbin/useradd" + OSMYSHELL="/bin/false" + elif [ "$UNAME" = "AIX" ]; then + [ -f "/usr/bin/mkgroup" ] && GROUPADD="/usr/bin/mkgroup" || GROUPADD="/usr/sbin/mkgroup" + USERADD="/usr/sbin/useradd" + OSMYSHELL="/bin/false" + elif [ "$UNAME" = "OpenBSD" ]; then + GROUPADD="/usr/sbin/groupadd" + USERADD="/usr/sbin/useradd" + OSMYSHELL="/sbin/nologin" + else + # Alpine linux has adduser/addgroup + if [ -e "/etc/alpine-release" ]; then + GROUPADD="/usr/sbin/addgroup" + USERADD="/usr/sbin/adduser" + OSMYSHELL="/sbin/nologin" + else + # All current linux distributions should support system accounts for + # users/groups. If not, leave the GROUPADD/USERADD as it was before + # this change + sys_acct_chk () { + $1 --help 2>&1 | grep -e " *-r.*system account" >/dev/null 2>&1 && echo "$1 -r" || echo "$1" + } + GROUPADD=$(sys_acct_chk "/usr/sbin/groupadd -f") + USERADD=$(sys_acct_chk "/usr/sbin/useradd") + OSMYSHELL="/sbin/nologin" + fi + fi + + if [ -x /usr/bin/getent ]; then + if [ `getent group "${GROUP}" | wc -l` -lt 1 ]; then + ${GROUPADD} "${GROUP}" + fi + elif ! grep "^${GROUP}" /etc/group > /dev/null 2>&1; then + ${GROUPADD} "${GROUP}" + fi + + if [ "${OSMYSHELL}" = "/sbin/nologin" ]; then + # We first check if /sbin/nologin is present. If it is not, + # we look for /bin/false. If none of them is present, we + # just stick with nologin (no need to fail the install for that). + if [ ! -f ${OSMYSHELL} ]; then + if [ -f /bin/false ]; then + OSMYSHELL="/bin/false" + fi + fi + fi + + for U in ${USER} ${USER_MAIL} ${USER_REM}; do + if [ -x /usr/bin/getent ]; then + if [ `getent passwd ${U} | wc -l` -lt 1 ]; then + if [ "$UNAME" = "OpenBSD" ] || [ "$UNAME" = "SunOS" ]; then + ${USERADD} -d "${DIR}" -s ${OSMYSHELL} -g "${GROUP}" "${U}" + elif [ -e "/etc/alpine-release" ]; then + ${USERADD} -G ${GROUP} -s ${OSMYSHELL} -h ${DIR} -S ${U} + else + ${USERADD} "${U}" -d "${DIR}" -s ${OSMYSHELL} -g "${GROUP}" + fi + fi + elif ! `grep "^${U}" /etc/passwd > /dev/null 2>&1`; then + if [ "$UNAME" = "OpenBSD" ] || [ "$UNAME" = "SunOS" ]; then + ${USERADD} -d "${DIR}" -s ${OSMYSHELL} -g "${GROUP}" "${U}" + elif [ -e "/etc/alpine-release" ]; then + ${USERADD} -G ${GROUP} -s ${OSMYSHELL} -h ${DIR} -S ${U} + elif [ "$UNAME" = "AIX" ]; then + if `grep "shells=.*${OSMYSHELL}" /etc/security/login.cfg > /dev/null 2>&1`; then + ${USERADD} -d "${DIR}" -s ${OSMYSHELL} -g "${GROUP}" "${U}" + else + ${USERADD} -d "${DIR}" -g "${GROUP}" "${U}" + fi + else + ${USERADD} "${U}" -d "${DIR}" -s ${OSMYSHELL} -g "${GROUP}" + fi + fi + done +fi + +echo "success"; +exit 0; diff --git a/src/init/darwin-addusers.pl b/src/init/darwin-addusers.pl new file mode 100644 index 000000000..7079a228e --- /dev/null +++ b/src/init/darwin-addusers.pl @@ -0,0 +1,81 @@ +#!/usr/bin/env perl +####################################### +# Name: openarmor-add-ung.pl +# Desc: Add openarmor users and groups on OSX using the NetInfo cmds +# Author: Chuck L. +# License: GPL +### +# for vi: set tabstop=4 +####################################### + +# Variables and whatnot +my ($debug, $oUid, $oGid, @inUseUids, @inUseGids, $rev, $revDate); +$rev = '0.2-1'; +$revDate = '30-Aug-2006'; +$debug = '0'; +$fName = "/tmp/niusers.tmp"; + +# Commands +$NILOAD = "/usr/bin/niload"; +$NIRPT = "/usr/bin/nireport"; +$NIUTIL = "/usr/bin/niutil"; +$SORT = "/usr/bin/sort"; +$GREP = "/usr/bin/grep"; +$SUDO = "/usr/bin/sudo"; + +# Subroutine calls +findUsersGroups(); +createUsersGroups(); + +sub findUsersGroups { + @inUseUids = `$NIRPT . /users uid | $GREP "^5[0-9][0-9]" | $SORT -ru`; + @inUseGids = `$NIRPT . /groups gid | $GREP "^5[0-9][0-9]" | $SORT -ru`; + + foreach (@inUseUids) { + chomp(); + print "In use UID: $_\n" if $debug; + if ($oUid < $_) { + $oUid = $_; + } + } + $oUid++; + print "Next available UID: $oUid\n" if $debug; + + foreach (@inUseGids) { + chomp(); + print "In use GID: $_\n" if $debug; + if ($oGid < $_) { + $oGid = $_; + } + } + $oGid++; + print "Next available GID: $oGid\n" if $debug; +} # end sub + +sub createUsersGroups { + print "Sub - UID is: $oUid\n" if $debug; + print "Sub - GID is: $oGid\n" if $debug; + + my $oUidM = $oUid + 1; + my $oUidE = $oUid + 2; + my $oUidR = $oUid + 3; + + $niPid = open (NIFH, "| $SUDO $NILOAD -v group /"); + print "Adding openarmor group\n" if $debug; + print NIFH "openarmor:*:" . $oGid . ":openarmor,openarmorm,openarmorr\n"; + close (NIFH); + + $fh = open (NITMP, ">$fName") or die "Unable to create temp file: $!\n"; + + print "Adding openarmor users\n" if $debug; + print NITMP "openarmor:*:" . $oUid . ":" . $oGid . "::0:0:openarmor acct:/var/openarmor:/sbin/nologin\n"; + print NITMP "openarmorm:*:" . $oUidM . ":" . $oGid . "::0:0:openarmorm acct:/var/openarmor:/sbin/nologin\n"; + print NITMP "openarmorr:*:" . $oUidR . ":" . $oGid . "::0:0:openarmorr acct:/var/openarmor:/sbin/nologin\n"; + + close ($fh); + $rtnVal = system("$SUDO $NILOAD -v passwd / < $fName"); + print "Return value from syscmd: $rtnVal\n" if $debug; + unlink ($fName); + +} # end sub + diff --git a/src/init/darwin-init.sh b/src/init/darwin-init.sh new file mode 100644 index 000000000..623ddd0b7 --- /dev/null +++ b/src/init/darwin-init.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# Darwin init script. +# by Lorenzo Costanzia di Costigliole + +mkdir -p /Library/StartupItems/openarmor +cat </Library/StartupItems/openarmor/StartupParameters.plist + + + + + Description + openarmor Host-based Intrusion Detection System + Messages + + start + Starting openarmor + stop + Stopping openarmor + + Provides + + openarmor + + Requires + + IPFilter + + + +EOF + +cat </Library/StartupItems/openarmor/openarmor +#!/bin/sh + +. /etc/rc.common +. /etc/openarmor-init.conf +if [ "X\${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + + +StartService () +{ + \${DIRECTORY}/bin/openarmor-control start +} + +StopService () +{ + \${DIRECTORY}/bin/openarmor-control stop +} + +RestartService () +{ + \${DIRECTORY}/bin/openarmor-control restart +} + +RunService "\$1" +EOF +chmod 755 /Library/StartupItems/openarmor +chmod 644 /Library/StartupItems/openarmor/StartupParameters.plist +chmod 755 /Library/StartupItems/openarmor/openarmor diff --git a/src/init/functions.sh b/src/init/functions.sh new file mode 100644 index 000000000..79e72515c --- /dev/null +++ b/src/init/functions.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Shell script functions for the openarmor HIDS +# Author: Daniel B. Cid + +TRUE="true"; +FALSE="false"; + + +isFile() +{ + FILE=$1 + ls ${FILE} >/dev/null 2>&1 + if [ $? = 0 ]; then + echo "${TRUE}" + return 0; + fi + echo "${FALSE}" + return 1; +} + diff --git a/src/init/fw-check.sh b/src/init/fw-check.sh new file mode 100644 index 000000000..5a0c37703 --- /dev/null +++ b/src/init/fw-check.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +set -e +set -u + +# Checking which firewall to use. +UNAME=$(uname); +FILE=""; + +if [ "X${UNAME}" = "XFreeBSD" ]; then + # Is ipfw enabled? + if grep 'firewall_enable="YES"' /etc/rc.conf >/dev/null 2>&1; then + # Firewall is IPFW + FILE="ipfw.sh"; + echo "IPFW"; + fi + + # if pf enabled? + if grep 'pf_enable="YES"' /etc/rc.conf >/dev/null 2>&1; then + # Firewall is PF + FILE="pf.sh"; + echo "PF"; + fi + +# Darwin +elif [ "X${UNAME}" = "XDarwin" ]; then + # Is pfctl present? + if which pfctl; then + echo "PF"; + FILE="pf.sh"; + else + echo "IPFW"; + FILE="ipfw_mac.sh"; + fi + +elif [ "X${UNAME}" = "XOpenBSD" ]; then + if grep 'pf_enable="YES"' /etc/rc.conf >/dev/null 2>&1; then + # Firewall is PF + FILE="pf.sh"; + echo "PF"; + fi +fi + +# If file is set and execute flag is set +if [ ! "X$FILE" = "X" ]; then + if [ $# -eq 1 ] && [ "X$1" = "Xexecute" ]; then + cp -pr ../active-response/firewall-drop.sh ../active-response/firewalls/default-firewall-drop.sh + cp -pr ../active-response/firewalls/$FILE ../active-response/firewall-drop.sh + fi +fi + +exit 0; diff --git a/src/init/init.sh b/src/init/init.sh new file mode 100644 index 000000000..de42d4196 --- /dev/null +++ b/src/init/init.sh @@ -0,0 +1,150 @@ +#!/bin/sh +# Init functions for the openarmor HIDS +# Author: Daniel B. Cid + +UN=${NUNAME}; + +runInit() +{ + echo "" + echo "" + # Checking if it is a Redhat system. + if [ -r "/etc/redhat-release" ]; then + if [ -d /etc/rc.d/init.d ]; then + echo " - ${systemis} Redhat Linux." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids-rh.init /etc/rc.d/init.d/openarmor + chmod 555 /etc/rc.d/init.d/openarmor + chown root:openarmor /etc/rc.d/init.d/openarmor + /sbin/chkconfig --add openarmor > /dev/null 2>&1 + return 0; + fi + fi + # Checking for Gentoo + if [ -r "/etc/gentoo-release" ]; then + echo " - ${systemis} Gentoo Linux." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids-gentoo.init /etc/init.d/openarmor + chmod 555 /etc/init.d/openarmor + chown root:openarmor /etc/init.d/openarmor + rc-update add openarmor default + return 0; + fi + + # Suse + if [ -r "/etc/SuSE-release" ]; then + echo " - ${systemis} Suse Linux." + echo " - ${modifiedinit}" + + cp -pr ./src/init/openarmor-hids-suse.init /etc/init.d/openarmor + chmod 555 /etc/init.d/openarmor + chown root:openarmor /etc/init.d/openarmor + + /sbin/chkconfig --add openarmor > /dev/null 2>&1 + return 0; + fi + + # Checking for slackware (by Jack S. Lai) + if [ -r "/etc/slackware-version" ]; then + echo " - ${systemis} Slackware Linux." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids.init /etc/rc.d/rc.openarmor + chmod 555 /etc/rc.d/rc.openarmor + chown root:openarmor /etc/rc.d/rc.openarmor + + grep openarmor /etc/rc.d/rc.local > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "if [ -x /etc/rc.d/rc.openarmor ]; then" >> /etc/rc.d/rc.local + echo " /etc/rc.d/rc.openarmor start" >>/etc/rc.d/rc.local + echo "fi" >>/etc/rc.d/rc.local + fi + + return 0; + fi + + # Darwin init script (by Lorenzo Costanzia di Costigliole ) + if [ "X${NUNAME}" = "XDarwin" ]; then + # Generating darwin init script. + + echo " - ${systemis} Darwin." + echo " - ${modifiedinit}" + sh ./src/init/darwin-init.sh + return 0; + fi + + if [ "X${UN}" = "XSunOS" ]; then + echo " - ${systemis} Solaris (SunOS)." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids-solaris.init /etc/init.d/openarmor + chmod 755 /etc/init.d/openarmor + ln -s /etc/init.d/openarmor /etc/rc2.d/S97openarmor + ln -s /etc/init.d/openarmor /etc/rc3.d/S97openarmor + return 0; + fi + + if [ "X${UN}" = "XAIX" ]; then + echo " - ${systemis} AIX." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids-aix.init /etc/rc.d/init.d/openarmor + chmod 755 /etc/rc.d/init.d/openarmor + ln -s /etc/rc.d/init.d/openarmor /etc/rc.d/rc2.d/S97openarmor + ln -s /etc/rc.d/init.d/openarmor /etc/rc.d/rc3.d/S97openarmor + return 0; + fi + + if [ "X${UN}" = "XOpenBSD" -o "X${UN}" = "XNetBSD" -o "X${UN}" = "XFreeBSD" -o "X${UN}" = "XDragonFly" ]; then + # Checking for the presence of openarmor-control on rc.local + grep openarmor-control /etc/rc.local > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "echo \"${starting}\"" >> /etc/rc.local + echo "${INSTALLDIR}/bin/openarmor-control start" >> /etc/rc.local + fi + echo " - ${systemis} ${NUNAME}." + echo " - ${modifiedinit}" + return 0; + elif [ "X${NUNAME}" = "XLinux" ]; then + if [ -e "/etc/rc.d/rc.local" ]; then + echo " - ${systemis} Linux." + echo " - ${modifiedinit}" + + grep openarmor-control /etc/rc.d/rc.local > /dev/null 2>&1 + if [ $? != 0 ]; then + echo "echo \"${starting}\"" >> /etc/rc.d/rc.local + echo "${INSTALLDIR}/bin/openarmor-control start" >> /etc/rc.d/rc.local + fi + return 0; + elif [ -d "/etc/rc.d/init.d" ]; then + echo " - ${systemis} Linux (SysV)." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids.init /etc/rc.d/init.d/openarmor + chmod 555 /etc/rc.d/init.d/openarmor + chown root:openarmor /etc/rc.d/init.d/openarmor + return 0; + # Taken from Stephen Bunn openarmor howto. + elif [ -d "/etc/init.d" -a -f "/usr/sbin/update-rc.d" ]; then + echo " - ${systemis} Debian (Ubuntu or derivative)." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids-debian.init /etc/init.d/openarmor + chmod +x /etc/init.d/openarmor + chmod go-w /etc/init.d/openarmor + chown root:openarmor /etc/init.d/openarmor + update-rc.d openarmor defaults > /dev/null 2>&1 + return 0; + elif [ -e "/etc/alpine-release" ]; then + echo " - ${systemis} Alpine Linux." + echo " - ${modifiedinit}" + cp -pr ./src/init/openarmor-hids-alpine.init /etc/init.d/openarmor + chmod +x /etc/init.d/openarmor + chmod go-w /etc/init.d/openarmor + chown root:openarmor /etc/init.d/openarmor + return 0; + else + echo " - ${noboot}" + fi + else + echo " - ${noboot}" + fi + + return 1; +} + diff --git a/src/init/language.sh b/src/init/language.sh new file mode 100644 index 000000000..5fc05cd66 --- /dev/null +++ b/src/init/language.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# language.sh +# Author: Daniel B. Cid + +catError() +{ + FILE=$1; + + FILE_PATH="${TEMPLATE}/${LANGUAGE}/${ERROR}/${FILE}.txt" + if [ `isFile ${FILE_PATH}` = "${FALSE}" ]; then + # If we can't file in that specific language, try + # the english one. + FILE_PATH="${TEMPLATE}/en/${ERROR}/${FILE}.txt" + if [ `isFile ${FILE_PATH}` = "${FALSE}" ]; then + echo "0x0000 - Internal error for ${FILE}" + exit 1; + fi + fi + cat ${FILE_PATH} + exit 1; +} + +catMsg() +{ + FILE=$1; + + FILE_PATH="${TEMPLATE}/${LANGUAGE}/${MSG}/${FILE}.txt" + if [ `isFile ${FILE_PATH}` = "${FALSE}" ]; then + # If we can't file in that specific language, try + # the english one. + FILE_PATH="${TEMPLATE}/en/${MSG}/${FILE}.txt" + FILE_PATH="${MSG_TEMPLATE}/en/${FILE}.txt" + if [ `isFile ${FILE_PATH}` = "${FALSE}" ]; then + echo "0x0001 - Internal error for ${FILE}" + exit 1; + fi + fi + + cat ${FILE_PATH} +} + diff --git a/src/init/openarmor-client.sh b/src/init/openarmor-client.sh new file mode 100644 index 000000000..d1d1a72d1 --- /dev/null +++ b/src/init/openarmor-client.sh @@ -0,0 +1,230 @@ +#!/bin/sh +# openarmor-control This shell script takes care of starting +# or stopping openarmor-hids +# Author: Daniel B. Cid + +LOCAL=`dirname $0`; +cd ${LOCAL} +PWD=`pwd` +DIR=`dirname $PWD`; + + +### Do not modify below here ### +NAME="openarmor HIDS" +VERSION="v3.8.0" +DAEMONS="openarmor-logcollector openarmor-syscheckd openarmor-agentd openarmor-execd" + +[ -f /etc/openarmor-init.conf ] && . /etc/openarmor-init.conf + +## Locking for the start/stop +LOCK="${DIR}/var/start-script-lock" +LOCK_PID="${LOCK}/pid" + +# This number should be more than enough (even if it is +# started multiple times together). It will try for up +# to 10 attempts (or 10 seconds) to execute. +MAX_ITERATION="10" + +checkpid() +{ + for i in ${DAEMONS}; do + for j in `cat ${DIR}/var/run/${i}*.pid 2>/dev/null`; do + ps -p $j |grep openarmor >/dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "Deleting PID file '${DIR}/var/run/${i}-${j}.pid' not used..." + rm ${DIR}/var/run/${i}-${j}.pid + fi + done + done +} + +lock() +{ + i=0; + + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Waiting 1 second before trying again + sleep 1; + i=`expr $i + 1`; + + # If PID is not present, speed things a bit. + kill -0 `cat ${LOCK_PID}` >/dev/null 2>&1 + if [ ! $? = 0 ]; then + # Pid is not present. + i=`expr $i + 1`; + fi + + # We tried 10 times to acquire the lock. + if [ "$i" = "${MAX_ITERATION}" ]; then + # Unlocking and executing + unlock; + mkdir ${LOCK} > /dev/null 2>&1 + echo "$$" > ${LOCK_PID} + return; + fi + done +} + +unlock() +{ + rm -rf ${LOCK} +} + +help() +{ + # Help message + echo "Usage: $0 {start|stop|reload|restart|status}"; + exit 1; +} + +status() +{ + RETVAL=0 + for i in ${DAEMONS}; do + pstatus ${i}; + if [ $? = 0 ]; then + RETVAL=1 + echo "${i} not running..." + else + echo "${i} is running..." + fi + done + exit $RETVAL +} + +testconfig() +{ + # We first loop to check the config. + for i in ${SDAEMONS}; do + ${DIR}/bin/${i} -t; + if [ $? != 0 ]; then + echo "${i}: Configuration error. Exiting" + unlock; + exit 1; + fi + done +} + +# Start function +start() +{ + SDAEMONS="openarmor-execd openarmor-agentd openarmor-logcollector openarmor-syscheckd" + + echo "Starting $NAME $VERSION..." + lock; + checkpid; + + # We actually start them now. + for i in ${SDAEMONS}; do + pstatus ${i}; + if [ $? = 0 ]; then + ${DIR}/bin/${i}; + if [ $? != 0 ]; then + echo "${i} did not start"; + unlock; + exit 1; + fi + + echo "Started ${i}..." + else + echo "${i} already running..." + fi + done + + # After we start we give 2 seconds for the daemons + # to internally create their PID files. + sleep 2; + unlock; + echo "Completed." +} + +pstatus() +{ + pfile=$1; + + # pfile must be set + if [ "X${pfile}" = "X" ]; then + return 0; + fi + + ls ${DIR}/var/run/${pfile}*.pid > /dev/null 2>&1 + if [ $? = 0 ]; then + for j in `cat ${DIR}/var/run/${pfile}*.pid 2>/dev/null`; do + ps -p $j |grep openarmor >/dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "${pfile}: Process $j not used by openarmor, removing .." + rm -f ${DIR}/var/run/${pfile}-$j.pid + continue; + fi + + kill -0 $j > /dev/null 2>&1 + if [ $? = 0 ]; then + return 1; + fi + done + fi + + return 0; +} + +stopa() +{ + lock; + checkpid; + for i in ${DAEMONS}; do + pstatus ${i}; + if [ $? = 1 ]; then + echo "Killing ${i} .. "; + + kill `cat ${DIR}/var/run/${i}*.pid`; + else + echo "${i} not running .."; + fi + + rm -f ${DIR}/var/run/${i}*.pid + done + + unlock; + echo "$NAME $VERSION Stopped" +} + +### MAIN HERE ### + +case "$1" in +start) + testconfig + start + ;; +stop) + stopa + ;; +restart) + testconfig + stopa + sleep 1; + start + ;; +reload) + DAEMONS="openarmor-logcollector openarmor-syscheckd openarmor-agentd" + stopa + start + ;; +status) + status + ;; +help) + help + ;; +*) + help +esac + diff --git a/src/init/openarmor-hids-aix.init b/src/init/openarmor-hids-aix.init new file mode 100644 index 000000000..d5b544825 --- /dev/null +++ b/src/init/openarmor-hids-aix.init @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# name: openarmor +# purpose: Init script for openarmor-hids +# Aug. 07 2008 Chris Cuevas +# + +case "$1" in +start) + if [ -f /var/openarmor/bin/openarmor-control ]; then + echo "Starting openarmor" + /var/openarmor/bin/openarmor-control start + fi + ;; +stop) + if [ -f /var/openarmor/bin/openarmor-control ]; then + echo "Stopping openarmor" + /var/openarmor/bin/openarmor-control stop + fi + ;; +status) + if [ -f /var/openarmor/bin/openarmor-control ]; then + /var/openarmor/bin/openarmor-control status + fi + ;; +*) + echo "Usage: $0 (start | stop | status)" + exit 1 +esac diff --git a/src/init/openarmor-hids-alpine.init b/src/init/openarmor-hids-alpine.init new file mode 100644 index 000000000..82333a473 --- /dev/null +++ b/src/init/openarmor-hids-alpine.init @@ -0,0 +1,57 @@ +#!/sbin/openrc-run +DIRECTORY="/var/openarmor" +openarmor_CONTROL="${DIRECTORY}/bin/openarmor-control" + +depend() { + need net + use logger +} + +configtest() { + ebegin "Checking openarmor Configuration" + checkconfig + eend $? +} + +checkconfig() { + CONFIGFILE="${CONFIGFILE:-${DIRECTORY}/etc/openarmor.conf}" + if [ ! -r "${CONFIGFILE}" ]; then + eerror "Unable to read configuration file: ${CONFIGFILE}" + return 1 + fi + + # Maybe put some kind of config file syntax checking in here? XML is a little different + # so maybe not. + return $ret +} + +start() { + checkconfig || return 1 + ebegin "Starting openarmor-hids" + ${openarmor_CONTROL} start > /dev/null 2>&1 + eend $? +} + +stop() { + checkconfig || return 1 + ebegin "Stopping openarmor-hids" + ${openarmor_CONTROL} stop > /dev/null 2>&1 + eend $? +} + +restart() { + if ! service_started "${myservice}" ; then + eerror "openarmor is not running! Please start it before trying to reload it." + else + checkconfig || return 1 + ebegin "Reloading openarmor" + svc_stop ${openarmor_CONTROL} + svc_start ${openarmor_CONTROL} + eend $? + fi +} + +status() { + checkconfig || return 1 + ${openarmor_CONTROL} status +} diff --git a/src/init/openarmor-hids-debian.init b/src/init/openarmor-hids-debian.init new file mode 100644 index 000000000..08ac65211 --- /dev/null +++ b/src/init/openarmor-hids-debian.init @@ -0,0 +1,53 @@ +#!/bin/sh +# openarmor Controls openarmor HIDS +# Author: Daniel B. Cid +# Modified for Debian by Michael Starks (patch by Costas Drogos) + +### BEGIN INIT INFO +# Provides: openarmor +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Should-Start: $network +# Should-Stop: $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start and stop openarmor HIDS +# Description: Controls openarmor HIDS daemons +# +### END INIT INFO + +. /etc/openarmor-init.conf +if [ "X${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + +start() { + ${DIRECTORY}/bin/openarmor-control start +} + +stop() { + ${DIRECTORY}/bin/openarmor-control stop +} + +status() { + ${DIRECTORY}/bin/openarmor-control status +} + +case "$1" in +start) + start + ;; +stop) + stop + ;; +restart) + stop + start + ;; +status) + status + ;; +*) + echo "*** Usage: $0 {start|stop|restart|status}" + exit 1 +esac diff --git a/src/init/openarmor-hids-gentoo.init b/src/init/openarmor-hids-gentoo.init new file mode 100644 index 000000000..b6beef461 --- /dev/null +++ b/src/init/openarmor-hids-gentoo.init @@ -0,0 +1,67 @@ +#!/sbin/runscript +# Gentoo init script +# by gentuxx + +opts="${opts} status configtest" + +# Finding where openarmor is installed +. /etc/openarmor-init.conf +if [ "X${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + +openarmor_CONTROL="${DIRECTORY}/bin/openarmor-control" + +depend() { + need net + use logger +} + +configtest() { + ebegin "Checking openarmor Configuration" + checkconfig + eend $? +} + +checkconfig() { + CONFIGFILE="${CONFIGFILE:-${DIRECTORY}/etc/openarmor.conf}" + if [ ! -r "${CONFIGFILE}" ]; then + eerror "Unable to read configuration file: ${CONFIGFILE}" + return 1 + fi + + # Maybe put some kind of config file syntax checking in here? XML is a little different + # so maybe not. + return $ret +} + +start() { + checkconfig || return 1 + ebegin "Starting openarmor-hids" + ${openarmor_CONTROL} start > /dev/null 2>&1 + eend $? +} + +stop() { + checkconfig || return 1 + ebegin "Stopping openarmor-hids" + ${openarmor_CONTROL} stop > /dev/null 2>&1 + eend $? +} + +restart() { + if ! service_started "${myservice}" ; then + eerror "openarmor is not running! Please start it before trying to reload it." + else + checkconfig || return 1 + ebegin "Reloading openarmor" + svc_stop ${openarmor_CONTROL} + svc_start ${openarmor_CONTROL} + eend $? + fi +} + +status() { + checkconfig || return 1 + ${openarmor_CONTROL} status +} diff --git a/src/init/openarmor-hids-rh.init b/src/init/openarmor-hids-rh.init new file mode 100644 index 000000000..3bed052c1 --- /dev/null +++ b/src/init/openarmor-hids-rh.init @@ -0,0 +1,72 @@ +#!/bin/sh +# openarmor Controls openarmor HIDS on Redhat-based systems +# Author: Kayvan A. Sylvan +# Author: Daniel B. Cid +# +# chkconfig: 2345 99 15 +# description: Starts and stops openarmor HIDS (Host Intrusion Detection System) +# +# This will work on Redhat systems (maybe others too) + +# Source function library. +export LANG=C + +. /etc/init.d/functions +. /etc/openarmor-init.conf + +if [ "X${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + +start() { + echo -n "Starting openarmor: " + ${DIRECTORY}/bin/openarmor-control start > /dev/null + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + success + else + failure + fi + echo + return $RETVAL +} + +stop() { + echo -n "Stopping openarmor: " + ${DIRECTORY}/bin/openarmor-control stop > /dev/null + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + success + else + failure + fi + echo + return $RETVAL +} + +status() { + ${DIRECTORY}/bin/openarmor-control status + RETVAL=$? + return $RETVAL +} + +case "$1" in +start) + start + ;; +stop) + stop + ;; +restart) + stop + start + ;; +status) + status + ;; +*) + echo "*** Usage: openarmor {start|stop|restart|status}" + exit 1 +esac + +exit $? diff --git a/src/init/openarmor-hids-solaris.init b/src/init/openarmor-hids-solaris.init new file mode 100644 index 000000000..aa679852a --- /dev/null +++ b/src/init/openarmor-hids-solaris.init @@ -0,0 +1,73 @@ +#!/bin/bash +# openarmor Controls openarmor HIDS on Solaris systems +# Author: Kayvan A. Sylvan +# Author: Daniel B. Cid +# +# chkconfig: 2345 99 15 +# description: Starts and stops openarmor HIDS (Host Intrusion Detection System) +# +# This will work on Solaris systems (maybe others too) +# +# Modified by Chris Cuevas and Darryl Marsee to work on Solaris +# +# Source function library. +LANG=C +export $LANG + +. /etc/openarmor-init.conf + +if [ "X${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + +start() { + echo -n "Starting openarmor: " + ${DIRECTORY}/bin/openarmor-control start > /dev/null + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + echo success + else + echo failure + fi + echo + return $RETVAL +} + +stop() { + echo -n "Stopping openarmor: " + ${DIRECTORY}/bin/openarmor-control stop > /dev/null + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + echo success + else + echo failure + fi + echo + return $RETVAL +} + +status() { + ${DIRECTORY}/bin/openarmor-control status +} + + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status + ;; + *) + echo "*** Usage: openarmor {start|stop|restart|status}" + exit 1 +esac + +exit $? diff --git a/src/init/openarmor-hids-suse.init b/src/init/openarmor-hids-suse.init new file mode 100644 index 000000000..c32465f6a --- /dev/null +++ b/src/init/openarmor-hids-suse.init @@ -0,0 +1,94 @@ +#!/bin/sh +# Author: Scott Knauss scott@knauss.com +# +# /etc/init.d/openarmor +# +# +### BEGIN INIT INFO +# Provides: openarmor +# Required-Start: $syslog +# Required-Stop: +# Default-Start: 2 3 5 +# Default-Stop: +# Description: Start the openarmor HIDS daemon +### END INIT INFO + +# Shell functions sourced from /etc/rc.status: +# rc_check check and set local and overall rc status +# rc_status check and set local and overall rc status +# rc_status -v ditto but be verbose in local rc status +# rc_status -v -r ditto and clear the local rc status +# rc_failed set local and overall rc status to failed +# rc_failed set local and overall rc status to +# rc_reset clear local rc status (overall remains) +# rc_exit exit appropriate to overall rc status +. /etc/rc.status + +# First reset status of this service +rc_reset + +# Return values acc. to LSB for all commands but status: +# 0 - success +# 1 - generic or unspecified error +# 2 - invalid or excess argument(s) +# 3 - unimplemented feature (e.g. "reload") +# 4 - insufficient privilege +# 5 - program is not installed +# 6 - program is not configured +# 7 - program is not running +# +# Note that starting an already running service, stopping +# or restarting a not-running service as well as the restart +# with force-reload (in case signalling is not supported) are +# considered a success. + + +# Reading openarmor init conf. +if [ -f /etc/openarmor-init.conf ]; then + . /etc/openarmor-init.conf +fi + +if [ "X${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + + +#Just to make sure openarmor is installed ... +CONTROL="$DIRECTORY/bin/openarmor-control" + +test -x $CONTROL || { echo "$CONTROL not installed"; + if [ "$1" = "stop" ]; then exit 0; + else exit 5; fi; } + +start() { + ${DIRECTORY}/bin/openarmor-control start +} + +stop() { + ${DIRECTORY}/bin/openarmor-control stop +} + +status() { + ${DIRECTORY}/bin/openarmor-control status +} + +case "$1" in +start) + start + ;; +stop) + stop + ;; +restart) + stop + start + ;; +status) + status + ;; +*) + echo "*** Usage: $0 {start|stop|restart|status}" + exit 1 +esac + +exit 0 diff --git a/src/init/openarmor-hids.init b/src/init/openarmor-hids.init new file mode 100644 index 000000000..30956a0ed --- /dev/null +++ b/src/init/openarmor-hids.init @@ -0,0 +1,42 @@ +#!/bin/sh +# openarmor Controls openarmor HIDS +# Author: Daniel B. Cid +# Modified for slackware by Jack S. Lai + +. /etc/openarmor-init.conf +if [ "X${DIRECTORY}" = "X" ]; then + DIRECTORY="/var/openarmor" +fi + +start() { + ${DIRECTORY}/bin/openarmor-control start +} + +stop() { + ${DIRECTORY}/bin/openarmor-control stop +} + +status() { + ${DIRECTORY}/bin/openarmor-control status +} + +case "$1" in +start) + start + ;; +stop) + stop + ;; +restart) + stop + start + ;; +status) + status + ;; +*) + echo "*** Usage: $0 {start|stop|restart|status}" + exit 1 +esac + +exit 0 diff --git a/src/init/openarmor-local.sh b/src/init/openarmor-local.sh new file mode 100644 index 000000000..f2c6447ab --- /dev/null +++ b/src/init/openarmor-local.sh @@ -0,0 +1,309 @@ +#!/bin/sh +# openarmor-control This shell script takes care of starting +# or stopping openarmor-hids +# Author: Daniel B. Cid + +# Getting where we are installed +LOCAL=`dirname $0`; +cd ${LOCAL} +PWD=`pwd` +DIR=`dirname $PWD`; +PLIST=${DIR}/bin/.process_list; + +### Do not modify below here ### + +# Getting additional processes +ls -la ${PLIST} > /dev/null 2>&1 +if [ $? = 0 ]; then +. ${PLIST}; +fi + +NAME="openarmor HIDS" +VERSION="v3.8.0" +DAEMONS="openarmor-monitord openarmor-logcollector openarmor-syscheckd openarmor-analysisd openarmor-maild openarmor-execd ${DB_DAEMON} ${CSYSLOG_DAEMON} ${AGENTLESS_DAEMON}" + +## Locking for the start/stop +LOCK="${DIR}/var/start-script-lock" +LOCK_PID="${LOCK}/pid" + +# This number should be more than enough (even if it is +# started multiple times together). It will try for up +# to 10 attempts (or 10 seconds) to execute. +MAX_ITERATION="10" + +checkpid() { + for i in ${DAEMONS}; do + for j in `cat ${DIR}/var/run/${i}*.pid 2>/dev/null`; do + ps -p $j |grep openarmor >/dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "Deleting PID file '${DIR}/var/run/${i}-${j}.pid' not used..." + rm ${DIR}/var/run/${i}-${j}.pid + fi + done + done +} + +lock() { + i=0; + + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Waiting 1 second before trying again + sleep 1; + i=`expr $i + 1`; + + # If PID is not present, speed things a bit. + kill -0 `cat ${LOCK_PID}` >/dev/null 2>&1 + if [ ! $? = 0 ]; then + # Pid is not present. + i=`expr $i + 1`; + fi + + # We tried 10 times to acquire the lock. + if [ "$i" = "${MAX_ITERATION}" ]; then + # Unlocking and executing + unlock; + mkdir ${LOCK} > /dev/null 2>&1 + echo "$$" > ${LOCK_PID} + return; + fi + done +} + +unlock() +{ + rm -rf ${LOCK} +} + +help() +{ + # Help message + echo "" + echo "Usage: $0 {start|stop|restart|status|enable|disable}"; + exit 1; +} + +# Enables additional daemons +enable() +{ + if [ "X$2" = "X" ]; then + echo "" + echo "Enable options: database, client-syslog, agentless, debug" + echo "Usage: $0 enable [database|client-syslog|agentless|debug]" + exit 1; + fi + + if [ "X$2" = "Xdatabase" ]; then + echo "DB_DAEMON=openarmor-dbd" >> ${PLIST}; + elif [ "X$2" = "Xclient-syslog" ]; then + echo "CSYSLOG_DAEMON=openarmor-csyslogd" >> ${PLIST}; + elif [ "X$2" = "Xagentless" ]; then + echo "AGENTLESS_DAEMON=openarmor-agentlessd" >> ${PLIST}; + elif [ "X$2" = "Xdebug" ]; then + echo "DEBUG_CLI=\"-d\"" >> ${PLIST}; + else + echo "" + echo "Invalid enable option." + echo "" + echo "Enable options: database, client-syslog, agentless, debug" + echo "Usage: $0 enable [database|client-syslog|agentless|debug]" + exit 1; + fi +} + +# Disables additional daemons +disable() +{ + if [ "X$2" = "X" ]; then + echo "" + echo "Disable options: database, client-syslog, agentless, debug" + echo "Usage: $0 disable [database|client-syslog|agentless,debug]" + exit 1; + fi + + if [ "X$2" = "Xdatabase" ]; then + echo "DB_DAEMON=\"\"" >> ${PLIST}; + elif [ "X$2" = "Xclient-syslog" ]; then + echo "CSYSLOG_DAEMON=\"\"" >> ${PLIST}; + elif [ "X$2" = "Xagentless" ]; then + echo "AGENTLESS_DAEMON=\"\"" >> ${PLIST}; + elif [ "X$2" = "Xdebug" ]; then + echo "DEBUG_CLI=\"\"" >> ${PLIST}; + else + echo "" + echo "Invalid disable option." + echo "" + echo "Disable options: database, client-syslog, agentless, debug" + echo "Usage: $0 disable [database|client-syslog|agentless|debug]" + exit 1; + fi +} + +status() +{ + RETVAL=0 + for i in ${DAEMONS}; do + pstatus ${i}; + if [ $? = 0 ]; then + RETVAL=1 + echo "${i} not running..." + else + echo "${i} is running..." + fi + done + exit $RETVAL +} + +testconfig() +{ + # We first loop to check the config + for i in ${SDAEMONS}; do + ${DIR}/bin/${i} -t ${DEBUG_CLI}; + if [ $? != 0 ]; then + echo "${i}: Configuration error. Exiting" + unlock; + exit 1; + fi + done +} + +start() +{ + SDAEMONS="${DB_DAEMON} ${CSYSLOG_DAEMON} ${AGENTLESS_DAEMON} openarmor-maild openarmor-execd openarmor-analysisd openarmor-logcollector openarmor-syscheckd openarmor-monitord" + + echo "Starting $NAME $VERSION..." + echo | ${DIR}/bin/openarmor-logtest > /dev/null 2>&1; + if [ ! $? = 0 ]; then + echo "openarmor-analysisd: Configuration error. Exiting." + exit 1; + fi + + lock; + checkpid; + + # We actually start them now. + for i in ${SDAEMONS}; do + pstatus ${i}; + if [ $? = 0 ]; then + ${DIR}/bin/${i} ${DEBUG_CLI}; + if [ $? != 0 ]; then + echo "${i} did not start correctly."; + unlock; + exit 1; + fi + echo "Started ${i}..." + else + echo "${i} already running..." + fi + done + + # After we start we give 2 seconds for the daemons + # to internally create their PID files. + sleep 2; + unlock; + + ls -la "${DIR}/openarmor-agent/" >/dev/null 2>&1 + if [ $? = 0 ]; then + echo "" + echo "Starting sub agent directory (for hybrid mode)" + ${DIR}/openarmor-agent/bin/openarmor-control start + fi + + echo "Completed." +} + +pstatus() +{ + pfile=$1; + + # pfile must be set + if [ "X${pfile}" = "X" ]; then + return 0; + fi + + ls ${DIR}/var/run/${pfile}*.pid > /dev/null 2>&1 + if [ $? = 0 ]; then + for j in `cat ${DIR}/var/run/${pfile}*.pid 2>/dev/null`; do + ps -p $j |grep openarmor >/dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "${pfile}: Process $j not used by openarmor, removing .." + rm -f ${DIR}/var/run/${pfile}-$j.pid + continue; + fi + + kill -0 $j > /dev/null 2>&1 + if [ $? = 0 ]; then + return 1; + fi + done + fi + + return 0; +} + +stopa() +{ + lock; + checkpid; + for i in ${DAEMONS}; do + pstatus ${i}; + if [ $? = 1 ]; then + echo "Killing ${i} .. "; + kill `cat ${DIR}/var/run/${i}*.pid`; + else + echo "${i} not running .."; + fi + rm -f ${DIR}/var/run/${i}*.pid + done + + unlock; + + ls -la "${DIR}/openarmor-agent/" >/dev/null 2>&1 + if [ $? = 0 ]; then + echo "" + echo "Stopping sub agent directory (for hybrid mode)" + ${DIR}/openarmor-agent/bin/openarmor-control stop + fi + echo "$NAME $VERSION Stopped" +} + +### MAIN HERE ### + +case "$1" in +start) + testconfig + start + ;; +stop) + stopa + ;; +restart) + testconfig + stopa + sleep 1; + start + ;; +status) + status + ;; +help) + help + ;; +enable) + enable $1 $2; + ;; +disable) + disable $1 $2; + ;; +*) + help +esac + diff --git a/src/init/openarmor-server.sh b/src/init/openarmor-server.sh new file mode 100644 index 000000000..b8295e798 --- /dev/null +++ b/src/init/openarmor-server.sh @@ -0,0 +1,323 @@ +#!/bin/sh +# openarmor-control This shell script takes care of starting +# or stopping openarmor-hids +# Author: Daniel B. Cid + +# Getting where we are installed +LOCAL=`dirname $0`; +cd ${LOCAL} +PWD=`pwd` +DIR=`dirname $PWD`; +PLIST=${DIR}/bin/.process_list; + +### Do not modify below here ### + +# Getting additional processes +ls -la ${PLIST} > /dev/null 2>&1 +if [ $? = 0 ]; then +. ${PLIST}; +fi + +NAME="openarmor HIDS" +VERSION="v3.8.0" + +[ -f /etc/openarmor-init.conf ] && . /etc/openarmor-init.conf; + +DAEMONS="openarmor-monitord openarmor-logcollector openarmor-remoted openarmor-syscheckd openarmor-analysisd openarmor-maild openarmor-execd ${DB_DAEMON} ${CSYSLOG_DAEMON} ${AGENTLESS_DAEMON}" + +## Locking for the start/stop +LOCK="${DIR}/var/start-script-lock" +LOCK_PID="${LOCK}/pid" + +# This number should be more than enough (even if it is +# started multiple times together). It will try for up +# to 10 attempts (or 10 seconds) to execute. +MAX_ITERATION="10" + +checkpid() +{ + for i in ${DAEMONS}; do + for j in `cat ${DIR}/var/run/${i}*.pid 2>/dev/null`; do + ps -p $j |grep openarmor >/dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "Deleting PID file '${DIR}/var/run/${i}-${j}.pid' not used..." + rm ${DIR}/var/run/${i}-${j}.pid + fi + done + done +} + +lock() +{ + i=0; + + # Providing a lock. + while [ 1 ]; do + mkdir ${LOCK} > /dev/null 2>&1 + MSL=$? + if [ "${MSL}" = "0" ]; then + # Lock acquired (setting the pid) + echo "$$" > ${LOCK_PID} + return; + fi + + # Waiting 1 second before trying again + sleep 1; + i=`expr $i + 1`; + + # If PID is not present, speed things a bit. + kill -0 `cat ${LOCK_PID}` >/dev/null 2>&1 + if [ ! $? = 0 ]; then + # Pid is not present. + i=`expr $i + 1`; + fi + + # We tried 10 times to acquire the lock. + if [ "$i" = "${MAX_ITERATION}" ]; then + # Unlocking and executing + unlock; + mkdir ${LOCK} > /dev/null 2>&1 + echo "$$" > ${LOCK_PID} + return; + fi + done +} + +unlock() +{ + rm -rf ${LOCK} +} + +help() +{ + # Help message + echo "" + echo "Usage: $0 {start|stop|reload|restart|status|enable|disable}"; + exit 1; +} + +# Enables additional daemons +enable() +{ + if [ "X$2" = "X" ]; then + echo "" + echo "Enable options: database, client-syslog, agentless, debug" + echo "Usage: $0 enable [database|client-syslog|agentless|debug]" + exit 1; + fi + + if [ "X$2" = "Xdatabase" ]; then + echo "DB_DAEMON=openarmor-dbd" >> ${PLIST}; + elif [ "X$2" = "Xclient-syslog" ]; then + echo "CSYSLOG_DAEMON=openarmor-csyslogd" >> ${PLIST}; + elif [ "X$2" = "Xagentless" ]; then + echo "AGENTLESS_DAEMON=openarmor-agentlessd" >> ${PLIST}; + elif [ "X$2" = "Xdebug" ]; then + echo "DEBUG_CLI=\"-d\"" >> ${PLIST}; + else + echo "" + echo "Invalid enable option." + echo "" + echo "Enable options: database, client-syslog, agentless, debug" + echo "Usage: $0 enable [database|client-syslog|agentless|debug]" + exit 1; + fi +} + +# Disables additional daemons +disable() +{ + if [ "X$2" = "X" ]; then + echo "" + echo "Disable options: database, client-syslog, agentless, debug" + echo "Usage: $0 disable [database|client-syslog|agentless|debug]" + exit 1; + fi + + if [ "X$2" = "Xdatabase" ]; then + echo "DB_DAEMON=\"\"" >> ${PLIST}; + elif [ "X$2" = "Xclient-syslog" ]; then + echo "CSYSLOG_DAEMON=\"\"" >> ${PLIST}; + elif [ "X$2" = "Xagentless" ]; then + echo "AGENTLESS_DAEMON=\"\"" >> ${PLIST}; + elif [ "X$2" = "Xdebug" ]; then + echo "DEBUG_CLI=\"\"" >> ${PLIST}; + else + echo "" + echo "Invalid disable option." + echo "" + echo "Disable options: database, client-syslog, agentless, debug" + echo "Usage: $0 disable [database|client-syslog|agentless|debug]" + exit 1; + fi +} + +status() +{ + RETVAL=0 + for i in ${DAEMONS}; do + ## If openarmor-maild is disabled, don't try to start it. + if [ X"$i" = "Xopenarmor-maild" ]; then + grep "no<" ${DIR}/etc/openarmor.conf >/dev/null 2>&1 + if [ $? = 0 ]; then + continue + fi + fi + + pstatus ${i}; + if [ $? = 0 ]; then + echo "${i} not running..." + RETVAL=1 + else + echo "${i} is running..." + fi + done + exit $RETVAL +} + +testconfig() +{ + # We first loop to check the config. + for i in ${SDAEMONS}; do + ${DIR}/bin/${i} -t ${DEBUG_CLI}; + if [ $? != 0 ]; then + echo "${i}: Configuration error. Exiting" + unlock; + exit 1; + fi + done +} + +# Start function +start() +{ + SDAEMONS="${DB_DAEMON} ${CSYSLOG_DAEMON} ${AGENTLESS_DAEMON} openarmor-maild openarmor-execd openarmor-analysisd openarmor-logcollector openarmor-remoted openarmor-syscheckd openarmor-monitord" + + echo "Starting $NAME $VERSION..." + echo | ${DIR}/bin/openarmor-logtest > /dev/null 2>&1; + if [ ! $? = 0 ]; then + echo "openarmor analysisd: Testing rules failed. Configuration error. Exiting." + exit 1; + fi + lock; + checkpid; + + # We actually start them now. + for i in ${SDAEMONS}; do + + ## If openarmor-maild is disabled, don't try to start it. + if [ X"$i" = "Xopenarmor-maild" ]; then + grep "no<" ${DIR}/etc/openarmor.conf >/dev/null 2>&1 + if [ $? = 0 ]; then + continue + fi + fi + + pstatus ${i}; + if [ $? = 0 ]; then + ${DIR}/bin/${i} ${DEBUG_CLI}; + if [ $? != 0 ]; then + echo "${i} did not start correctly."; + unlock; + exit 1; + fi + + echo "Started ${i}..." + else + echo "${i} already running..." + fi + done + + # After we start we give 2 seconds for the daemons + # to internally create their PID files. + sleep 2; + unlock; + echo "Completed." +} + +pstatus() +{ + pfile=$1; + + # pfile must be set + if [ "X${pfile}" = "X" ]; then + return 0; + fi + + ls ${DIR}/var/run/${pfile}*.pid > /dev/null 2>&1 + if [ $? = 0 ]; then + for j in `cat ${DIR}/var/run/${pfile}*.pid 2>/dev/null`; do + ps -p $j |grep openarmor >/dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "${pfile}: Process $j not used by openarmor, removing .." + rm -f ${DIR}/var/run/${pfile}-$j.pid + continue; + fi + + kill -0 $j > /dev/null 2>&1 + if [ $? = 0 ]; then + return 1; + fi + done + fi + + return 0; +} + +stopa() +{ + lock; + checkpid; + for i in ${DAEMONS}; do + pstatus ${i}; + if [ $? = 1 ]; then + echo "Killing ${i} .. "; + + kill `cat ${DIR}/var/run/${i}*.pid`; + else + echo "${i} not running .."; + fi + rm -f ${DIR}/var/run/${i}*.pid + done + + unlock; + echo "$NAME $VERSION Stopped" +} + +### MAIN HERE ### + +case "$1" in +start) + testconfig + start + ;; +stop) + stopa + ;; +restart) + testconfig + stopa + sleep 1; + start + ;; +reload) + DAEMONS="openarmor-monitord openarmor-logcollector openarmor-remoted openarmor-syscheckd openarmor-analysisd openarmor-maild ${DB_DAEMON} ${CSYSLOG_DAEMON} ${AGENTLESS_DAEMON}" + stopa + start + ;; +status) + status + ;; +help) + help + ;; +enable) + enable $1 $2; + ;; +disable) + disable $1 $2; + ;; +*) + help +esac + diff --git a/src/init/osx105-addusers.sh b/src/init/osx105-addusers.sh new file mode 100644 index 000000000..412d2b300 --- /dev/null +++ b/src/init/osx105-addusers.sh @@ -0,0 +1,119 @@ +#! /bin/bash +# By Spransy, Derek" and Charlie Scott + +##### +# This checks for an error and exits with a custom message +# Returns zero on success +# $1 is the message +# $2 is the error code + +if [[ ! -f "/usr/bin/dscl" ]] + then + echo "Error, I have no dscl, dying here"; + exit +fi + +DSCL="/usr/bin/dscl"; + +function check_errm +{ + if [[ ${?} != "0" ]] + then + echo "${1}"; + exit ${2}; + fi +} + +# get unique id numbers (uid, gid) that are greater than 100 +unset -v i new_uid new_gid idvar; +declare -i new_uid=0 new_gid=0 i=100 idvar=0; +while [[ $idvar -eq 0 ]]; do + i=$[i+1] + j=$[i+1] + k=$[i+2] + if [[ -z "$(/usr/bin/dscl . -search /Users uid ${i})" ]] && [[ -z "$(/usr/bin/dscl . -search /Groups gid ${i})" ]] && \ + [[ -z "$(/usr/bin/dscl . -search /Users uid ${j})" ]] && [[ -z "$(/usr/bin/dscl . -search /Groups gid ${j})" ]] && \ + [[ -z "$(/usr/bin/dscl . -search /Users uid ${k})" ]] && [[ -z "$(/usr/bin/dscl . -search /Groups gid ${k})" ]]; + then + new_uid=$i + new_gid=$i + idvar=1 + #break + fi +done + +echo "UIDs available are:"; +echo ${new_uid} +echo ${j} +echo ${k} + +# Verify that the uid and gid exist and match +if [[ $new_uid -eq 0 ]] || [[ $new_gid -eq 0 ]]; + then + echo "Getting unique id numbers (uid, gid) failed!"; + exit 1; + fi +if [[ ${new_uid} != ${new_gid} ]] + then + echo "I failed to find matching free uid and gid!"; + exit 5; + fi + + +# Creating the groups. +sudo ${DSCL} localhost -create /Local/Default/Groups/openarmor +check_errm "Error creating group openarmor" "67" +sudo ${DSCL} localhost -createprop /Local/Default/Groups/openarmor PrimaryGroupID ${new_gid} +sudo ${DSCL} localhost -createprop /Local/Default/Groups/openarmor RealName openarmor +sudo ${DSCL} localhost -createprop /Local/Default/Groups/openarmor RecordName openarmor +sudo ${DSCL} localhost -createprop /Local/Default/Groups/openarmor RecordType: dsRecTypeStandard:Groups +sudo ${DSCL} localhost -createprop /Local/Default/Groups/openarmor Password "*" + + +# Creating the users. + +if [[ $(dscl . -read /Users/openarmorm) ]] + then + echo "openarmorm already exists"; +else + sudo ${DSCL} localhost -create /Local/Default/Users/openarmorm + check_errm "Error creating user openarmorm" "87" + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorm RecordName openarmorm + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorm RealName "openarmormacct" + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorm NFSHomeDirectory /var/openarmor + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorm UniqueID ${j} + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorm PrimaryGroupID ${new_gid} + sudo ${DSCL} localhost -append /Local/Default/Groups/openarmor GroupMembership openarmorm + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorm Password "*" +fi + +if [[ $(dscl . -read /Users/openarmorr) ]] + then + echo "openarmorr already exists"; +else + sudo ${DSCL} localhost -create /Local/Default/Users/openarmorr + check_errm "Error creating user openarmorr" "97" + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorr RecordName openarmorr + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorr RealName "openarmorracct" + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorr NFSHomeDirectory /var/openarmor + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorr UniqueID ${k} + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorr PrimaryGroupID ${new_gid} + sudo ${DSCL} localhost -append /Local/Default/Groups/openarmor GroupMembership openarmorr + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmorr Password "*" +fi + +if [[ $(dscl . -read /Users/openarmor) ]] + then + echo "openarmor already exists"; +else + sudo ${DSCL} localhost -create /Local/Default/Users/openarmor + check_errm "Error creating user openarmor" "77" + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmor RecordName openarmor + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmor RealName "openarmoracct" + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmor NFSHomeDirectory /var/openarmor + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmor UniqueID ${new_uid} + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmor PrimaryGroupID ${new_gid} + sudo ${DSCL} localhost -append /Local/Default/Groups/openarmor GroupMembership openarmor + sudo ${DSCL} localhost -createprop /Local/Default/Users/openarmor Password "*" +fi + diff --git a/src/init/shared.sh b/src/init/shared.sh new file mode 100644 index 000000000..0fae10b24 --- /dev/null +++ b/src/init/shared.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# Shared variables and functions +# Author: Daniel B. Cid + +### Setting up variables +VERSION_FILE="./src/VERSION" +VERSION=`cat ${VERSION_FILE}` +LOCATION="./src/LOCATION" +UNAME=`uname -snr` +NUNAME=`uname` + +# If whoami does not exist, try id +ls "`which whoami`" > /dev/null 2>&1 +if [ ! $? = 0 ]; then + ME=`id | cut -d " " -f 1` + if [ "X${ME}" = "Xuid=0(root)" ]; then + ME="root" + fi +else + ME=`whoami 2>/dev/null` +fi + +openarmor_INIT="/etc/openarmor-init.conf" +HOST=`hostname` +NAMESERVERS=`cat /etc/resolv.conf | grep "^nameserver" | cut -d " " -sf 2` +NAMESERVERS2=`cat /etc/resolv.conf | grep "^nameserver" | cut -sf 2` +HOST_CMD=`which host` +NAME="openarmor HIDS" +INSTYPE="server" +DEFAULT_DIR=`grep DIR ${LOCATION} | cut -f2 -d\"` +INSTALLDIR="$DEFAULT_DIR"; +WORKDIR="$INSTALLDIR" +CEXTRA="" + +# Internal definitions +NEWCONFIG="./etc/openarmor.mc" +PRECONFIG="./etc/PRECONFIG" + +## Templates +TEMPLATE="./etc/templates" +ERROR="errors" +MSG="messages" + +## Config templates +SYSCHECK_TEMPLATE="./etc/templates/config/syscheck.template" +SYSLOG_TEMPLATE="./etc/templates/config/syslog-logs.template" +APACHE_TEMPLATE="./etc/templates/config/apache-logs.template" +SNORT_TEMPLATE="./etc/templates/config/snort-logs.template" +PGSQL_TEMPLATE="./etc/templates/config/pgsql-logs.template" +HOST_DENY_TEMPLATE="./etc/templates/config/ar-host-deny.template" +FIREWALL_DROP_TEMPLATE="./etc/templates/config/ar-firewall-drop.template" +DISABLE_ACCOUNT_TEMPLATE="./etc/templates/config/ar-disable-account.template" +ACTIVE_RESPONSE_TEMPLATE="./etc/templates/config/active-response.template" +ROUTENULL_TEMPLATE="./etc/templates/config/ar-routenull.template" +RULES_TEMPLATE="./etc/templates/config/rules.template" + +## Host output +openarmorMX="devmail.theopenarmor.org mail is handled by 10 openarmor.mooo.com." +openarmorMX2="devmail.theopenarmor.org mail is handled (pri=10) by openarmor.mooo.com" +openarmorMX3="devmail.theopenarmor.org mail is handled by 10 openarmor.mooo.COM." + +## Predefined file +PREDEF_FILE="./etc/preloaded-vars.conf" + diff --git a/src/init/update.sh b/src/init/update.sh new file mode 100644 index 000000000..8eb3989b8 --- /dev/null +++ b/src/init/update.sh @@ -0,0 +1,129 @@ +#!/bin/sh +# Shell script update functions for the openarmor HIDS +# Author: Daniel B. Cid + +FALSE="false" +TRUE="true" + +isUpdate() +{ + ls -la ${openarmor_INIT} > /dev/null 2>&1 + if [ $? = 0 ]; then + . ${openarmor_INIT} + if [ "X$DIRECTORY" = "X" ]; then + echo "# ($FUNCNAME) ERROR: The variable DIRECTORY wasn't set" 1>&2 + echo "${FALSE}" + return 1; + fi + ls -la $DIRECTORY > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "${TRUE}" + return 0; + fi + fi + echo "${FALSE}" + return 1; +} + +doUpdatecleanup() +{ + . ${openarmor_INIT} + + if [ "X$DIRECTORY" = "X" ]; then + echo "# ($FUNCNAME) ERROR: The variable DIRECTORY wasn't set." 1>&2 + echo "${FALSE}" + return 1; + fi + + # Checking if the directory is valid. + _dir_pattern_update="^/[-a-zA-Z0-9/\.-]{3,128}$" + echo $DIRECTORY | grep -E "$_dir_pattern_update" > /dev/null 2>&1 + if [ ! $? = 0 ]; then + echo "# ($FUNCNAME) ERROR: directory name ($DIRECTORY) doesn't match the pattern $_dir_pattern_update" 1>&2 + echo "${FALSE}" + return 1; + fi +} + +getPreinstalled() +{ + . ${openarmor_INIT} + + # agent + cat $DIRECTORY/etc/openarmor.conf | grep "" > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "agent" + return 0; + fi + + cat $DIRECTORY/etc/openarmor.conf | grep "" > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "server" + return 0; + fi + + echo "local" + return 0; +} + +getPreinstalledDir() +{ + . ${openarmor_INIT} + echo "$DIRECTORY" + return 0; +} + +UpdateStartopenarmor() +{ + . ${openarmor_INIT} + + $DIRECTORY/bin/openarmor-control start +} + +UpdateStopopenarmor() +{ + . ${openarmor_INIT} + + $DIRECTORY/bin/openarmor-control stop + + # We also need to remove all syscheck queue file (format changed) + if [ "X$VERSION" = "X0.9-3" ]; then + rm -f $DIRECTORY/queue/syscheck/* > /dev/null 2>&1 + rm -f $DIRECTORY/queue/agent-info/* > /dev/null 2>&1 + fi + rm -f $DIRECTORY/queue/syscheck/.* > /dev/null 2>&1 +} + +UpdateopenarmorRules() +{ + . ${openarmor_INIT} + + openarmor_CONF_FILE="$DIRECTORY/etc/openarmor.conf" + + # Backing up the old config + cp -pr ${openarmor_CONF_FILE} "${openarmor_CONF_FILE}.$$.bak" + + # Getting rid of old rules entries + grep -Ev "|||||rules global entry" ${openarmor_CONF_FILE} > "${openarmor_CONF_FILE}.$$.tmp" + + # Customer decoder, decoder_dir, rule_dir are carried over during upgrade + grep -E '|' ${openarmor_CONF_FILE} | grep -v '" >> ${openarmor_CONF_FILE} + grep -v '' ${RULES_TEMPLATE} >> ${openarmor_CONF_FILE} + cat "${openarmor_CONF_FILE}.$$.tmp2" >> ${openarmor_CONF_FILE} + echo "" >> ${openarmor_CONF_FILE} + echo " " >> ${openarmor_CONF_FILE} + rm "${openarmor_CONF_FILE}.$$.tmp2" +} + diff --git a/src/install-shim-aix.ksh b/src/install-shim-aix.ksh new file mode 100644 index 000000000..aa0db5f07 --- /dev/null +++ b/src/install-shim-aix.ksh @@ -0,0 +1,53 @@ +#!/bin/ksh +# +# Wrapper for install on AIX, handling -b and -d options +# + +# AIX defaults +mode="755" +owner="bin" +group="bin" + +backup="" +directories=0 + +while getopts "m:M:o:O:g:G:bd" opt; do + case "$opt" in + m|M) mode=$OPTARG ;; + o|O) owner=$OPTARG ;; + g|G) group=$OPTARG ;; + b) backup="-o" ;; + d) directories=1 ;; + esac +done + +shift $((OPTIND-1)) +[ "${1:-}" = "--" ] && shift + +if [ "${directories}" -eq 1 ]; then + for directory in $@; do + mkdir -p "${directory}" + chown ${owner}:${group} "${directory}" + chmod ${mode} "${directory}" + done +else + sources="" + destination="" + while [ -n "$1" ]; do + destination="$1" + shift + [ -n "$1" ] && sources="${sources} $destination" + done + for source in $sources; do + if [ ! -d "${destination}" -o "${source}" == "/dev/null" ]; then + # need to manually copy the file if the target includes the filename or the source is null + cp "${source}" "${destination}" + chown ${owner}:${group} "${destination}" + chmod ${mode} "${destination}" + else + install -M ${mode} -O ${owner} -G ${group} -f "${destination}" "${backup}" "${source}" || exit $? + fi + done +fi + +exit 0 diff --git a/src/logcollector/COPYRIGHT b/src/logcollector/COPYRIGHT new file mode 100644 index 000000000..dcf488939 --- /dev/null +++ b/src/logcollector/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (C) 2009 Trend Micro Inc. + All right reserved. + This program is a free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License (version 2) as published by the FSF - Free Software + Foundation + +openarmor, logcollector. +Available at http://www.theopenarmor.org/hids/ diff --git a/src/logcollector/VERSION b/src/logcollector/VERSION new file mode 100644 index 000000000..bd73f4707 --- /dev/null +++ b/src/logcollector/VERSION @@ -0,0 +1 @@ +0.4 diff --git a/src/logcollector/config.c b/src/logcollector/config.c new file mode 100644 index 000000000..b85f7d295 --- /dev/null +++ b/src/logcollector/config.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read the config file (the localfiles) */ +int LogCollectorConfig(const char *cfgfile, int accept_remote) +{ + int modules = 0; + logreader_config log_config; + + modules |= CLOCALFILE; + + log_config.config = NULL; + log_config.agent_cfg = 0; + log_config.accept_remote = accept_remote; + + if (ReadConfig(modules, cfgfile, &log_config, NULL) < 0) { + return (OS_INVALID); + } + +#ifdef CLIENT + modules |= CAGENT_CONFIG; + log_config.agent_cfg = 1; + ReadConfig(modules, AGENTCONFIG, &log_config, NULL); + log_config.agent_cfg = 0; +#endif + + logff = log_config.config; + + return (1); +} + diff --git a/src/logcollector/logcollector.c b/src/logcollector/logcollector.c new file mode 100644 index 000000000..103614349 --- /dev/null +++ b/src/logcollector/logcollector.c @@ -0,0 +1,734 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + +/* Prototypes */ +int update_fname(int i); + +/* Global variables */ +int loop_timeout; +int logr_queue; +int open_file_attempts; +logreader *logff; +static int _cday = 0; + + +static char *rand_keepalive_str(char *dst, int size) +{ + static const char text[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "!@#$%^&*()_+-=;'[],./?"; + int i, len = rand() % (size - 10); + + strncpy(dst, "--MARK--: ", 12); + for ( i = 10; i < len; ++i ) { + dst[i] = text[(unsigned int)rand() % (sizeof text - 1)]; + } + dst[i] = '\0'; + return dst; +} + +/* Handle file management */ +void LogCollectorStart() +{ + int i = 0, r = 0; + int max_file = 0; + int f_check = 0; + time_t curr_time = 0; + char keepalive[1024]; + + +#ifndef WIN32 + int int_error = 0; + struct timeval fp_timeout; + /* To check for inode changes */ + struct stat tmp_stat; +#else + BY_HANDLE_FILE_INFORMATION lpFileInformation; + + /* Check if we are on Windows Vista */ + checkVista(); + + /* Read vista descriptions */ + if (isVista) { + win_read_vista_sec(); + } +#endif + + debug1("%s: DEBUG: Entering LogCollectorStart().", ARGV0); + + /* Initialize each file and structure */ + for (i = 0;; i++) { + if (logff[i].file == NULL) { + break; + } + + /* Remove duplicate entries */ + for (r = 0; r < i; r++) { + if (logff[r].file && strcmp(logff[i].file, logff[r].file) == 0) { + merror("%s: WARN: Duplicated log file given: '%s'.", + ARGV0, logff[i].file); + logff[i].file = NULL; + logff[i].command = NULL; + logff[i].fp = NULL; + logff[i].ptr = NULL; + + break; + } + } + + if (logff[i].file == NULL) { + /* Do nothing, duplicated entry */ + } + + else if (strcmp(logff[i].logformat, "eventlog") == 0) { +#ifdef WIN32 + + verbose(READING_EVTLOG, ARGV0, logff[i].file); + win_startel(logff[i].file); + +#endif + logff[i].file = NULL; + logff[i].command = NULL; + logff[i].fp = NULL; + logff[i].ptr = NULL; + } + + else if (strcmp(logff[i].logformat, "eventchannel") == 0) { +#ifdef WIN32 + +#ifdef EVENTCHANNEL_SUPPORT + verbose(READING_EVTLOG, ARGV0, logff[i].file); + win_start_event_channel(logff[i].file, logff[i].future, logff[i].query); +#else + merror("%s: WARN: eventchannel not available on this version of openarmor", ARGV0); +#endif + +#endif + + logff[i].file = NULL; + logff[i].command = NULL; + logff[i].fp = NULL; + logff[i].ptr = NULL; + } + + else if (strcmp(logff[i].logformat, "command") == 0) { + logff[i].file = NULL; + logff[i].fp = NULL; + logff[i].ptr = NULL; + logff[i].size = 0; + + if (logff[i].command) { + logff[i].read = read_command; + + verbose("%s: INFO: Monitoring output of command(%d): %s", ARGV0, logff[i].ign, logff[i].command); + + if (!logff[i].alias) { + os_strdup(logff[i].command, logff[i].alias); + } + } else { + merror("%s: ERROR: Missing command argument. Ignoring it.", + ARGV0); + } + } else if (strcmp(logff[i].logformat, "full_command") == 0) { + logff[i].file = NULL; + logff[i].fp = NULL; + logff[i].ptr = NULL; + logff[i].size = 0; + if (logff[i].command) { + logff[i].read = read_fullcommand; + + verbose("%s: INFO: Monitoring full output of command(%d): %s", ARGV0, logff[i].ign, logff[i].command); + + if (!logff[i].alias) { + os_strdup(logff[i].command, logff[i].alias); + } + } else { + merror("%s: ERROR: Missing command argument. Ignoring it.", + ARGV0); + } + } + else if (strcmp(logff[i].logformat, "journald") == 0) { +#ifdef HAVE_SYSTEMD + verbose(READING_JOURNAL, ARGV0, logff[i].file); + logff[i].read = sd_read_journal; +#else + merror("%s: WARN: journald not available on this version of openarmor", ARGV0); +#endif + logff[i].command = NULL; + logff[i].fp = NULL; + logff[i].ptr = NULL; + } + + else { + logff[i].command = NULL; + + /* Initialize the files */ + if (logff[i].ffile) { + /* Day must be zero for all files to be initialized */ + _cday = 0; + if (update_fname(i)) { + handle_file(i, 1, 1); + } else { + ErrorExit(PARSE_ERROR, ARGV0, logff[i].ffile); + } + + } else { + handle_file(i, 1, 1); + } + + verbose(READING_FILE, ARGV0, logff[i].file); + + /* Get the log type */ + if (strcmp("snort-full", logff[i].logformat) == 0) { + logff[i].read = read_snortfull; + } +#ifndef WIN32 + if (strcmp("openarmoralert", logff[i].logformat) == 0) { + logff[i].read = read_openarmoralert; + } +#endif + else if (strcmp("nmapg", logff[i].logformat) == 0) { + logff[i].read = read_nmapg; + } else if (strcmp("mysql_log", logff[i].logformat) == 0) { + logff[i].read = read_mysql_log; + } else if (strcmp("mssql_log", logff[i].logformat) == 0) { + logff[i].read = read_mssql_log; + } else if (strcmp("postgresql_log", logff[i].logformat) == 0) { + logff[i].read = read_postgresql_log; + } else if (strcmp("djb-multilog", logff[i].logformat) == 0) { + if (!init_djbmultilog(i)) { + merror(INV_MULTILOG, ARGV0, logff[i].file); + if (logff[i].fp) { + fclose(logff[i].fp); + logff[i].fp = NULL; + logff[i].ptr = NULL; + } + logff[i].file = NULL; + } + logff[i].read = read_djbmultilog; + } else if (logff[i].logformat[0] >= '0' && logff[i].logformat[0] <= '9') { + logff[i].read = read_multiline; + } else if (strcmp("audit", logff[i].logformat) == 0) { + logff[i].read = read_audit; + } else if (strcmp("multi-line_indented", logff[i].logformat) == 0) { + logff[i].read = read_multiline_indented; + } else { + logff[i].read = read_syslog; + } + + /* More tweaks for Windows. For some reason IIS places + * some weird characters at the end of the files and getc + * always returns 0 (even after clearerr). + */ +#ifdef WIN32 + if (logff[i].fp) { + logff[i].read(i, &r, 1); + } +#endif + } + + if (logff[i].alias) { + int ii = 0; + while (logff[i].alias[ii] != '\0') { + if (logff[i].alias[ii] == ':') { + logff[i].alias[ii] = '\\'; + } + ii++; + } + } + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + max_file = i - 1; + + /* Cannot be zero */ + if (max_file < 0) { + max_file = 0; + } + + /* Daemon loop */ + while (1) { +#ifndef WIN32 + fp_timeout.tv_sec = loop_timeout; + fp_timeout.tv_usec = 0; + + /* Wait for the select timeout */ + if ((r = select(0, NULL, NULL, NULL, &fp_timeout)) < 0) { + merror(SELECT_ERROR, ARGV0, errno, strerror(errno)); + int_error++; + + if (int_error >= 5) { + ErrorExit(SYSTEM_ERROR, ARGV0); + } + continue; + } +#else + + /* Windows doesn't like select that way */ + sleep(loop_timeout + 2); + + /* Check for messages in the event viewer */ + win_readel(); +#endif + + f_check++; + + /* Check which file is available */ + for (i = 0; i <= max_file; i++) { + if (!logff[i].fp) { + /* Run the command */ + if ((logff[i].command || !strncmp(logff[i].logformat, "journald", 7)) && (f_check % 2)) { + curr_time = time(0); + if ((curr_time - logff[i].size) >= logff[i].ign) { + logff[i].size = curr_time; + logff[i].read(i, &r, 0); + } + } + continue; + } + + /* Windows with IIS logs is very strange. + * For some reason it always returns 0 (not EOF) + * the fgetc. To solve this problem, we always + * pass it to the function pointer directly. + */ +#ifndef WIN32 + /* We check for the end of file. If is returns EOF, + * we don't attempt to read it. + */ + if ((r = fgetc(logff[i].fp)) == EOF) { + clearerr(logff[i].fp); + continue; + } + + /* If it is not EOF, we need to return the read character */ + ungetc(r, logff[i].fp); +#endif + + /* Finally, send to the function pointer to read it */ + logff[i].read(i, &r, 0); + + /* Check for error */ + if (!ferror(logff[i].fp)) { + /* Clear EOF */ + clearerr(logff[i].fp); + + /* Parsing error */ + if (r != 0) { + logff[i].ign++; + } + } + /* If ferror is set */ + else { + merror(FREAD_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); +#ifndef WIN32 + if (fseek(logff[i].fp, 0, SEEK_END) < 0) +#else + if (1) +#endif + { + +#ifndef WIN32 + merror(FSEEK_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); +#endif + + /* Close the file */ + if (logff[i].fp) { + fclose(logff[i].fp); +#ifdef WIN32 + CloseHandle(logff[i].h); +#endif + } + logff[i].fp = NULL; + + + /* Try to open it again */ + if (handle_file(i, 1, 1) != 0) { + logff[i].ign++; + continue; + } +#ifdef WIN32 + logff[i].read(i, &r, 1); +#endif + } + /* Increase the error count */ + logff[i].ign++; + clearerr(logff[i].fp); + } + } + + /* Only check below if check > VCHECK_FILES */ + if (f_check <= VCHECK_FILES) { + continue; + } + + /* Send keep alive message */ + rand_keepalive_str(keepalive, 700); + SendMSG(logr_queue, keepalive, "openarmor-keepalive", LOCALFILE_MQ); + + /* Zero f_check */ + f_check = 0; + + /* Check if any file has been renamed/removed */ + for (i = 0; i <= max_file; i++) { + /* These are the windows logs or ignored files */ + if (!logff[i].file) { + continue; + } + + /* Files with date -- check for day change */ + if (logff[i].ffile) { + if (update_fname(i)) { + if (logff[i].fp) { + fclose(logff[i].fp); +#ifdef WIN32 + CloseHandle(logff[i].h); +#endif + } + logff[i].fp = NULL; + handle_file(i, 0, 1); + continue; + } + + /* Variable file name */ + else if (!logff[i].fp) { + handle_file(i, 0, 0); + continue; + } + } + + /* Check for file change -- if the file is open already */ + if (logff[i].fp) { +#ifndef WIN32 + + /* To help detect a file rollover, temporarily open the file a second time. + * Previously the fstat would work on "cached" file data, but this should + * ensure it's fresh when hardlinks are used (like alerts.log). + */ + FILE *tf; + tf = fopen(logff[i].file, "r"); + if(tf == NULL) { + merror(FOPEN_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + } + + else if ((fstat(fileno(tf), &tmp_stat)) == -1) { + fclose(logff[i].fp); + fclose(tf); + logff[i].fp = NULL; + + merror(FSTAT_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + } + else if(fclose(tf) == EOF) { + merror("Closing the temporary file %s did not work (%d): %s", logff[i].file, errno, strerror(errno)); + } +#else + HANDLE h1; + + h1 = CreateFile(logff[i].file, GENERIC_READ, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h1 == INVALID_HANDLE_VALUE) { + fclose(logff[i].fp); + CloseHandle(logff[i].h); + logff[i].fp = NULL; + merror(FILE_ERROR, ARGV0, logff[i].file); + } else if (GetFileInformationByHandle(h1, &lpFileInformation) == 0) { + fclose(logff[i].fp); + CloseHandle(logff[i].h); + CloseHandle(h1); + logff[i].fp = NULL; + merror(FILE_ERROR, ARGV0, logff[i].file);; + } +#endif + +#ifdef WIN32 + else if (logff[i].fd != (lpFileInformation.nFileIndexLow + lpFileInformation.nFileIndexHigh)) +#else + else if (logff[i].fd != tmp_stat.st_ino) +#endif + { + char msg_alert[512 + 1]; + + snprintf(msg_alert, 512, "openarmor: File rotated (inode " + "changed): '%s'.", + logff[i].file); + + /* Send message about log rotated */ + SendMSG(logr_queue, msg_alert, + "openarmor-logcollector", LOCALFILE_MQ); + + debug1("%s: DEBUG: File inode changed. %s", + ARGV0, logff[i].file); + + fclose(logff[i].fp); + +#ifdef WIN32 + CloseHandle(logff[i].h); + CloseHandle(h1); +#endif + + logff[i].fp = NULL; + handle_file(i, 0, 1); + continue; + } +#ifdef WIN32 + else if (logff[i].size > (lpFileInformation.nFileSizeHigh + lpFileInformation.nFileSizeLow)) +#else + else if (logff[i].size > tmp_stat.st_size) +#endif + { + char msg_alert[512 + 1]; + + snprintf(msg_alert, 512, "openarmor: File size reduced " + "(inode remained): '%s'.", + logff[i].file); + + /* Send message about log rotated */ + SendMSG(logr_queue, msg_alert, + "openarmor-logcollector", LOCALFILE_MQ); + + debug1("%s: DEBUG: File size reduced. %s", + ARGV0, logff[i].file); + + /* Get new file */ + fclose(logff[i].fp); + +#ifdef WIN32 + CloseHandle(logff[i].h); + CloseHandle(h1); +#endif + + logff[i].fp = NULL; + handle_file(i, 1, 1); + } +#ifdef WIN32 + else { + CloseHandle(h1); + } +#endif + } + + + /* Too many errors for the file */ + if (logff[i].ign > open_file_attempts) { + /* 999 Maximum ignore */ + if (logff[i].ign == 999) { + continue; + } + + merror(LOGC_FILE_ERROR, ARGV0, logff[i].file); + if (logff[i].fp) { + fclose(logff[i].fp); +#ifdef WIN32 + CloseHandle(logff[i].h); +#endif + } + + logff[i].fp = NULL; + + /* If the file has a variable date, ignore it for today only */ + if (!logff[i].ffile) { + /* Variable log files should always be attempted + * to be open... + */ + //logff[i].file = NULL; + } + logff[i].ign = 999; + continue; + } + + /* File not open */ + if (!logff[i].fp) { + if (logff[i].ign >= 999) { + continue; + } else { + /* Try for a few times to open the file */ + if (handle_file(i, 1, 1) < 0) { + logff[i].ign++; + } + continue; + } + } + + /* Update file size */ +#ifdef WIN32 + logff[i].size = lpFileInformation.nFileSizeHigh + lpFileInformation.nFileSizeLow; +#else + logff[i].size = tmp_stat.st_size; +#endif + } + } +} + +int update_fname(int i) +{ + struct tm *p; + time_t __ctime = time(0); + char lfile[OS_FLSIZE + 1]; + size_t ret; + + p = localtime(&__ctime); + + /* Handle file */ + if (p->tm_mday == _cday) { + return (0); + } + + lfile[OS_FLSIZE] = '\0'; + ret = strftime(lfile, OS_FLSIZE, logff[i].ffile, p); + if (ret == 0) { + ErrorExit(PARSE_ERROR, ARGV0, logff[i].ffile); + } + + /* Update the filename */ + if (strcmp(lfile, logff[i].file) != 0) { + os_free(logff[i].file); + + os_strdup(lfile, logff[i].file); + + verbose(VAR_LOG_MON, ARGV0, logff[i].file); + + /* Setting cday to zero because other files may need + * to be changed. + */ + _cday = 0; + return (1); + } + + _cday = p->tm_mday; + return (0); +} + +/* Open, get the fileno, seek to the end and update mtime */ +int handle_file(int i, int do_fseek, int do_log) +{ + int fd; + struct stat stat_fd; + + /* We must be able to open the file, fseek and get the + * time of change from it. + */ +#ifndef WIN32 + logff[i].fp = fopen(logff[i].file, "r"); + if (!logff[i].fp) { + if (do_log == 1) { + merror(FOPEN_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + } + return (-1); + } + /* Get inode number for fp */ + fd = fileno(logff[i].fp); + if (fstat(fd, &stat_fd) == -1) { + merror(FSTAT_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + fclose(logff[i].fp); + logff[i].fp = NULL; + return (-1); + } + + logff[i].fd = stat_fd.st_ino; + logff[i].size = stat_fd.st_size; + + +#else + BY_HANDLE_FILE_INFORMATION lpFileInformation; + + logff[i].fp = NULL; + logff[i].h = CreateFile(logff[i].file, GENERIC_READ, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (logff[i].h == INVALID_HANDLE_VALUE) { + if (do_log == 1) { + merror(FOPEN_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + } + return (-1); + } + fd = _open_osfhandle((long)logff[i].h, 0); + if (fd == -1) { + merror(FOPEN_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + CloseHandle(logff[i].h); + return (-1); + } + logff[i].fp = _fdopen(fd, "r"); + if (logff[i].fp == NULL) { + merror(FOPEN_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + CloseHandle(logff[i].h); + return (-1); + } + + + /* On windows, we also need the real inode, which is the combination + * of the index low + index high numbers. + */ + if (GetFileInformationByHandle(logff[i].h, &lpFileInformation) == 0) { + merror("%s: Unable to get file information by handle.", ARGV0); + fclose(logff[i].fp); + CloseHandle(logff[i].h); + logff[i].fp = NULL; + return (-1); + } + + logff[i].fd = (lpFileInformation.nFileIndexLow + lpFileInformation.nFileIndexHigh); + logff[i].size = (lpFileInformation.nFileSizeHigh + lpFileInformation.nFileSizeLow); + +#endif + + /* Only seek the end of the file if set to */ + if (do_fseek == 1 && S_ISREG(stat_fd.st_mode)) { + /* Windows and fseek causes some weird issues */ +#ifndef WIN32 + if (fseek(logff[i].fp, 0, SEEK_END) < 0) { + merror(FSEEK_ERROR, ARGV0, logff[i].file, errno, strerror(errno)); + fclose(logff[i].fp); + logff[i].fp = NULL; + return (-1); + } +#endif + } + + /* Set ignore to zero */ + logff[i].ign = 0; + return (0); +} + +#ifdef WIN32 + +/* Remove newlines and replace tabs in the argument fields with spaces */ +void win_format_event_string(char *string) +{ + if (string == NULL) { + return; + } + + while (*string != '\0') { + if (*string == '\n' || *string == '\r' || *string == ':') { + if (*string == '\n' || *string == '\r') { + *string = ' '; + } + + string++; + + while (*string == '\t') { + *string = ' '; + string++; + } + + continue; + } + + string++; + } +} + +#endif /* WIN32 */ diff --git a/src/logcollector/logcollector.h b/src/logcollector/logcollector.h new file mode 100644 index 000000000..5cd64b7f0 --- /dev/null +++ b/src/logcollector/logcollector.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __LOGREADER_H +#define __LOGREADER_H + +#ifndef ARGV0 +#define ARGV0 "openarmor-logcollector" +#endif + +#include "shared.h" +#include "config/localfile-config.h" +#include "config/config.h" + +/*** Function prototypes ***/ + +/* Read logcollector config */ +int LogCollectorConfig(const char *cfgfile, int accept_remote); + +/* Start log collector daemon */ +void LogCollectorStart(void) __attribute__((noreturn)); + +/* Handle files */ +int handle_file(int i, int do_fseek, int do_log); + +/* Read syslog file */ +void *read_syslog(int pos, int *rc, int drop_it); + +/* Read snort full file */ +void *read_snortfull(int pos, int *rc, int drop_it); + +/* Read openarmor alert file */ +void *read_openarmoralert(int pos, int *rc, int drop_it); + +/* Read nmap grepable format */ +void *read_nmapg(int pos, int *rc, int drop_it); + +/* Read mysql log format */ +void *read_mysql_log(int pos, int *rc, int drop_it); + +/* Read mysql log format */ +void *read_mssql_log(int pos, int *rc, int drop_it); + +/* Read postgresql log format */ +void *read_postgresql_log(int pos, int *rc, int drop_it); + +/* read multi line logs */ +void *read_multiline(int pos, int *rc, int drop_it); + +/* read indented multi line logs */ +void *read_multiline_indented(int pos, int *rc, int drop_it); + +/* Read DJB multilog format */ +/* Initializes multilog */ +int init_djbmultilog(int pos); +void *read_djbmultilog(int pos, int *rc, int drop_it); + +/* Read events from output of command */ +void *read_command(int pos, int *rc, int drop_it); +void *read_fullcommand(int pos, int *rc, int drop_it); + +/* Read auditd events */ +void *read_audit(int pos, int *rc, int drop_it); + +#ifdef WIN32 +void win_startel(); +void win_readel(); +void win_read_vista_sec(); +void win_start_event_channel(char *evt_log, char future, char *query); +void win_format_event_string(char *string); +#endif + +#ifdef HAVE_SYSTEMD +/* Read systemd entries */ +void *sd_read_journal(int pos, int *rc, int drop_it); +#endif + +/*** Global variables ***/ +extern int loop_timeout; +extern int logr_queue; +extern int open_file_attempts; +extern logreader *logff; + +#endif /* __LOGREADER_H */ diff --git a/src/logcollector/main.c b/src/logcollector/main.c new file mode 100644 index 000000000..d28a9fef5 --- /dev/null +++ b/src/logcollector/main.c @@ -0,0 +1,165 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Logcollector daemon + * Monitor some files and forward the output to our analysis system + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "os_regex/os_regex.h" +#include "logcollector.h" + +/* Prototypes */ +static void help_logcollector(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_logcollector() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-c config]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c; + int debug_level = 0; + int test_config = 0, run_foreground = 0; + int accept_manager_commands = 0; + const char *cfg = DEFAULTCPATH; + + /* Setup random */ + srandom_init(); + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vtdhfc:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_logcollector(); + break; + case 'd': + nowDebug(); + debug_level = 1; + break; + case 'f': + run_foreground = 1; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_logcollector(); + break; + } + + } + + /* Check current debug_level + * Command line setting takes precedence + */ + if (debug_level == 0) { + /* Get debug level */ + debug_level = getDefine_Int("logcollector", "debug", 0, 2); + while (debug_level != 0) { + nowDebug(); + debug_level--; + } + } + + debug1(STARTED_MSG, ARGV0); + + accept_manager_commands = getDefine_Int("logcollector", "remote_commands", + 0, 1); + + /* Read config file */ + if (LogCollectorConfig(cfg, accept_manager_commands) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Get loop timeout */ + loop_timeout = getDefine_Int("logcollector", + "loop_timeout", + 1, 120); + + open_file_attempts = getDefine_Int("logcollector", "open_attempts", + 2, 998); + + /* Exit if test config */ + if (test_config) { + exit(0); + } + + /* No file available to monitor -- continue */ + if (logff == NULL) { + os_calloc(2, sizeof(logreader), logff); + logff[0].file = NULL; + logff[0].ffile = NULL; + logff[0].logformat = NULL; + logff[0].fp = NULL; + logff[1].file = NULL; + logff[1].logformat = NULL; + + merror(NO_FILE, ARGV0); + } + + /* Start signal handler */ + StartSIG(ARGV0); + + if (!run_foreground) { + /* Going on daemon mode */ + nowDaemon(); + goDaemon(); + } + + /* Create PID file */ + if (CreatePID(ARGV0, getpid()) < 0) { + merror(PID_ERROR, ARGV0); + } + + /* Wait 6 seconds for the analysisd/agentd to settle */ + debug1("%s: DEBUG: Waiting main daemons to settle.", ARGV0); + sleep(6); + + /* Start the queue */ + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* Main loop */ + LogCollectorStart(); +} + diff --git a/src/logcollector/read_audit.c b/src/logcollector/read_audit.c new file mode 100644 index 000000000..8673d7081 --- /dev/null +++ b/src/logcollector/read_audit.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + +#define MAX_CACHE 16 +#define MAX_HEADER 64 + +/* Compile message from cache and send through queue */ +static void audit_send_msg(char **cache, int top, const char *file, int drop_it) { + int i; + size_t n = 0; + size_t z; + char message[OS_MAXSTR]; + + for (i = 0; i < top; i++) { + z = strlen(cache[i]); + + if (n + z + 1 < OS_MAXSTR) { + if (n > 0) + message[n++] = ' '; + + strncpy(message + n, cache[i], z); + } + + n += z; + free(cache[i]); + } + + if (!drop_it) { + message[n] = '\0'; + + if (SendMSG(logr_queue, message, file, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } +} + +void *read_audit(int pos, int *rc, int drop_it) { + char *cache[MAX_CACHE]; + char header[MAX_HEADER] = { '\0' }; + int icache = 0; + char buffer[OS_MAXSTR]; + char *id; + char *p; + size_t z; + long offset = ftell(logff[pos].fp); + + if (offset < 0) { + merror(FTELL_ERROR, ARGV0, logff[pos].file, errno, strerror(errno)); + return NULL; + } + + *rc = 0; + + while (fgets(buffer, OS_MAXSTR, logff[pos].fp)) { + if ((p = strchr(buffer, '\n'))) + *p = '\0'; + else { + if (strlen(buffer) == OS_MAXSTR - 1) { + // Message too large, discard line + while (fgets(buffer, OS_MAXSTR, logff[pos].fp) && !strchr(buffer, '\n')); + } else { + debug1("%s: Message not complete. Trying again: '%s'", ARGV0, buffer); + + if (fseek(logff[pos].fp, offset, SEEK_SET) < 0) { + merror(FSEEK_ERROR, ARGV0, logff[pos].file, errno, strerror(errno)); + break; + } + } + + break; + } + + // Extract header: "type=\.* msg=audit(\d+.\d+:\d+):" + + if (strncmp(buffer, "type=", 5) || !((id = strstr(buffer + 5, "msg=audit(")) && (p = strstr(id += 10, "): ")))) { + merror("%s: ERROR: discarding audit message because of invalid syntax", ARGV0); + break; + } + + z = p - id; + + if (strncmp(id, header, z)) { + // Current message belongs to another event: send cached messages + if (icache > 0) + audit_send_msg(cache, icache, logff[pos].file, drop_it); + + // Store current event + *cache = strdup(buffer); + icache = 1; + strncpy(header, id, z < MAX_HEADER ? z : MAX_HEADER - 1); + } else { + // The header is the same: store + if (icache == MAX_CACHE) + merror("%s: ERROR: discarding audit message because cache is full", ARGV0); + else + cache[icache++] = strdup(buffer); + } + } + + if (icache > 0) + audit_send_msg(cache, icache, logff[pos].file, drop_it); + + return NULL; +} diff --git a/src/logcollector/read_command.c b/src/logcollector/read_command.c new file mode 100644 index 000000000..9cecb56cd --- /dev/null +++ b/src/logcollector/read_command.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read Output of commands */ +void *read_command(int pos, int *rc, int drop_it) +{ + size_t cmd_size = 0; + char *p; + char str[OS_MAXSTR + 1]; + FILE *cmd_output; + + str[OS_MAXSTR] = '\0'; + *rc = 0; + + debug2("%s: DEBUG: Running command '%s'", ARGV0, logff[pos].command); + + cmd_output = popen(logff[pos].command, "r"); + if (!cmd_output) { + merror("%s: ERROR: Unable to execute command: '%s'.", + ARGV0, logff[pos].command); + + logff[pos].command = NULL; + return (NULL); + } + + snprintf(str, 256, "openarmor: output: '%s': ", + (NULL != logff[pos].alias) + ? logff[pos].alias + : logff[pos].command); + cmd_size = strlen(str); + + while (fgets(str + cmd_size, OS_MAXSTR - OS_LOG_HEADER - 256, cmd_output) != NULL) { + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + } + + /* Remove empty lines */ +#ifdef WIN32 + if (str[0] == '\r' && str[1] == '\0') { + continue; + } +#endif + if (str[0] == '\0') { + continue; + } + + debug2("%s: DEBUG: Reading command message: '%s'", ARGV0, str); + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, str, + (NULL != logff[pos].alias) ? logff[pos].alias : logff[pos].command, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + continue; + } + + pclose(cmd_output); + + return (NULL); +} + diff --git a/src/logcollector/read_djb_multilog.c b/src/logcollector/read_djb_multilog.c new file mode 100644 index 000000000..43c57ba5b --- /dev/null +++ b/src/logcollector/read_djb_multilog.c @@ -0,0 +1,181 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Read DJB multilog */ + +#include "shared.h" +#include "logcollector.h" + + +/* To translate between month (int) to month (char) */ +static const char *(djb_month[]) = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; +static char djb_host[512 + 1]; + + +/* Initialize multilog */ +int init_djbmultilog(int pos) +{ + char *djbp_name = NULL; + char *tmp_str = NULL; + + logff[pos].djb_program_name = NULL; + + /* Initialize hostname */ + memset(djb_host, '\0', 512 + 1); + +#ifndef WIN32 + if (gethostname(djb_host, 512 - 1) != 0) { + strncpy(djb_host, "unknown", 512 - 1); + } else { + char *_ltmp; + + /* Remove domain part if available */ + _ltmp = strchr(djb_host, '.'); + if (_ltmp) { + *_ltmp = '\0'; + } + } +#else + strncpy(djb_host, "win32", 512 - 1); +#endif + + /* Multilog must be in the following format: /path/program_name/current */ + tmp_str = strrchr(logff[pos].file, '/'); + if (!tmp_str) { + return (0); + } + + /* Must end with /current and must not be in the beginning of the string */ + if ((strcmp(tmp_str, "/current") != 0) || (tmp_str == logff[pos].file)) { + return (0); + } + + tmp_str[0] = '\0'; + + /* Get final name */ + djbp_name = strrchr(logff[pos].file, '/'); + if (djbp_name == logff[pos].file) { + tmp_str[0] = '/'; + return (0); + } + + os_strdup(djbp_name + 1, logff[pos].djb_program_name); + tmp_str[0] = '/'; + + verbose("%s: INFO: Using program name '%s' for DJB multilog file: '%s'.", + ARGV0, logff[pos].djb_program_name, logff[pos].file); + + return (1); +} + +void *read_djbmultilog(int pos, int *rc, int drop_it) +{ + size_t str_len = 0; + int need_clear = 0; + char *p; + char str[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + + str[OS_MAXSTR] = '\0'; + *rc = 0; + + /* Must have a valid program name */ + if (!logff[pos].djb_program_name) { + return (NULL); + } + + /* Get new entry */ + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + /* Get buffer size */ + str_len = strlen(str); + + /* Getting the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + + /* If need_clear is set, we just get the line and ignore it */ + if (need_clear) { + need_clear = 0; + continue; + } + } else { + need_clear = 1; + } + + /* Multilog messages have the following format: + * @40000000463246020c2ca16c xx... + */ + if ((str_len > 26) && + (str[0] == '@') && + isalnum((int)str[1]) && + isalnum((int)str[2]) && + isalnum((int)str[3]) && + isalnum((int)str[24]) && + (str[25] == ' ')) { + /* Remove spaces and tabs */ + p = str + 26; + while (*p == ' ' || *p == '\t') { + p++; + } + + /* If message has a valid syslog header, send as is */ + if ((str_len > 44) && + (p[3] == ' ') && + (p[6] == ' ') && + (p[9] == ':') && + (p[12] == ':') && + (p[15] == ' ')) { + p += 16; + strncpy(buffer, p, OS_MAXSTR); + } else { + /* We will add a proper syslog header */ + time_t djbtime; + struct tm *pt; + + djbtime = time(NULL); + pt = localtime(&djbtime); + + /* Syslog time: Apr 27 14:50:32 */ + snprintf(buffer, OS_MAXSTR, "%s %02d %02d:%02d:%02d %s %s: %s", + djb_month[pt->tm_mon], + pt->tm_mday, + pt->tm_hour, + pt->tm_min, + pt->tm_sec, + djb_host, + logff[pos].djb_program_name, + p); + } + } + + else { + debug2("%s: DEBUG: Invalid DJB log: '%s'", ARGV0, str); + continue; + } + + debug2("%s: DEBUG: Reading DJB multilog message: '%s'", ARGV0, buffer); + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, buffer, logff[pos].file, MYSQL_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + continue; + } + + return (NULL); +} + diff --git a/src/logcollector/read_fullcommand.c b/src/logcollector/read_fullcommand.c new file mode 100644 index 000000000..e114fb218 --- /dev/null +++ b/src/logcollector/read_fullcommand.c @@ -0,0 +1,91 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read Output of commands */ +void *read_fullcommand(int pos, int *rc, int drop_it) +{ + size_t n = 0; + size_t cmd_size = 0; + char *p; + char str[OS_MAXSTR + 1]; + char strfinal[OS_MAXSTR + 1]; + FILE *cmd_output; + + str[OS_MAXSTR] = '\0'; + strfinal[OS_MAXSTR] = '\0'; + *rc = 0; + + debug2("%s: DEBUG: Running full command '%s'", ARGV0, logff[pos].command); + + cmd_output = popen(logff[pos].command, "r"); + if (!cmd_output) { + merror("%s: ERROR: Unable to execute command: '%s'.", + ARGV0, logff[pos].command); + + logff[pos].command = NULL; + return (NULL); + } + + snprintf(str, 256, "openarmor: output: '%s':\n", + (NULL != logff[pos].alias) + ? logff[pos].alias + : logff[pos].command); + cmd_size = strlen(str); + + n = fread(str + cmd_size, 1, OS_MAXSTR - OS_LOG_HEADER - 256, cmd_output); + if (n > 0) { + str[cmd_size + n] = '\0'; + + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + } + + debug2("%s: DEBUG: Reading command message: '%s'", ARGV0, str); + + /* Remove empty lines */ + n = 0; + p = str; + while (*p != '\0') { + if (p[0] == '\r') { + p++; + continue; + } + + if (p[0] == '\n' && p[1] == '\n') { + p++; + } + strfinal[n] = *p; + n++; + p++; + } + strfinal[n] = '\0'; + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, strfinal, + (NULL != logff[pos].alias) ? logff[pos].alias : logff[pos].command, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + } + + pclose(cmd_output); + + return (NULL); +} + diff --git a/src/logcollector/read_journald.c b/src/logcollector/read_journald.c new file mode 100644 index 000000000..16315f3e0 --- /dev/null +++ b/src/logcollector/read_journald.c @@ -0,0 +1,132 @@ +#ifdef HAVE_SYSTEMD +#include "shared.h" +#include "logcollector.h" +#include + +void *prime_sd_journal(int pos) { + int ret; + sd_journal *jrn; + ret = sd_journal_open(&jrn, SD_JOURNAL_LOCAL_ONLY); + if (ret < 0) { + merror("%s: ERROR: Unable to open journal", ARGV0); + return NULL; + } + // For future use + logff[pos].fd = sd_journal_get_fd(jrn); + if (ret < 0) { + merror("%s: ERROR: Unable to get journal fd", ARGV0); + return NULL; + } + ret = sd_journal_seek_tail(jrn); + if (ret < 0) { + merror("%s: ERROR: Unable to seek journal tail", ARGV0); + return NULL; + } + // prime sd_journal_next before the reader loop + ret = sd_journal_previous(jrn); + if (ret < 0) { + merror("%s: ERROR: Unable to seek journal previous", ARGV0); + } + return (void *)jrn; +} + +void *sd_read_journal(int pos, int *rc, int drop_it) { + sd_journal *jrn = (sd_journal *) logff[pos].ptr; + char *unit = logff[pos].file; + int ret; + const char *jmsg = NULL, *jsrc = NULL, *jhst = NULL; + size_t len; + struct timeval tv; + uint64_t curr_timestamp; + time_t nowtime; + struct tm *nowtm; + char tmbuf[64], final_msg[OS_MAXSTR], sunitid[128]; + *rc = 0; + + if (jrn == NULL) { + jrn = logff[pos].ptr = prime_sd_journal(pos); + if (jrn == NULL) { + merror("%s: ERROR: Unable to prime journal", ARGV0); + return NULL; + } + } + + if (unit == NULL) { + unit = logff[pos].file = "all"; + } + + // Anything negative is an error + while (ret > 0) { + ret = sd_journal_next(jrn); + // below 0 Means problem or journal file vanished. Open it again next time and + // try again + // 0 means there is no new messages + if (ret < 0) { + sd_journal_close(jrn); + logff[pos].ptr = NULL; + *rc = -1; + continue; + } else if (!ret) { + continue; + } + // Check if data is coming from the unit starting with our passed selector + ret = sd_journal_get_data( + jrn, + "SYSLOG_IDENTIFIER", + (const void **)&jsrc, + &len + ); + // Strip off "SYSLOG_IDENTIFIER=" prefix for unit comparison inline + memset(sunitid, 0x00, 128); + strncpy(sunitid, (jsrc + 18), 128); + // If incoming systemd unit is unit or unit is 'all' which means log everything + // or unit starts which char '/' which means unit is directory and + // user have malconfigured journald + if (!strncmp(sunitid, unit, 128) || !strncmp(unit, "all", 3) || unit[0] == '/') { + // Read hostname + ret = sd_journal_get_data(jrn, "_HOSTNAME", (const void **)&jhst, &len); + // Read data + ret = sd_journal_get_data(jrn, "MESSAGE", (const void **)&jmsg, &len); + // Read timestamp and format it + ret = sd_journal_get_realtime_usec(jrn, &curr_timestamp); + tv.tv_sec = curr_timestamp / 1000000; + tv.tv_usec = curr_timestamp % 1000000; + nowtime = tv.tv_sec; + nowtm = localtime(&nowtime); + // We have to mimic syslog-ng for time and date for openarmor-HIDS + // time and date parser. + // Syslog-ng It produces broken ISO8601 strings like + // 2020-04-01T12:00:00+03:00 + // Journald reader triest to mimics it. + strftime(tmbuf, sizeof tmbuf, "%Y-%m-%dT%T%z", nowtm); + tmbuf[strlen(tmbuf) - 2] = '\0'; + // Build and send message + snprintf( + final_msg, + sizeof(final_msg), + "%s:00 %s %s: %.*s\n", + tmbuf, + // Strip the "_HOSTNAME", "SYSLOG_IDENTIFIER=" and "MESSAGE=" prefixes + (char *)(jhst + 10), + sunitid, + (int) len, + (char *)(jmsg + 8) + ); + if (SendMSG(logr_queue, final_msg, "journald", LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + } + // These pointers are only valid until next one + // So it's safe to just to NULL them + jhst = NULL; + jmsg = NULL; + } + // This pointer is only valid until next one + // So it's safe to just to NULL them + jsrc = NULL; + // Prime next iteration condition & journal position + ret = sd_journal_next(jrn); + } + return NULL; +} + +#endif //HAVE_SYSTEMD diff --git a/src/logcollector/read_mssql_log.c b/src/logcollector/read_mssql_log.c new file mode 100644 index 000000000..529bb3ac5 --- /dev/null +++ b/src/logcollector/read_mssql_log.c @@ -0,0 +1,151 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Read MS SQL logs */ + +#include "shared.h" +#include "logcollector.h" + + +/* Send MS SQL message and check the return code */ +static void __send_mssql_msg(int pos, int drop_it, char *buffer) +{ + debug2("%s: DEBUG: Reading MSSQL message: '%s'", ARGV0, buffer); + if (drop_it == 0) { + if (SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } +} + +/* Read MS SQL log files */ +void *read_mssql_log(int pos, int *rc, int drop_it) +{ + size_t str_len = 0; + int need_clear = 0; + char *p; + char str[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + + /* Zero buffer and str */ + buffer[0] = '\0'; + buffer[OS_MAXSTR] = '\0'; + str[OS_MAXSTR] = '\0'; + *rc = 0; + + /* Get new entry */ + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + /* Get buffer size */ + str_len = strlen(str); + + /* Check str_len size. Very useless, but just to make sure */ + if (str_len >= sizeof(buffer) - 2) { + str_len = sizeof(buffer) - 10; + } + + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + + /* If need clear is set, we just get the line and ignore it */ + if (need_clear) { + need_clear = 0; + continue; + } + } else { + need_clear = 1; + } + +#ifdef WIN32 + if ((p = strrchr(str, '\r')) != NULL) { + *p = '\0'; + } + + /* Look for empty string (only on windows) */ + if (str_len <= 1) { + continue; + } + + /* Windows can have comment on their logs */ + if (str[0] == '#') { + continue; + } +#endif + + /* MS SQL messages have the following formats: + * 2009-03-25 04:47:30.01 Server + * 2003-10-09 00:00:06.68 sys1 + * 2009-02-06 11:48:59 Server + */ + if ((str_len > 19) && + (str[4] == '-') && + (str[7] == '-') && + (str[10] == ' ') && + (str[13] == ':') && + (str[16] == ':') && + isdigit((int)str[0]) && + isdigit((int)str[1]) && + isdigit((int)str[2]) && + isdigit((int)str[3])) { + + /* If the saved message is empty, set it and continue */ + if (buffer[0] == '\0') { + strncpy(buffer, str, OS_MAXSTR); + continue; + } + + /* If not, send the saved one and store the new one for later */ + else { + __send_mssql_msg(pos, drop_it, buffer); + + /* Store current one at the buffer */ + strncpy(buffer, str, OS_MAXSTR); + } + } + + /* Query logs can be in multiple lines + * They always start with a tab in the additional lines + */ + else if ((str_len > 2) && (buffer[0] != '\0')) { + /* Size of the buffer */ + size_t buffer_len = strlen(buffer); + + p = str; + + /* Remove extra spaces and tabs */ + while (*p == ' ' || *p == '\t') { + p++; + } + + /* Add additional message to the saved buffer */ + if (sizeof(buffer) - buffer_len > str_len + 256) { + /* Here we make sure that the size of the buffer + * minus what was used (strlen) is greater than + * the length of the received message. + */ + buffer[buffer_len] = ' '; + buffer[buffer_len + 1] = '\0'; + strncat(buffer, str, OS_MAXSTR); + } + } + + continue; + } + + /* Send whatever is stored */ + if (buffer[0] != '\0') { + __send_mssql_msg(pos, drop_it, buffer); + } + + return (NULL); +} + diff --git a/src/logcollector/read_multiline.c b/src/logcollector/read_multiline.c new file mode 100644 index 000000000..0d353d31f --- /dev/null +++ b/src/logcollector/read_multiline.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read multiline logs */ +void *read_multiline(int pos, int *rc, int drop_it) +{ + int __ms = 0; + int linecount; + int linesgot = 0; + size_t buffer_size = 0; + char *p; + char str[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + fpos_t fp_pos; + + buffer[0] = '\0'; + buffer[OS_MAXSTR] = '\0'; + str[OS_MAXSTR] = '\0'; + *rc = 0; + + linecount = atoi(logff[pos].logformat); + + /* Get initial file location */ + fgetpos(logff[pos].fp, &fp_pos); + + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + linesgot++; + + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + } + + /* If we didn't get the new line, because the + * size is large, send what we got so far. + */ + else if (strlen(str) >= (OS_MAXSTR - OS_LOG_HEADER - 2)) { + /* Message size > maximum allowed */ + __ms = 1; + } else { + /* Message not complete. Return. */ + debug1("%s: Message not complete. Trying again: '%s'", ARGV0, str); + fsetpos(logff[pos].fp, &fp_pos); + break; + } + +#ifdef WIN32 + if ((p = strrchr(str, '\r')) != NULL) { + *p = '\0'; + } +#endif + + debug2("%s: DEBUG: Reading message: '%s'", ARGV0, str); + + /* Add to buffer */ + buffer_size = strlen(buffer); + if (buffer[0] != '\0') { + buffer[buffer_size] = ' '; + buffer_size++; + } + + strncpy(buffer + buffer_size, str, OS_MAXSTR - buffer_size - 2); + + if (linesgot < linecount) { + continue; + } + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, buffer, logff[pos].file, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + buffer[0] = '\0'; + + + /* Incorrect message size */ + if (__ms) { + merror("%s: Large message size: '%s'", ARGV0, str); + while (fgets(str, OS_MAXSTR - 2, logff[pos].fp) != NULL) { + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + break; + } + } + __ms = 0; + } + + fgetpos(logff[pos].fp, &fp_pos); + continue; + } + + return (NULL); +} + diff --git a/src/logcollector/read_multiline_indented.c b/src/logcollector/read_multiline_indented.c new file mode 100644 index 000000000..2937b4d48 --- /dev/null +++ b/src/logcollector/read_multiline_indented.c @@ -0,0 +1,120 @@ +/* Copyright (C) 2019, Semper Victus LLC + * Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Read indentend multi line logs */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read multi line indented log files */ +void *read_multiline_indented(int pos, int *rc, int drop_it) { + size_t str_len = 0; + char *p; + char str[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + /* Zero buffer and str */ + buffer[0] = '\0'; + buffer[OS_MAXSTR] = '\0'; + str[OS_MAXSTR] = '\0'; + *rc = 0; + + /* Get new entry */ + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + + /* Get buffer size */ + str_len = strlen(str); + + /* Check str_len size. Very useless, but just to make sure.. */ + if (str_len >= sizeof(buffer) - 2) { + str_len = sizeof(buffer) - 10; + } + + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + } + +#ifdef WIN32 + if ((p = strrchr(str, '\r')) != NULL) { + *p = '\0'; + } +#endif + /* Look for empty string */ + if ((str_len <= 1) || (str[0] == '\r')) { + /* Send existing data if any in buffer */ + if (buffer[0] != '\0') { + if (drop_it == 0 && SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + buffer[0] = '\0'; + } + continue; + } + + /* Look for lines starting with indents */ + if ((str_len > 2) && (buffer[0] != '\0') && + ((str[0] == ' ') || (str[0] == '\t'))) { + /* Size of the buffer */ + size_t buffer_len = strlen(buffer); + + p = str + 1; + + /* Remove extra spaces and tabs */ + while (*p == ' ' || *p == '\t') { + p++; + } + + /* Add additional message to the saved buffer */ + if (sizeof(buffer) - buffer_len > str_len + 256) { + /* Here we make sure that the size of the buffer + * minus what was used (strlen) is greater than + * the length of the received message. + */ + buffer[buffer_len] = ' '; + buffer[buffer_len + 1] = '\0'; + strncat(buffer, str, str_len + 3); + } + /* Look for lines not starting with indents */ + } else if ((str[0] != ' ') || (str[0] != '\t')) { + /* Flush previous messages */ + if (buffer[0] != '\0') { + if (drop_it == 0 && SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + buffer[0] = '\0'; + } + strncpy(buffer, str, str_len + 2); + continue; + /* Error handling for buffer[0] being '\0' when indents are present */ + } else { + // messages or retries + } + + } + + /* Send whatever is stored */ + if (buffer[0] != '\0') { + if (drop_it == 0 && SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + return (NULL); +} diff --git a/src/logcollector/read_mysql_log.c b/src/logcollector/read_mysql_log.c new file mode 100644 index 000000000..2f11722c0 --- /dev/null +++ b/src/logcollector/read_mysql_log.c @@ -0,0 +1,139 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Read MySQL logs */ + +#include "shared.h" +#include "logcollector.h" + +/* Starting last time */ +static char __mysql_last_time[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + +void *read_mysql_log(int pos, int *rc, int drop_it) +{ + size_t str_len = 0; + int need_clear = 0; + char *p; + char str[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + + str[OS_MAXSTR] = '\0'; + *rc = 0; + + /* Get new entry */ + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + /* Get buffer size */ + str_len = strlen(str); + + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + + /* If need clear is set, we just get the line and ignore it */ + if (need_clear) { + need_clear = 0; + continue; + } + } else { + need_clear = 1; + } + +#ifdef WIN32 + if ((p = strrchr(str, '\r')) != NULL) { + *p = '\0'; + } + + /* Look for empty string (only on windows) */ + if (str_len <= 2) { + continue; + } + + + /* Windows can have comment on their logs */ + if (str[0] == '#') { + continue; + } +#endif + + /* MySQL messages have the following format: + * 070823 21:01:30 xx + */ + if ((str_len > 18) && + (str[6] == ' ') && + (str[9] == ':') && + (str[12] == ':') && + isdigit((int)str[0]) && + isdigit((int)str[1]) && + isdigit((int)str[2]) && + isdigit((int)str[3]) && + isdigit((int)str[4]) && + isdigit((int)str[5]) && + isdigit((int)str[7]) && + isdigit((int)str[8])) { + /* Save last time */ + strncpy(__mysql_last_time, str, 16); + __mysql_last_time[15] = '\0'; + + + /* Remove spaces and tabs */ + p = str + 15; + while (*p == ' ' || *p == '\t') { + p++; + } + + /* Valid MySQL message */ + snprintf(buffer, OS_MAXSTR, "MySQL log: %s %s", + __mysql_last_time, p); + } + + /* Multiple events at the same second share the same timestamp: + * 0909 2020 2020 2020 20 + */ + else if ((str_len > 10) && (__mysql_last_time[0] != '\0') && + (str[0] == 0x09) && + (str[1] == 0x09) && + (str[2] == 0x20) && + (str[3] == 0x20) && + (str[4] == 0x20) && + (str[5] == 0x20) && + (str[6] == 0x20) && + (str[7] == 0x20)) { + p = str + 2; + + /* Remove extra spaces and tabs */ + while (*p == ' ' || *p == '\t') { + p++; + } + + /* Valid MySQL message */ + snprintf(buffer, OS_MAXSTR, "MySQL log: %s %s", + __mysql_last_time, p); + } else { + continue; + } + + debug2("%s: DEBUG: Reading mysql messages: '%s'", ARGV0, buffer); + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, buffer, logff[pos].file, MYSQL_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + continue; + } + + return (NULL); +} + diff --git a/src/logcollector/read_nmapg.c b/src/logcollector/read_nmapg.c new file mode 100644 index 000000000..469390a12 --- /dev/null +++ b/src/logcollector/read_nmapg.c @@ -0,0 +1,261 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + +#define NMAPG_HOST "Host: " +#define NMAPG_PORT "Ports:" +#define NMAPG_OPEN "open/" +#define NMAPG_STAT "Status:" + +/* Prototypes */ +static char *__go_after(char *x, const char *y); +static char *__get_port(char *str, char *proto, char *port, size_t msize); + + +/* Get port and protocol */ +static char *__get_port(char *str, char *proto, char *port, size_t msize) +{ + int filtered = 0; + char *p, *q; + + /* Remov whitespace */ + while (*str == ' ') { + str++; + } + + /* Get port */ + p = strchr(str, '/'); + if (!p) { + return (NULL); + } + *p = '\0'; + p++; + + /* Get port */ + strncpy(port, str, msize); + port[msize - 1] = '\0'; + + /* Check if the port is open */ + q = __go_after(p, NMAPG_OPEN); + if (!q) { + /* Port is not open */ + filtered = 1; + q = p; + + /* Going to the start of protocol field */ + p = strchr(q, '/'); + if (!p) { + return (NULL); + } + p++; + } else { + p = q; + } + + /* Get protocol */ + str = p; + p = strchr(str, '/'); + if (!p) { + return (NULL); + } + *p = '\0'; + p++; + + strncpy(proto, str, msize); + proto[msize - 1] = '\0'; + + /* Set proto to null if port is not open */ + if (filtered) { + proto[0] = '\0'; + } + + /* Remove slashes */ + if (*p == '/') { + p++; + q = p; + p = strchr(p, ','); + if (p) { + return (p); + } + + return (q); + } + + return (NULL); +} + +/* Check if the string matches */ +static char *__go_after(char *x, const char *y) +{ + size_t x_s; + size_t y_s; + + /* X and Y must be not null */ + if (!x || !y) { + return (NULL); + } + + x_s = strlen(x); + y_s = strlen(y); + + if (x_s <= y_s) { + return (NULL); + } + + /* String does not match */ + if (strncmp(x, y, y_s) != 0) { + return (NULL); + } + + x += y_s; + + return (x); +} + +/* Read Nmap grepable files */ +void *read_nmapg(int pos, int *rc, int drop_it) +{ + int final_msg_s; + int need_clear = 0; + + char str[OS_MAXSTR + 1]; + char final_msg[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + char port[17]; + char proto[17]; + + char *ip = NULL; + char *p; + char *q; + + *rc = 0; + str[OS_MAXSTR] = '\0'; + final_msg[OS_MAXSTR] = '\0'; + buffer[OS_MAXSTR] = '\0'; + + port[16] = '\0'; + proto[16] = '\0'; + + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + /* If need clear is set, we need to clear the line */ + if (need_clear) { + if ((q = strchr(str, '\n')) != NULL) { + need_clear = 0; + } + continue; + } + + /* Remove \n at the end of the string */ + if ((q = strchr(str, '\n')) != NULL) { + *q = '\0'; + } else { + need_clear = 1; + } + + /* Do not get commented lines */ + if ((str[0] == '#') || (str[0] == '\0')) { + continue; + } + + /* Get host */ + q = __go_after(str, NMAPG_HOST); + if (!q) { + goto file_error; + } + + /* Get ip/hostname */ + p = strchr(q, ')'); + if (!p) { + goto file_error; + } + + /* Setting the valid ip */ + ip = q; + + /* Get the ports */ + q = strchr(p, '\t'); + if (!q) { + goto file_error; + } + q++; + + /* Now fixing p, to have the closing parenthesis */ + p++; + *p = '\0'; + + /* q now should point to the ports */ + p = __go_after(q, NMAPG_PORT); + if (!p) { + /* Check if no port is available */ + p = __go_after(q, NMAPG_STAT); + if (p) { + continue; + } + + goto file_error; + } + + /* Generate final msg */ + snprintf(final_msg, OS_MAXSTR, "Host: %s, open ports:", + ip); + final_msg_s = OS_MAXSTR - ((strlen(final_msg) + 3)); + + /* Get port and protocol */ + do { + /* Avoid filling the buffer (3*port size) */ + if (final_msg_s < 27) { + break; + } + + p = __get_port(p, proto, port, 9); + if (!p) { + debug1("%s: Bad formatted nmap grepable file (port).", ARGV0); + break; + } + + /* Port not open */ + if (proto[0] == '\0') { + continue; + } + + /* Add ports */ + snprintf(buffer, OS_MAXSTR, " %s(%s)", port, proto); + strncat(final_msg, buffer, final_msg_s); + final_msg_s -= (strlen(buffer) + 2); + + } while (*p == ',' && (p++)); + + if (drop_it == 0) { + /* Send message to queue */ + if (SendMSG(logr_queue, final_msg, logff[pos].file, + HOSTINFO_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + /* Get next */ + continue; + + /* Handle errors */ +file_error: + + merror("%s: Bad formatted nmap grepable file.", ARGV0); + *rc = -1; + return (NULL); + + } + + return (NULL); +} + diff --git a/src/logcollector/read_openarmoralert.c b/src/logcollector/read_openarmoralert.c new file mode 100644 index 000000000..f6a2543a1 --- /dev/null +++ b/src/logcollector/read_openarmoralert.c @@ -0,0 +1,113 @@ +/* Copyright (C) 2012 Daniel B. Cid (http://dcid.me) + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "headers/read-alert.h" +#include "logcollector.h" + + +void *read_openarmoralert(int pos, __attribute__((unused)) int *rc, int drop_it) +{ + alert_data *al_data; + char user_msg[256]; + char srcip_msg[256]; + char syslog_msg[OS_SIZE_2048 + 1]; + + *rc = 0; + + al_data = GetAlertData(0, logff[pos].fp); + if (!al_data) { + return (NULL); + } + + memset(syslog_msg, '\0', OS_SIZE_2048 + 1); + + /* Add source ip */ + if (!al_data->srcip || + ((al_data->srcip[0] == '(') && + (al_data->srcip[1] == 'n') && + (al_data->srcip[2] == 'o'))) { + srcip_msg[0] = '\0'; + } else { + snprintf(srcip_msg, 255, " srcip: %s;", al_data->srcip); + } + + /* Add username */ + if (!al_data->user || + ((al_data->user[0] == '(') && + (al_data->user[1] == 'n') && + (al_data->user[2] == 'o'))) { + user_msg[0] = '\0'; + } else { + snprintf(user_msg, 255, " user: %s;", al_data->user); + } + + if (al_data->log[1] == NULL) { + /* Build syslog message */ + snprintf(syslog_msg, OS_SIZE_2048, + "openarmor: Alert Level: %d; Rule: %d - %s; " + "Location: %s;%s%s %s", + al_data->level, al_data->rule, al_data->comment, + al_data->location, + srcip_msg, + user_msg, + al_data->log[0]); + } else { + char *tmp_msg = NULL; + short int j = 0; + + while (al_data->log[j] != NULL) { + tmp_msg = os_LoadString(tmp_msg, al_data->log[j]); + tmp_msg = os_LoadString(tmp_msg, "\n"); + if (tmp_msg == NULL) { + FreeAlertData(al_data); + return (NULL); + } + j++; + } + + if (tmp_msg == NULL) { + FreeAlertData(al_data); + return (NULL); + } + + if (strlen(tmp_msg) > 1596) { + tmp_msg[1594] = '.'; + tmp_msg[1595] = '.'; + tmp_msg[1596] = '.'; + tmp_msg[1597] = '\0'; + } + snprintf(syslog_msg, OS_SIZE_2048, + "openarmor: Alert Level: %d; Rule: %d - %s; " + "Location: %s;%s%s %s", + al_data->level, al_data->rule, al_data->comment, + al_data->location, + srcip_msg, + user_msg, + tmp_msg); + + free(tmp_msg); + } + + /* Clear the memory */ + FreeAlertData(al_data); + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, syslog_msg, logff[pos].file, LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + return (NULL); +} + diff --git a/src/logcollector/read_postgresql_log.c b/src/logcollector/read_postgresql_log.c new file mode 100644 index 000000000..00993915d --- /dev/null +++ b/src/logcollector/read_postgresql_log.c @@ -0,0 +1,148 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Read PostgreSQL logs */ + +#include "shared.h" +#include "logcollector.h" + + +/* Send pgsql message and check the return code */ +static void __send_pgsql_msg(int pos, int drop_it, char *buffer) +{ + debug2("%s: DEBUG: Reading PostgreSQL message: '%s'", ARGV0, buffer); + if (drop_it == 0) { + if (SendMSG(logr_queue, buffer, logff[pos].file, POSTGRESQL_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } +} + +/* Read PostgreSQL log files */ +void *read_postgresql_log(int pos, int *rc, int drop_it) +{ + size_t str_len = 0; + int need_clear = 0; + char *p; + char str[OS_MAXSTR + 1]; + char buffer[OS_MAXSTR + 1]; + + /* Zero buffer and str */ + buffer[0] = '\0'; + buffer[OS_MAXSTR] = '\0'; + str[OS_MAXSTR] = '\0'; + *rc = 0; + + /* Get new entry */ + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + /* Get buffer size */ + str_len = strlen(str); + + /* Check str_len size. Very useless, but just to make sure.. */ + if (str_len >= sizeof(buffer) - 2) { + str_len = sizeof(buffer) - 10; + } + + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + + /* If need_clear is set, we just get the line and ignore it. */ + if (need_clear) { + need_clear = 0; + continue; + } + } else { + need_clear = 1; + } + +#ifdef WIN32 + if ((p = strrchr(str, '\r')) != NULL) { + *p = '\0'; + } + + /* Look for empty string (only on Windows) */ + if (str_len <= 1) { + continue; + } + + /* Windows can have comment on their logs */ + if (str[0] == '#') { + continue; + } +#endif + + /* PostgreSQL messages have the following format: + * [2007-08-31 19:17:32.186 ADT] 192.168.2.99:db_name + */ + if ((str_len > 32) && + (str[0] == '[') && + (str[5] == '-') && + (str[8] == '-') && + (str[11] == ' ') && + (str[14] == ':') && + (str[17] == ':') && + isdigit((int)str[1]) && + isdigit((int)str[12])) { + + /* If the saved message is empty, set it and continue */ + if (buffer[0] == '\0') { + strncpy(buffer, str, str_len + 2); + continue; + } + + /* If not, send the saved one and store the new one for later */ + else { + __send_pgsql_msg(pos, drop_it, buffer); + /* Store current one at the buffer */ + strncpy(buffer, str, str_len + 2); + } + } + + /* Query logs can be in multiple lines + * They always start with a tab in the additional ones + */ + else if ((str_len > 2) && (buffer[0] != '\0') && + (str[0] == '\t')) { + /* Size of the buffer */ + size_t buffer_len = strlen(buffer); + + p = str + 1; + + /* Remove extra spaces and tabs */ + while (*p == ' ' || *p == '\t') { + p++; + } + + /* Add additional message to the saved buffer */ + if (sizeof(buffer) - buffer_len > str_len + 256) { + /* Here we make sure that the size of the buffer + * minus what was used (strlen) is greater than + * the length of the received message. + */ + buffer[buffer_len] = ' '; + buffer[buffer_len + 1] = '\0'; + strncat(buffer, str, str_len + 3); + } + } + + continue; + } + + /* Send whatever is stored */ + if (buffer[0] != '\0') { + __send_pgsql_msg(pos, drop_it, buffer); + } + + return (NULL); +} + diff --git a/src/logcollector/read_snortfull.c b/src/logcollector/read_snortfull.c new file mode 100644 index 000000000..a1f35b609 --- /dev/null +++ b/src/logcollector/read_snortfull.c @@ -0,0 +1,126 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read snort_full files */ +void *read_snortfull(int pos, int *rc, int drop_it) +{ + int f_msg_size = OS_MAXSTR; + const char *one = "one"; + const char *two = "two"; + const char *p = NULL; + char *q; + char str[OS_MAXSTR + 1]; + char f_msg[OS_MAXSTR + 1]; + + *rc = 0; + str[OS_MAXSTR] = '\0'; + f_msg[OS_MAXSTR] = '\0'; + + while (fgets(str, OS_MAXSTR, logff[pos].fp) != NULL) { + /* Remove \n at the end of the string */ + if ((q = strrchr(str, '\n')) != NULL) { + *q = '\0'; + } else { + goto file_error; + } + + /* First part of the message */ + if (p == NULL) { + if (strncmp(str, "[**] [", 6) == 0) { + strncpy(f_msg, str, OS_MAXSTR); + f_msg_size -= strlen(str) + 1; + p = one; + } + } else { + if (p == one) { + /* Second line has the [Classification: */ + if (strncmp(str, "[Classification: ", 16) == 0) { + strncat(f_msg, str, f_msg_size); + f_msg_size -= strlen(str) + 1; + p = two; + } else if (strncmp(str, "[Priority: ", 10) == 0) { + strncat(f_msg, "[Classification: Preprocessor] " + "[Priority: 3] ", f_msg_size); + f_msg_size -= strlen(str) + 1; + p = two; + } + + /* If it is a preprocessor message, it will not have + * the classification. + */ + else if ((str[2] == '/') && (str[5] == '-') && (q = strchr(str, ' '))) { + strncat(f_msg, "[Classification: Preprocessor] " + "[Priority: 3] ", f_msg_size); + strncat(f_msg, ++q, f_msg_size - 40); + + /* Clean for next event */ + p = NULL; + + /* Send the message */ + if (drop_it == 0) { + if (SendMSG(logr_queue, f_msg, logff[pos].file, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + f_msg[0] = '\0'; + f_msg_size = OS_MAXSTR; + str[0] = '\0'; + } else { + goto file_error; + } + } else if (p == two) { + /* Third line has the 01/13-15 (date) */ + if ((str[2] == '/') && (str[5] == '-') && (q = strchr(str, ' '))) { + strncat(f_msg, ++q, f_msg_size); + f_msg_size -= strlen(q) + 1; + p = NULL; + + /* Send the message */ + if (drop_it == 0) { + if (SendMSG(logr_queue, f_msg, logff[pos].file, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + f_msg[0] = '\0'; + f_msg_size = OS_MAXSTR; + str[0] = '\0'; + } else { + goto file_error; + } + + } + } + + continue; + +file_error: + + merror("%s: Bad formatted snort full file.", ARGV0); + *rc = -1; + return (NULL); + + } + + return (NULL); +} + diff --git a/src/logcollector/read_syslog.c b/src/logcollector/read_syslog.c new file mode 100644 index 000000000..7a40ca2eb --- /dev/null +++ b/src/logcollector/read_syslog.c @@ -0,0 +1,108 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Read the syslog */ + +#include "shared.h" +#include "logcollector.h" + + +/* Read syslog files */ +void *read_syslog(int pos, int *rc, int drop_it) +{ + int __ms = 0; + char *p; + char str[OS_MAXSTR + 1]; + fpos_t fp_pos; + + str[OS_MAXSTR] = '\0'; + *rc = 0; + + /* Get initial file location */ + fgetpos(logff[pos].fp, &fp_pos); + + while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { + /* Get the last occurrence of \n */ + if ((p = strrchr(str, '\n')) != NULL) { + *p = '\0'; + /* From issue #913 @ybonnamy */ + } else if((p = strchr(str, '\0')) != NULL) { + /* Replace NUL with a space */ + *p = ' '; + } + + /* If we didn't get the new line, because the + * size is large, send what we got so far. + */ + else if (strlen(str) >= (OS_MAXSTR - OS_LOG_HEADER - 2)) { + /* Message size > maximum allowed */ + __ms = 1; + } else { + /* Message not complete. Return. */ + debug1("%s: Message not complete. Trying again: '%s'", ARGV0, str); + fsetpos(logff[pos].fp, &fp_pos); + break; + } + +#ifdef WIN32 + if ((p = strrchr(str, '\r')) != NULL) { + *p = '\0'; + } + + /* Look for empty string (only on Windows) */ + if (strlen(str) <= 2) { + fgetpos(logff[pos].fp, &fp_pos); + continue; + } + + /* Windows can have comment on their logs */ + if (str[0] == '#') { + fgetpos(logff[pos].fp, &fp_pos); + continue; + } +#endif + + debug2("%s: DEBUG: Reading syslog message: '%s'", ARGV0, str); + + /* Send message to queue */ + if (drop_it == 0) { + if (SendMSG(logr_queue, str, logff[pos].file, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + /* Incorrect message size */ + if (__ms) { + // strlen(str) >= (OS_MAXSTR - OS_LOG_HEADER - 2) + // truncate str before logging to openarmor.log +#define OUTSIZE 4096 + char buf[OUTSIZE + 1]; + buf[OUTSIZE] = '\0'; + snprintf(buf, OUTSIZE, "%s", str); + merror("%s: Large message size(length=%d): '%s...'", ARGV0, (int)strlen(str), buf); + while (fgets(str, OS_MAXSTR - 2, logff[pos].fp) != NULL) { + /* Get the last occurrence of \n */ + if (strrchr(str, '\n') != NULL) { + break; + } + } + __ms = 0; + } + + fgetpos(logff[pos].fp, &fp_pos); + continue; + } + + return (NULL); +} + diff --git a/src/logcollector/read_win_el.c b/src/logcollector/read_win_el.c new file mode 100644 index 000000000..8aa149a48 --- /dev/null +++ b/src/logcollector/read_win_el.c @@ -0,0 +1,627 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "logcollector.h" + +#ifdef WIN32 + +#define BUFFER_SIZE 2048*256 + +/* Event logging local structure */ +typedef struct _os_el { + int time_of_last; + char *name; + + EVENTLOGRECORD *er; + HANDLE h; + + DWORD record; + +} os_el; + +/** Global variables **/ + +/* Maximum of 9 event log sources */ +os_el el[9]; +int el_last = 0; +void *vista_sec_id_hash = NULL; +void *dll_hash = NULL; + + +/* Start the event logging for each el */ +int startEL(char *app, os_el *el) +{ + DWORD NumberOfRecords = 0; + + /* Open the event log */ + el->h = OpenEventLog(NULL, app); + if (!el->h) { + merror(EVTLOG_OPEN, ARGV0, app); + return (-1); + } + + el->name = app; + if (GetOldestEventLogRecord(el->h, &el->record) == 0) { + /* Unable to read oldest event log record */ + merror(EVTLOG_GETLAST, ARGV0, app); + CloseEventLog(el->h); + el->h = NULL; + return (-1); + } + + if (GetNumberOfEventLogRecords(el->h, &NumberOfRecords) == 0) { + merror(EVTLOG_GETLAST, ARGV0, app); + CloseEventLog(el->h); + el->h = NULL; + return (-1); + } + + if (NumberOfRecords <= 0) { + return (0); + } + + return ((int)NumberOfRecords); +} + +/* Returns a string that is a human readable datetime from an epoch int */ +char *epoch_to_human(time_t epoch) +{ + struct tm *ts; + static char buf[80]; + + ts = localtime(&epoch); + strftime(buf, sizeof(buf), "%Y %b %d %H:%M:%S", ts); + return (buf); +} + +/* Returns a string related to the category id of the log */ +char *el_getCategory(int category_id) +{ + char *cat; + switch (category_id) { + case EVENTLOG_ERROR_TYPE: + cat = "ERROR"; + break; + case EVENTLOG_WARNING_TYPE: + cat = "WARNING"; + break; + case EVENTLOG_INFORMATION_TYPE: + cat = "INFORMATION"; + break; + case EVENTLOG_AUDIT_SUCCESS: + cat = "AUDIT_SUCCESS"; + break; + case EVENTLOG_AUDIT_FAILURE: + cat = "AUDIT_FAILURE"; + break; + default: + cat = "Unknown"; + break; + } + return (cat); +} + +/* Returns the event */ +char *el_getEventDLL(char *evt_name, char *source, char *event) +{ + char *ret_str; + HKEY key; + DWORD ret; + char keyname[512]; + + keyname[511] = '\0'; + + snprintf(keyname, 510, + "System\\CurrentControlSet\\Services\\EventLog\\%s\\%s", + evt_name, + source); + + /* Check if we have it in memory */ + ret_str = OSHash_Get(dll_hash, keyname + 42); + if (ret_str) { + return (ret_str); + } + + /* Open Registry */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, + KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) { + return (NULL); + } + + ret = MAX_PATH - 1; + if (RegQueryValueEx(key, "EventMessageFile", NULL, + NULL, (LPBYTE)event, &ret) != ERROR_SUCCESS) { + event[0] = '\0'; + RegCloseKey(key); + return (NULL); + } else { + /* Adding to memory */ + char *skey; + char *sval; + + skey = strdup(keyname + 42); + sval = strdup(event); + + if (skey && sval) { + OSHash_Add(dll_hash, skey, sval); + } else { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + } + + RegCloseKey(key); + return (event); +} + +/* Returns a descriptive message of the event - Vista only */ +char *el_vista_getMessage(int evt_id_int, LPTSTR *el_sstring) +{ + DWORD fm_flags = 0; + LPSTR message = NULL; + char *desc_string; + char evt_id[16]; + + /* Flags for format event */ + fm_flags |= FORMAT_MESSAGE_FROM_STRING; + fm_flags |= FORMAT_MESSAGE_ALLOCATE_BUFFER; + fm_flags |= FORMAT_MESSAGE_ARGUMENT_ARRAY; + + /* Get descriptive message */ + evt_id[15] = '\0'; + snprintf(evt_id, 15, "%d", evt_id_int); + + desc_string = OSHash_Get(vista_sec_id_hash, evt_id); + if (!desc_string) { + return (NULL); + } + + if (!FormatMessage(fm_flags, desc_string, 0, 0, + (LPTSTR) &message, 0, el_sstring)) { + return (NULL); + } + + return (message); +} + +/* Returns a descriptive message of the event */ +char *el_getMessage(EVENTLOGRECORD *er, char *name, + char *source, LPTSTR *el_sstring) +{ + DWORD fm_flags = 0; + char tmp_str[257]; + char event[MAX_PATH + 1]; + char *curr_str; + char *next_str; + LPSTR message = NULL; + + HMODULE hevt; + + /* Initialize variables */ + event[MAX_PATH] = '\0'; + tmp_str[256] = '\0'; + + /* Flags for format event */ + fm_flags |= FORMAT_MESSAGE_FROM_HMODULE; + fm_flags |= FORMAT_MESSAGE_ALLOCATE_BUFFER; + fm_flags |= FORMAT_MESSAGE_ARGUMENT_ARRAY; + + /* Get the file name from the registry (stored on event) */ + if (!(curr_str = el_getEventDLL(name, source, event))) { + return (NULL); + } + + /* If our event has multiple libraries, try each one of them */ + while ((next_str = strchr(curr_str, ';'))) { + *next_str = '\0'; + + ExpandEnvironmentStrings(curr_str, tmp_str, 255); + + /* Revert back old value */ + *next_str = ';'; + + /* Load library */ + hevt = LoadLibraryEx(tmp_str, NULL, + DONT_RESOLVE_DLL_REFERENCES | + LOAD_LIBRARY_AS_DATAFILE); + if (hevt) { + if (!FormatMessage(fm_flags, hevt, er->EventID, 0, + (LPTSTR) &message, 0, el_sstring)) { + message = NULL; + } + FreeLibrary(hevt); + + /* If we have a message, we can return it */ + if (message) { + return (message); + } + } + + curr_str = next_str + 1; + } + + /* Get last value */ + ExpandEnvironmentStrings(curr_str, tmp_str, 255); + hevt = LoadLibraryEx(tmp_str, NULL, + DONT_RESOLVE_DLL_REFERENCES | + LOAD_LIBRARY_AS_DATAFILE); + if (hevt) { + int hr; + if (!(hr = FormatMessage(fm_flags, hevt, er->EventID, + 0, + (LPTSTR) &message, 0, el_sstring))) { + message = NULL; + } + FreeLibrary(hevt); + + /* If we have a message, we can return it */ + if (message) { + return (message); + } + } + + return (NULL); +} + +/* Reads the event log */ +void readel(os_el *el, int printit) +{ + DWORD _evtid = 65535; + DWORD nstr; + DWORD user_size; + DWORD domain_size; + DWORD read, needed; + int size_left; + int str_size; + int id; + + char mbuffer[BUFFER_SIZE + 1]; + LPSTR sstr = NULL; + + char *tmp_str = NULL; + char *category; + char *source; + char *computer_name; + char *descriptive_msg; + + char el_user[OS_FLSIZE + 1]; + char el_domain[OS_FLSIZE + 1]; + char el_string[OS_MAXSTR + 1]; + char final_msg[OS_MAXSTR + 1]; + LPSTR el_sstring[OS_FLSIZE + 1]; + + /* er must point to the mbuffer */ + el->er = (EVENTLOGRECORD *) &mbuffer; + + /* Zero the values */ + el_string[OS_MAXSTR] = '\0'; + el_user[OS_FLSIZE] = '\0'; + el_domain[OS_FLSIZE] = '\0'; + final_msg[OS_MAXSTR] = '\0'; + el_sstring[0] = NULL; + el_sstring[OS_FLSIZE] = NULL; + + /* Event log is not open */ + if (!el->h) { + return; + } + + /* Read the event log */ + while (ReadEventLog(el->h, + EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, + 0, + el->er, BUFFER_SIZE - 1, &read, &needed)) { + if (!printit) { + /* Set er to the beginning of the buffer */ + el->er = (EVENTLOGRECORD *)&mbuffer; + continue; + } + + + while (read > 0) { + /* We need to initialize every variable before the loop */ + category = el_getCategory(el->er->EventType); + source = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD)); + computer_name = source + strlen(source) + 1; + descriptive_msg = NULL; + + /* Get event id */ + id = (int)el->er->EventID & _evtid; + + /* Initialize domain/user size */ + user_size = 255; + domain_size = 255; + el_domain[0] = '\0'; + el_user[0] = '\0'; + + /* We must have some description */ + if (el->er->NumStrings) { + size_left = OS_MAXSTR - OS_SIZE_1024; + + sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset); + el_string[0] = '\0'; + + for (nstr = 0; nstr < el->er->NumStrings; nstr++) { + str_size = strlen(sstr); + if (size_left > 1) { + strncat(el_string, sstr, size_left); + } + + tmp_str = strchr(el_string, '\0'); + if (tmp_str) { + *tmp_str = ' '; + tmp_str++; + *tmp_str = '\0'; + } else { + merror("%s: Invalid application string (size+)", + ARGV0); + } + size_left -= str_size + 2; + + if (nstr <= 92) { + el_sstring[nstr] = (LPSTR)sstr; + el_sstring[nstr + 1] = NULL; + } + + sstr = strchr( (LPSTR)sstr, '\0'); + if (sstr) { + sstr++; + } else { + break; + } + } + + /* Get a more descriptive message (if available) */ + if (isVista && strcmp(el->name, "Security") == 0) { + descriptive_msg = el_vista_getMessage(id, el_sstring); + } + + else { + descriptive_msg = el_getMessage(el->er, + el->name, + source, + el_sstring); + } + + if (descriptive_msg != NULL) { + /* format message */ + win_format_event_string(descriptive_msg); + } + } else { + strncpy(el_string, "(no message)", 128); + } + + /* Get username */ + if (el->er->UserSidLength) { + SID_NAME_USE account_type; + if (!LookupAccountSid(NULL, + (SID *)((LPSTR)el->er + + el->er->UserSidOffset), + el_user, + &user_size, + el_domain, + &domain_size, + &account_type)) { + strncpy(el_user, "(no user)", 255); + strncpy(el_domain, "no domain", 255); + } + } + + else if (isVista && strcmp(el->name, "Security") == 0) { + int uid_array_id = -1; + + switch (id) { + case 4624: + uid_array_id = 5; + break; + case 4634: + uid_array_id = 1; + break; + case 4647: + uid_array_id = 1; + break; + case 4769: + uid_array_id = 0; + break; + } + + if ((uid_array_id >= 0) && + el_sstring[uid_array_id] && + el_sstring[uid_array_id + 1]) { + strncpy(el_user, el_sstring[uid_array_id], OS_FLSIZE); + strncpy(el_domain, el_sstring[uid_array_id + 1], OS_FLSIZE); + } else { + strncpy(el_user, "(no user)", 255); + strncpy(el_domain, "no domain", 255); + } + } + + else { + strncpy(el_user, "(no user)", 255); + strncpy(el_domain, "no domain", 255); + } + + if (printit) { + DWORD _evtid = 65535; + int id = (int)el->er->EventID & _evtid; + + final_msg[OS_MAXSTR - OS_LOG_HEADER] = '\0'; + final_msg[OS_MAXSTR - OS_LOG_HEADER - 1] = '\0'; + + snprintf(final_msg, OS_MAXSTR - OS_LOG_HEADER - 1, + "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s", + epoch_to_human((int)el->er->TimeGenerated), + el->name, + category, + id, + source, + el_user, + el_domain, + computer_name, + descriptive_msg != NULL ? descriptive_msg : el_string); + + if (SendMSG(logr_queue, final_msg, "WinEvtLog", + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + } + } + + if (descriptive_msg != NULL) { + LocalFree(descriptive_msg); + } + + /* Change the point to the er */ + read -= el->er->Length; + el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length); + } + + /* Set er to the beginning of the buffer */ + el->er = (EVENTLOGRECORD *)&mbuffer; + } + + id = GetLastError(); + if (id == ERROR_HANDLE_EOF) { + return; + } + + /* Event log was cleared */ + else if (id == ERROR_EVENTLOG_FILE_CHANGED) { + char msg_alert[512 + 1]; + msg_alert[512] = '\0'; + merror("%s: WARN: Event log cleared: '%s'", ARGV0, el->name); + + /* Send message about cleared */ + snprintf(msg_alert, 512, "openarmor: Event log cleared: '%s'", el->name); + SendMSG(logr_queue, msg_alert, "WinEvtLog", LOCALFILE_MQ); + + /* Close the event log and reopen */ + CloseEventLog(el->h); + el->h = NULL; + + /* Reopen */ + if (startEL(el->name, el) < 0) { + merror("%s: ERROR: Unable to reopen event log '%s'", + ARGV0, el->name); + } + } + + else { + debug1("%s: WARN: Error reading event log: %d", ARGV0, id); + } +} + +/* Read Windows Vista security description */ +void win_read_vista_sec() +{ + char *p; + char buf[OS_MAXSTR + 1]; + FILE *fp; + + /* Vista security */ + fp = fopen("vista_sec.txt", "r"); + if (!fp) { + merror("%s: ERROR: Unable to read vista security descriptions.", + ARGV0); + exit(1); + } + + /* Creating the hash */ + vista_sec_id_hash = OSHash_Create(); + if (!vista_sec_id_hash) { + merror("%s: ERROR: Unable to read vista security descriptions.", + ARGV0); + exit(1); + } + + /* Read the whole file and add it to memory */ + while (fgets(buf, OS_MAXSTR, fp) != NULL) { + char *key; + char *desc; + + /* Get the last occurrence of \n */ + if ((p = strrchr(buf, '\n')) != NULL) { + *p = '\0'; + } + + p = strchr(buf, ','); + if (!p) { + merror("%s: ERROR: Invalid entry on the Vista security " + "description.", ARGV0); + continue; + } + + *p = '\0'; + p++; + + /* Remove whitespace */ + while (*p == ' ') { + p++; + } + + /* Allocate memory */ + desc = strdup(p); + key = strdup(buf); + if (!key || !desc) { + merror("%s: ERROR: Invalid entry on the Vista security " + "description.", ARGV0); + continue; + } + + /* Insert on hash */ + OSHash_Add(vista_sec_id_hash, key, desc); + } + + fclose(fp); +} + +/* Start the event logging for windows */ +void win_startel(char *evt_log) +{ + int entries_count = 0; + + /* Maximum size */ + if (el_last == 9) { + merror(EVTLOG_DUP, ARGV0, evt_log); + return; + } + + /* Create the DLL hash */ + if (!dll_hash) { + dll_hash = OSHash_Create(); + if (!dll_hash) { + merror("%s: ERROR: Unable to create DLL hash.", + ARGV0); + } + } + + /* Start event log -- going to last available record */ + if ((entries_count = startEL(evt_log, &el[el_last])) < 0) { + merror(INV_EVTLOG, ARGV0, evt_log); + return; + } else { + readel(&el[el_last], 0); + } + el_last++; +} + +/* Read the event logging for windows */ +void win_readel() +{ + int i = 0; + + /* Sleep plus 2 seconds before reading again */ + Sleep(2000); + + for (; i < el_last; i++) { + readel(&el[i], 1); + } +} + +#endif + diff --git a/src/logcollector/read_win_event_channel.c b/src/logcollector/read_win_event_channel.c new file mode 100644 index 000000000..a0c37194b --- /dev/null +++ b/src/logcollector/read_win_event_channel.c @@ -0,0 +1,983 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifdef WIN32 +#ifdef EVENTCHANNEL_SUPPORT + +/* Saying we are on Vista in order to have the API */ +#define _WIN32_WINNT 0x0600 + +/* Using Secure APIs */ +#define MINGW_HAS_SECURE_API 1 + +/* Bookmarks directory */ +#define BOOKMARKS_DIR "bookmarks" + +#ifndef WC_ERR_INVALID_CHARS +#define WC_ERR_INVALID_CHARS 0x80 +#endif + +/* Logging levels */ +#define WINEVENT_AUDIT 0 +#define WINEVENT_CRITICAL 1 +#define WINEVENT_ERROR 2 +#define WINEVENT_WARNING 3 +#define WINEVENT_INFORMATION 4 +#define WINEVENT_VERBOSE 5 + +/* Audit types */ +#define WINEVENT_AUDIT_FAILURE 0x10000000000000LL +#define WINEVENT_AUDIT_SUCCESS 0x20000000000000LL + +#include "shared.h" +#include "logcollector.h" + +#include +#include +#include +#include +#include + +typedef struct _os_event { + char *name; + unsigned int id; + char *source; + SID *uid; + char *user; + char *domain; + char *computer; + char *message; + ULONGLONG time_created; + char *timestamp; + int64_t keywords; + int64_t level; + char *category; +} os_event; + +typedef struct _os_channel { + char *evt_log; + char *bookmark_name; + char bookmark_enabled; + char bookmark_filename[OS_MAXSTR]; +} os_channel; + + +void free_event(os_event *event) +{ + free(event->name); + free(event->source); + free(event->user); + free(event->domain); + free(event->computer); + free(event->message); + free(event->timestamp); +} + +char *convert_windows_string(LPCWSTR string) +{ + char *dest = NULL; + size_t size = 0; + int result = 0; + + if (string == NULL) { + return (NULL); + } + + /* Determine size required */ + size = WideCharToMultiByte(CP_UTF8, + WC_ERR_INVALID_CHARS, + string, + -1, + NULL, + 0, + NULL, + NULL); + + if (size == 0) { + log2file( + "%s: ERROR: Could not WideCharToMultiByte() when determining size which returned (%lu)", + ARGV0, + GetLastError()); + return (NULL); + } + + if ((dest = calloc(size, sizeof(char))) == NULL) { + log2file( + "%s: ERROR: Could not calloc() memory for WideCharToMultiByte() which returned [(%d)-(%s)]", + ARGV0, + errno, + strerror(errno) + ); + return (NULL); + } + + result = WideCharToMultiByte(CP_UTF8, + WC_ERR_INVALID_CHARS, + string, + -1, + dest, + size, + NULL, + NULL); + + if (result == 0) { + log2file( + "%s: ERROR: Could not WideCharToMultiByte() which returned (%lu)", + ARGV0, + GetLastError()); + free(dest); + return (NULL); + } + + return (dest); +} + +wchar_t *convert_unix_string(char *string) +{ + wchar_t *dest = NULL; + size_t size = 0; + int result = 0; + + if (string == NULL) { + return (NULL); + } + + /* Determine size required */ + size = MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, + string, + -1, + NULL, + 0); + + if (size == 0) { + log2file( + "%s: ERROR: Could not MultiByteToWideChar() when determining size which returned (%lu)", + ARGV0, + GetLastError()); + return (NULL); + } + + if ((dest = calloc(size, sizeof(wchar_t))) == NULL) { + log2file( + "%s: ERROR: Could not calloc() memory for MultiByteToWideChar() which returned [(%d)-(%s)]", + ARGV0, + errno, + strerror(errno)); + return (NULL); + } + + result = MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, + string, + -1, + dest, + size); + + if (result == 0) { + log2file( + "%s: ERROR: Could not MultiByteToWideChar() which returned (%lu)", + ARGV0, + GetLastError()); + free(dest); + return (NULL); + } + + return (dest); +} + +/* Filter escape characters */ + +char* filter_special_chars(const char *string) { + int i, j = 0; + int n = strlen(string); + char *filtered = malloc(n + 1); + + if (!filtered) + return NULL; + + for (i = 0; i <= n; i++) + filtered[j++] = (string[i] == '\\') ? string[++i] : string[i]; + + return filtered; +} + +char *get_property_value(PEVT_VARIANT value) +{ + if (value->Type == EvtVarTypeNull) { + return (NULL); + } + + return (convert_windows_string(value->StringVal)); +} + +int get_username_and_domain(os_event *event) +{ + int result = 0; + int status = 0; + DWORD user_length = 0; + DWORD domain_length = 0; + SID_NAME_USE account_type; + LPTSTR StringSid = NULL; + + /* Try to convert SID to a string. This isn't necessary to make + * things work but it is nice to have for error and debug logging. + */ + if (!ConvertSidToStringSid(event->uid, &StringSid)) { + debug1( + "%s: WARN: Could not convert SID to string which returned (%lu)", + ARGV0, + GetLastError()); + } + + debug1("%s: DEBUG: Performing a LookupAccountSid() on (%s)", + ARGV0, + StringSid ? StringSid : "unknown"); + + /* Make initial call to get buffer size */ + result = LookupAccountSid(NULL, + event->uid, + NULL, + &user_length, + NULL, + &domain_length, + &account_type); + + if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + /* Not having a user can be normal */ + goto cleanup; + } + + if ((event->user = calloc(user_length, sizeof(char))) == NULL) { + log2file( + "%s: ERROR: Could not lookup SID (%s) due to calloc() failure on user which returned [(%d)-(%s)]", + ARGV0, + StringSid ? StringSid : "unknown", + errno, + strerror(errno)); + goto cleanup; + } + + if ((event->domain = calloc(domain_length, sizeof(char))) == NULL) { + log2file( + "%s: ERROR: Could not lookup SID (%s) due to calloc() failure on domain which returned [(%d)-(%s)]", + ARGV0, + StringSid ? StringSid : "unknown", + errno, + strerror(errno)); + goto cleanup; + } + + result = LookupAccountSid(NULL, + event->uid, + event->user, + &user_length, + event->domain, + &domain_length, + &account_type); + if (result == FALSE) { + log2file( + "%s: ERROR: Could not LookupAccountSid() for (%s) which returned (%lu)", + ARGV0, + StringSid ? StringSid : "unknown", + GetLastError()); + goto cleanup; + } + + /* Success */ + status = 1; + +cleanup: + if (status == 0) { + free(event->user); + free(event->domain); + + event->user = NULL; + event->domain = NULL; + } + + if (StringSid) { + LocalFree(StringSid); + } + + return (status); +} + +char *get_message(EVT_HANDLE evt, LPCWSTR provider_name, DWORD flags) +{ + char *message = NULL; + EVT_HANDLE publisher = NULL; + DWORD size = 0; + wchar_t *buffer = NULL; + int result = 0; + + publisher = EvtOpenPublisherMetadata(NULL, + provider_name, + NULL, + 0, + 0); + if (publisher == NULL) { + log2file( + "%s: ERROR: Could not EvtOpenPublisherMetadata() with flags (%lu) which returned (%lu)", + ARGV0, + flags, + GetLastError()); + goto cleanup; + } + + /* Make initial call to determine buffer size */ + result = EvtFormatMessage(publisher, + evt, + 0, + 0, + NULL, + flags, + 0, + NULL, + &size); + if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + log2file( + "%s: ERROR: Could not EvtFormatMessage() to determine buffer size with flags (%lu) which returned (%lu)", + ARGV0, + flags, + GetLastError()); + goto cleanup; + } + + if ((buffer = calloc(size, sizeof(wchar_t))) == NULL) { + log2file( + "%s: ERROR: Could not calloc() memory which returned [(%d)-(%s)]", + ARGV0, + errno, + strerror(errno)); + goto cleanup; + } + + result = EvtFormatMessage(publisher, + evt, + 0, + 0, + NULL, + flags, + size, + buffer, + &size); + if (result == FALSE) { + log2file( + "%s: ERROR: Could not EvtFormatMessage() with flags (%lu) which returned (%lu)", + ARGV0, + flags, + GetLastError()); + goto cleanup; + } + + message = convert_windows_string(buffer); + +cleanup: + free(buffer); + + if (publisher != NULL) { + EvtClose(publisher); + } + + return (message); +} + +/* Read an existing bookmark (if one exists) */ +EVT_HANDLE read_bookmark(os_channel *channel) +{ + EVT_HANDLE bookmark = NULL; + size_t size = 0; + FILE *fp = NULL; + wchar_t bookmark_xml[OS_MAXSTR]; + + /* If we have a stored bookmark, start from it */ + if ((fp = fopen(channel->bookmark_filename, "r")) == NULL) { + /* Check if the error was not because the + * file did not exist which should be logged + */ + if (errno != ENOENT) { + log2file( + "%s: ERROR: Could not fopen() existing bookmark (%s) for (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + errno, + strerror(errno)); + } + return (NULL); + } + + size = fread(bookmark_xml, sizeof(wchar_t), OS_MAXSTR, fp); + if (ferror(fp)) { + log2file( + "%s: ERROR: Could not fread() bookmark (%s) for (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + errno, + strerror(errno)); + fclose(fp); + return (NULL); + } + + fclose(fp); + + /* Make sure bookmark data was read */ + if (size == 0) { + return (NULL); + } + + /* Make sure bookmark is terminated properly */ + bookmark_xml[size] = L'\0'; + + /* Create bookmark from saved XML */ + if ((bookmark = EvtCreateBookmark(bookmark_xml)) == NULL) { + log2file( + "%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + GetLastError()); + return (NULL); + } + + return (bookmark); +} + +/* Update the log position of a bookmark */ +int update_bookmark(EVT_HANDLE evt, os_channel *channel) +{ + DWORD size = 0; + DWORD count = 0; + wchar_t *buffer = NULL; + int result = 0; + int status = 0; + int clean_tmp = 0; + EVT_HANDLE bookmark = NULL; + FILE *fp = NULL; + char tmp_file[OS_MAXSTR]; + + /* Create temporary bookmark file name */ + snprintf(tmp_file, + sizeof(tmp_file), + "%s/%s-XXXXXX", + TMP_DIR, + channel->bookmark_name); + + if ((bookmark = EvtCreateBookmark(NULL)) == NULL) { + log2file( + "%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + if (!EvtUpdateBookmark(bookmark, evt)) { + log2file( + "%s: ERROR: Could not EvtUpdateBookmark() bookmark (%s) for (%s) which returned (%lu)", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + /* Make initial call to determine buffer size */ + result = EvtRender(NULL, + bookmark, + EvtRenderBookmark, + 0, + NULL, + &size, + &count); + if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + log2file( + "%s: ERROR: Could not EvtRender() to get buffer size to update bookmark (%s) for (%s) which returned (%lu)", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + if ((buffer = calloc(size, sizeof(char))) == NULL) { + log2file( + "%s: ERROR: Could not calloc() memory to save bookmark (%s) for (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->bookmark_filename, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + if (!EvtRender(NULL, + bookmark, + EvtRenderBookmark, + size, + buffer, + &size, + &count)) { + log2file( + "%s: ERROR: Could not EvtRender() bookmark (%s) for (%s) which returned (%lu)", + ARGV0, channel->bookmark_filename, channel->evt_log, + GetLastError()); + goto cleanup; + } + + if (mkstemp_ex(tmp_file)) { + log2file( + "%s: ERROR: Could not mkstemp_ex() temporary bookmark (%s) for (%s)", + ARGV0, + tmp_file, + channel->evt_log); + goto cleanup; + } + + if ((fp = fopen(tmp_file, "w")) == NULL) { + log2file( + "%s: ERROR: Could not fopen() temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]", + ARGV0, + tmp_file, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + /* Help to determine whether or not temporary file needs to be removed when + * function cleans up after itself + */ + clean_tmp = 1; + + if ((fwrite(buffer, 1, size, fp)) < size) { + log2file( + "%s: ERROR: Could not fwrite() to temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]", + ARGV0, + tmp_file, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + fclose(fp); + + if (rename_ex(tmp_file, channel->bookmark_filename)) { + log2file( + "%s: ERROR: Could not rename_ex() temporary bookmark (%s) to (%s) for (%s)", + ARGV0, + tmp_file, + channel->bookmark_filename, + channel->evt_log); + goto cleanup; + } + + /* Success */ + status = 1; + +cleanup: + free(buffer); + + if (bookmark != NULL) { + EvtClose(bookmark); + } + + if (fp) { + fclose(fp); + } + + if (status == 0 && clean_tmp == 1 && unlink(tmp_file)) { + log2file(DELETE_ERROR, + ARGV0, + tmp_file, + errno, + strerror(errno)); + } + + return (status); +} + +/* Format Timestamp from EventLog */ +char *WinEvtTimeToString(ULONGLONG ulongTime) +{ + SYSTEMTIME sysTime; + FILETIME fTime, lfTime; + ULARGE_INTEGER ulargeTime; + struct tm tm_struct; + char *timestamp = NULL; + int size = 80; + + if ((timestamp = malloc(size)) == NULL) { + log2file( + "%s: ERROR: Could not malloc() memory to convert timestamp which returned [(%d)-(%s)]", + ARGV0, + errno, + strerror(errno)); + goto cleanup; + } + + /* Zero out structure */ + memset(&tm_struct, 0, sizeof(tm_struct)); + + /* Convert from ULONGLONG to usable FILETIME value */ + ulargeTime.QuadPart = ulongTime; + + fTime.dwLowDateTime = ulargeTime.LowPart; + fTime.dwHighDateTime = ulargeTime.HighPart; + + /* Adjust time value to reflect current timezone then convert to a + * SYSTEMTIME + */ + if (FileTimeToLocalFileTime(&fTime, &lfTime) == 0) { + log2file( + "%s: ERROR: Could not FileTimeToLocalFileTime() to convert timestamp which returned (%lu)", + ARGV0, + GetLastError()); + goto cleanup; + } + + if (FileTimeToSystemTime(&lfTime, &sysTime) == 0) { + log2file( + "%s: ERROR: Could not FileTimeToSystemTime() to convert timestamp which returned (%lu)", + ARGV0, + GetLastError()); + goto cleanup; + } + + /* Convert SYSTEMTIME to tm */ + tm_struct.tm_year = sysTime.wYear - 1900; + tm_struct.tm_mon = sysTime.wMonth - 1; + tm_struct.tm_mday = sysTime.wDay; + tm_struct.tm_hour = sysTime.wHour; + tm_struct.tm_wday = sysTime.wDayOfWeek; + tm_struct.tm_min = sysTime.wMinute; + tm_struct.tm_sec = sysTime.wSecond; + + /* Format timestamp string */ + strftime(timestamp, size, "%Y %b %d %H:%M:%S", &tm_struct); + + return (timestamp); + +cleanup: + free(timestamp); + + return (NULL); +} + +void send_channel_event(EVT_HANDLE evt, os_channel *channel) +{ + DWORD buffer_length = 0; + PEVT_VARIANT properties_values = NULL; + DWORD count = 0; + EVT_HANDLE context = NULL; + os_event event = {0}; + char final_msg[OS_MAXSTR]; + int result = 0; + + if ((context = EvtCreateRenderContext(count, NULL, EvtRenderContextSystem)) == NULL) { + log2file( + "%s: ERROR: Could not EvtCreateRenderContext() for (%s) which returned (%lu)", + ARGV0, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + /* Make initial call to determine buffer size necessary */ + result = EvtRender(context, + evt, + EvtRenderEventValues, + 0, + NULL, + &buffer_length, + &count); + if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + log2file( + "%s: ERROR: Could not EvtRender() to determine buffer size for (%s) which returned (%lu)", + ARGV0, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + if ((properties_values = malloc(buffer_length)) == NULL) { + log2file( + "%s: ERROR: Could not malloc() memory to process event (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + if (!EvtRender(context, + evt, + EvtRenderEventValues, + buffer_length, + properties_values, + &buffer_length, + &count)) { + log2file( + "%s: ERROR: Could not EvtRender() for (%s) which returned (%lu)", + ARGV0, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + event.name = get_property_value(&properties_values[EvtSystemChannel]); + event.id = properties_values[EvtSystemEventID].UInt16Val; + event.source = get_property_value(&properties_values[EvtSystemProviderName]); + event.uid = properties_values[EvtSystemUserID].Type == EvtVarTypeNull ? NULL : properties_values[EvtSystemUserID].SidVal; + event.computer = get_property_value(&properties_values[EvtSystemComputer]); + event.time_created = properties_values[EvtSystemTimeCreated].FileTimeVal; + event.keywords = properties_values[EvtSystemKeywords].Type == EvtVarTypeNull ? 0 : properties_values[EvtSystemKeywords].UInt64Val; + event.level = properties_values[EvtSystemLevel].Type == EvtVarTypeNull ? -1 : properties_values[EvtSystemLevel].ByteVal; + + switch (event.level) { + case WINEVENT_CRITICAL: + event.category = "CRITICAL"; + break; + case WINEVENT_ERROR: + event.category = "ERROR"; + break; + case WINEVENT_WARNING: + event.category = "WARNING"; + break; + case WINEVENT_INFORMATION: + event.category = "INFORMATION"; + break; + case WINEVENT_VERBOSE: + event.category = "DEBUG"; + break; + case WINEVENT_AUDIT: + if (event.keywords & WINEVENT_AUDIT_FAILURE) { + event.category = "AUDIT_FAILURE"; + break; + } else if (event.keywords & WINEVENT_AUDIT_SUCCESS) { + event.category = "AUDIT_SUCCESS"; + break; + } + default: + event.category = "Unknown"; + break; + } + + if ((event.timestamp = WinEvtTimeToString(event.time_created)) == NULL) { + log2file( + "%s: ERROR: Could not convert timestamp for (%s)", + ARGV0, + channel->evt_log); + goto cleanup; + } + + /* Determine user and domain */ + get_username_and_domain(&event); + + /* Get event log message */ + if ((event.message = get_message(evt, properties_values[EvtSystemProviderName].StringVal, EvtFormatMessageEvent)) == NULL) { + log2file( + "%s: ERROR: Could not get message for (%s)", + ARGV0, + channel->evt_log); + } else { + /* Format message */ + win_format_event_string(event.message); + } + + snprintf( + final_msg, + sizeof(final_msg), + "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s", + event.timestamp, + event.name, + event.category, + event.id, + event.source && strlen(event.source) ? event.source : "no source", + event.user && strlen(event.user) ? event.user : "(no user)", + event.domain && strlen(event.domain) ? event.domain : "no domain", + event.computer && strlen(event.computer) ? event.computer : "no computer", + event.message && strlen(event.message) ? event.message : "(no message)" + ); + + if (SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + } + + if (channel->bookmark_enabled) { + update_bookmark(evt, channel); + } + +cleanup: + free(properties_values); + free_event(&event); + + if (context != NULL) { + EvtClose(context); + } + + return; +} + +DWORD WINAPI event_channel_callback(EVT_SUBSCRIBE_NOTIFY_ACTION action, os_channel *channel, EVT_HANDLE evt) +{ + if (action == EvtSubscribeActionDeliver) { + send_channel_event(evt, channel); + } + + return (0); +} + +void win_start_event_channel(char *evt_log, char future, char *query) +{ + wchar_t *wchannel = NULL; + wchar_t *wquery = NULL; + char *filtered_query = NULL; + os_channel *channel = NULL; + DWORD flags = EvtSubscribeToFutureEvents; + EVT_HANDLE bookmark = NULL; + EVT_HANDLE result = NULL; + int status = 0; + + if ((channel = calloc(1, sizeof(os_channel))) == NULL) { + log2file( + "%s: ERROR: Could not calloc() memory for channel to start reading (%s) which returned [(%d)-(%s)]", + ARGV0, + evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + channel->evt_log = evt_log; + + /* Create copy of event log string */ + if ((channel->bookmark_name = strdup(channel->evt_log)) == NULL) { + log2file( + "%s: ERROR: Could not strdup() event log name to start reading (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + /* Replace '/' with '_' */ + if (strchr(channel->bookmark_name, '/')) { + *(strrchr(channel->bookmark_name, '/')) = '_'; + } + + /* Convert evt_log to Windows string */ + if ((wchannel = convert_unix_string(channel->evt_log)) == NULL) { + log2file( + "%s: ERROR: Could not convert_unix_string() evt_log for (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + /* Convert query to Windows string */ + if (query) { + if ((filtered_query = filter_special_chars(query)) == NULL) { + log2file( + "%s: ERROR: Could not filter_special_chars() query for (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + + if ((wquery = convert_unix_string(filtered_query)) == NULL) { + log2file( + "%s: ERROR: Could not convert_unix_string() query for (%s) which returned [(%d)-(%s)]", + ARGV0, + channel->evt_log, + errno, + strerror(errno)); + goto cleanup; + } + } + + channel->bookmark_enabled = !future; + + if (channel->bookmark_enabled) { + /* Create bookmark file name */ + snprintf(channel->bookmark_filename, + sizeof(channel->bookmark_filename), "%s/%s", BOOKMARKS_DIR, + channel->bookmark_name); + + /* Try to read existing bookmark */ + if ((bookmark = read_bookmark(channel)) != NULL) { + flags = EvtSubscribeStartAfterBookmark; + } + } + + result = EvtSubscribe(NULL, + NULL, + wchannel, + wquery, + bookmark, + channel, + (EVT_SUBSCRIBE_CALLBACK)event_channel_callback, + flags); + + if (result == NULL && flags == EvtSubscribeStartAfterBookmark) { + result = EvtSubscribe(NULL, + NULL, + wchannel, + wquery, + NULL, + channel, + (EVT_SUBSCRIBE_CALLBACK)event_channel_callback, + EvtSubscribeToFutureEvents); + } + + if (result == NULL) { + log2file( + "%s: ERROR: Could not EvtSubscribe() for (%s) which returned (%lu)", + ARGV0, + channel->evt_log, + GetLastError()); + goto cleanup; + } + + /* Success */ + status = 1; + +cleanup: + free(wchannel); + free(wquery); + free(filtered_query); + + if (status == 0) { + free(channel->bookmark_name); + free(channel); + + if (result != NULL) { + EvtClose(result); + } + } + + if (bookmark != NULL) { + EvtClose(bookmark); + } + + return; +} + +#endif /* EVENTCHANNEL_SUPPORT */ +#endif /* WIN32 */ + diff --git a/src/monitord/compress_log.c b/src/monitord/compress_log.c new file mode 100644 index 000000000..9aed72db1 --- /dev/null +++ b/src/monitord/compress_log.c @@ -0,0 +1,80 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "monitord.h" + +#ifdef ZLIB_SYSTEM +#include +#else +#include "../external/zlib-1.2.11/zlib.h" +#endif + +/* gzip a log file */ +void OS_CompressLog(const char *logfile) +{ + FILE *log; + gzFile zlog; + + char logfileGZ[OS_FLSIZE + 1]; + int len, err; + + char buf[OS_MAXSTR + 1]; + + /* Do not compress */ + if (mond.compress == 0) { + return; + } + + /* Clear memory */ + memset(logfileGZ, '\0', OS_FLSIZE + 1); + memset(buf, '\0', OS_MAXSTR + 1); + + /* Set umask */ + umask(0027); + + /* Create the gzip file name */ + snprintf(logfileGZ, OS_FLSIZE, "%s.gz", logfile); + + /* Read log file */ + log = fopen(logfile, "r"); + if (!log) { + /* Do not warn in here, since the alert file may not exist */ + return; + } + + /* Open compressed file */ + zlog = gzopen(logfileGZ, "w"); + if (!zlog) { + fclose(log); + merror(FOPEN_ERROR, ARGV0, logfileGZ, errno, strerror(errno)); + return; + } + + for (;;) { + len = (int) fread(buf, 1, OS_MAXSTR, log); + if (len <= 0) { + break; + } + if (gzwrite(zlog, buf, (unsigned)len) != len) { + merror("%s: Compression error: %s", ARGV0, gzerror(zlog, &err)); + } + } + + fclose(log); + gzclose(zlog); + + /* Remove uncompressed file */ + if ((unlink(logfile)) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, logfile, strerror(errno)); + } + + return; +} + diff --git a/src/monitord/generate_reports.c b/src/monitord/generate_reports.c new file mode 100644 index 000000000..92f937b3f --- /dev/null +++ b/src/monitord/generate_reports.c @@ -0,0 +1,131 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "monitord.h" + +static const char *(monthss[]) = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + +void generate_reports(int cday, int cmon, int cyear) +{ + int s = 0; + + if (!mond.smtpserver) { + return; + } + + if (mond.reports) { + int twait = 0; + int childcount = 0; + + while (mond.reports[s]) { + pid_t pid; + if (mond.reports[s]->emailto == NULL) { + s++; + continue; + } + + /* We create a new process to run the report and send the email. + * To avoid crashing monitord if something goes wrong. + */ + pid = fork(); + if (pid < 0) { + merror("%s: ERROR: Fork failed. cause: %d - %s", ARGV0, errno, strerror(errno)); + s++; + continue; + } else if (pid == 0) { + char fname[256]; + char aname[256]; + fname[255] = '\0'; + aname[255] = '\0'; + snprintf(fname, 255, "/logs/.report-%d.log", getpid()); + + merror("%s: INFO: Starting daily reporting for '%s'", ARGV0, mond.reports[s]->title); + mond.reports[s]->r_filter.fp = fopen(fname, "w+"); + if (!mond.reports[s]->r_filter.fp) { + merror("%s: ERROR: Unable to open temporary reports file.", ARGV0); + s++; + continue; + } + + /* Open the log file */ + snprintf(aname, 255, "%s/%d/%s/openarmor-%s-%02d.log", + ALERTS, cyear, monthss[cmon], "alerts", cday); + os_strdup(aname, mond.reports[s]->r_filter.filename); + + /* Start report */ + os_ReportdStart(&mond.reports[s]->r_filter); + fflush(mond.reports[s]->r_filter.fp); + + fclose(mond.reports[s]->r_filter.fp); + + struct stat sb; + int sr; + if((sr = stat(fname, &sb)) < 0) { + merror("Cannot stat %s: %s", fname, strerror(errno)); + } + + if (sb.st_size == 0) { + merror("%s: INFO: Report '%s' empty.", ARGV0, mond.reports[s]->title); + } else if (OS_SendCustomEmail2(mond.reports[s]->emailto, + mond.reports[s]->title, + mond.smtpserver, + mond.emailfrom, + mond.emailidsname, + fname) + != 0) { + merror("%s: WARN: Unable to send report email.", ARGV0); + } + + if(unlink(fname) < 0) { + merror("%s: ERROR: Cannot unlink file %s: %s", ARGV0, fname, strerror(errno)); + } + + free(mond.reports[s]->r_filter.filename); + mond.reports[s]->r_filter.filename = NULL; + + exit(0); + } else { + /* Sleep between each report. Time is not important in here. */ + sleep(20); + childcount++; + } + + s++; + } + + while (childcount) { + int wp; + wp = waitpid((pid_t) - 1, NULL, WNOHANG); + if (wp < 0) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + } else if (wp == 0) { + /* If there is still any report left, sleep 5 and try again */ + sleep(5); + twait++; + + if (twait > 2) { + merror("%s: WARN: Report taking too long to complete. Waiting for it to finish...", ARGV0); + sleep(10); + if (twait > 10) { + merror("%s: WARN: Report took too long. Moving on...", ARGV0); + break; + } + } + } else { + childcount--; + } + } + } + return; +} + diff --git a/src/monitord/main.c b/src/monitord/main.c new file mode 100644 index 000000000..10ce31f11 --- /dev/null +++ b/src/monitord/main.c @@ -0,0 +1,217 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "config/config.h" +#include "monitord.h" +#include "os_net/os_net.h" + +/* Prototypes */ +static void help_monitord(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_monitord() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", USER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, test_config = 0, run_foreground = 0; + uid_t uid; + gid_t gid; + const char *dir = DEFAULTDIR; + const char *user = USER; + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + /* Initialize global variables */ + mond.a_queue = 0; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_monitord(); + break; + case 'd': + nowDebug(); + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_monitord(); + break; + } + + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + + /*Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Get config options */ + mond.day_wait = (unsigned short) getDefine_Int("monitord", "day_wait", 5, 240); + mond.compress = (short) getDefine_Int("monitord", "compress", 0, 1); + mond.sign = (short) getDefine_Int("monitord", "sign", 0, 1); + mond.monitor_agents = (short) getDefine_Int("monitord", "monitor_agents", 0, 1); + mond.notify_time = getDefine_Int("monitord", "notify_time", 60, 3600); + mond.agents = NULL; + mond.smtpserver = NULL; + mond.emailfrom = NULL; + mond.emailidsname = NULL; + + c = 0; + c |= CREPORTS; + if (ReadConfig(c, cfg, &mond, NULL) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* If we have any reports configured, read smtp/emailfrom */ + if (mond.reports) { + OS_XML xml; + char *tmpsmtp; + + const char *(xml_smtp[]) = {"openarmor_config", "global", "smtp_server", NULL}; + const char *(xml_from[]) = {"openarmor_config", "global", "email_from", NULL}; + const char *(xml_idsname[]) = {"openarmor_config", "global", "email_idsname", NULL}; + + if (OS_ReadXML(cfg, &xml) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + tmpsmtp = OS_GetOneContentforElement(&xml, xml_smtp); + mond.emailfrom = OS_GetOneContentforElement(&xml, xml_from); + mond.emailidsname = OS_GetOneContentforElement(&xml, xml_idsname); + + if (tmpsmtp && mond.emailfrom) { + mond.smtpserver = OS_GetHost(tmpsmtp, 5); + if (!mond.smtpserver) { + merror(INVALID_SMTP, ARGV0, tmpsmtp); + if (mond.emailfrom) { + free(mond.emailfrom); + } + mond.emailfrom = NULL; + merror("%s: Invalid SMTP server. Disabling email reports.", ARGV0); + } + } else { + if (tmpsmtp) { + free(tmpsmtp); + } + if (mond.emailfrom) { + free(mond.emailfrom); + } + + mond.emailfrom = NULL; + merror("%s: SMTP server or 'email from' missing. Disabling email reports.", ARGV0); + } + + OS_ClearXML(&xml); + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + if (!run_foreground) { + /* Going on daemon mode */ + nowDaemon(); + goDaemon(); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + nowChroot(); + + /* Change user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + debug1(CHROOT_MSG, ARGV0, dir); + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real daemon now */ + Monitord(); + exit(0); +} diff --git a/src/monitord/manage_files.c b/src/monitord/manage_files.c new file mode 100644 index 000000000..6e0dbac25 --- /dev/null +++ b/src/monitord/manage_files.c @@ -0,0 +1,186 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "monitord.h" + +static const char *(months[]) = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + +void manage_files(int cday, int cmon, int cyear) +{ + time_t tm_old; + struct tm *pp_old; + +#ifndef SOLARIS + struct tm p_old; +#endif + + char elogfile[OS_FLSIZE + 1]; + char elogfile_old[OS_FLSIZE + 1]; + + char alogfile[OS_FLSIZE + 1]; + char alogfile_old[OS_FLSIZE + 1]; + + char ajlogfile[OS_FLSIZE + 1]; + char ajlogfile_old[OS_FLSIZE + 1]; + + char flogfile[OS_FLSIZE + 1]; + char flogfile_old[OS_FLSIZE + 1]; + + char ejlogfile[OS_FLSIZE + 1]; + char ejlogfile_old[OS_FLSIZE + 1]; + + /* Get time from the day before (for log signing) */ + tm_old = time(NULL); + tm_old -= 93500; +#ifndef SOLARIS + pp_old = localtime_r(&tm_old, &p_old); +#else + pp_old = localtime(&tm_old); +#endif + + memset(elogfile, '\0', OS_FLSIZE + 1); + memset(elogfile_old, '\0', OS_FLSIZE + 1); + memset(alogfile, '\0', OS_FLSIZE + 1); + memset(alogfile_old, '\0', OS_FLSIZE + 1); + memset(ajlogfile, '\0', OS_FLSIZE + 1); + memset(ajlogfile_old, '\0', OS_FLSIZE + 1); + memset(flogfile, '\0', OS_FLSIZE + 1); + memset(flogfile_old, '\0', OS_FLSIZE + 1); + memset(ejlogfile, '\0', OS_FLSIZE + 1); + memset(ejlogfile_old, '\0', OS_FLSIZE + 1); + /* When the day changes, we wait up to day_wait before compressing the file */ + sleep(mond.day_wait); + + /* Event logfile */ + snprintf(elogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + EVENTS, + cyear, + months[cmon], + "archive", + cday); + /* Event log file old */ + snprintf(elogfile_old, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + EVENTS, + pp_old->tm_year + 1900, + months[pp_old->tm_mon], + "archive", + pp_old->tm_mday); + OS_SignLog(elogfile, elogfile_old, 0); + OS_CompressLog(elogfile); + + /* JSON Event logfile */ + snprintf(ejlogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.json", + EVENTS, + cyear, + months[cmon], + "archive", + cday); + /* JSON Event log file old */ + snprintf(ejlogfile_old, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.json", + EVENTS, + pp_old->tm_year + 1900, + months[pp_old->tm_mon], + "archive", + pp_old->tm_mday); + + int exists_json_events = 0; + FILE *fopnetestjsonevents; + + if ((fopnetestjsonevents = fopen(ejlogfile, "r"))) { + exists_json_events = 1; + fclose(fopnetestjsonevents); + } + + if ((fopnetestjsonevents = fopen(ejlogfile_old, "r"))) { + exists_json_events = 1; + fclose(fopnetestjsonevents); + } + + if (exists_json_events) { + /* Only if there is a file to operate on. */ + OS_SignLog(ejlogfile, ejlogfile_old, 0); + OS_CompressLog(ejlogfile); + } + + + /* alert logfile */ + snprintf(alogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + ALERTS, + cyear, + months[cmon], + "alerts", + cday); + /* alert logfile old */ + snprintf(alogfile_old, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + ALERTS, + pp_old->tm_year + 1900, + months[pp_old->tm_mon], + "alerts", + pp_old->tm_mday); + OS_SignLog(alogfile, alogfile_old, 1); + OS_CompressLog(alogfile); + + /* alert logfile */ + snprintf(ajlogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.json", + ALERTS, + cyear, + months[cmon], + "alerts", + cday); + /* alert logfile old */ + snprintf(ajlogfile_old, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.json", + ALERTS, + pp_old->tm_year + 1900, + months[pp_old->tm_mon], + "alerts", + pp_old->tm_mday); + + int exists = 0; + FILE *fopnetest; + + if ((fopnetest = fopen(ajlogfile, "r"))) { + exists = 1; + fclose(fopnetest); + } + + if ((fopnetest = fopen(ajlogfile_old, "r"))) { + exists = 1; + fclose(fopnetest); + } + + if (exists) { + /* Only if there is a file to operate on. */ + OS_SignLog(ajlogfile, ajlogfile_old, 1); + OS_CompressLog(ajlogfile); + } + + /* firewall events */ + snprintf(flogfile, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + FWLOGS, + cyear, + months[cmon], + "firewall", + cday); + /* firewall events old */ + snprintf(flogfile_old, OS_FLSIZE, "%s/%d/%s/openarmor-%s-%02d.log", + FWLOGS, + pp_old->tm_year + 1900, + months[pp_old->tm_mon], + "firewall", + pp_old->tm_mday); + OS_SignLog(flogfile, flogfile_old, 0); + OS_CompressLog(flogfile); + + return; +} + diff --git a/src/monitord/monitor_agents.c b/src/monitord/monitor_agents.c new file mode 100644 index 000000000..9b87a0c9a --- /dev/null +++ b/src/monitord/monitor_agents.c @@ -0,0 +1,62 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "monitord.h" +#include "read-agents.h" + + +void monitor_agents() +{ + char **cr_agents; + char **av_agents; + + av_agents = get_agents_with_timeout(GA_ACTIVE, mond.notify_time); + + /* No agent saved */ + if (!mond.agents) { + mond.agents = av_agents; + return; + } + + /* Check if any of the previously available agents are disconnected */ + cr_agents = mond.agents; + while (*cr_agents) { + int available = 0; + char **tmp_av; + + tmp_av = av_agents; + while (tmp_av && *tmp_av) { + if (strcmp(*cr_agents, *tmp_av) == 0) { + available = 1; + break; + } + tmp_av++; + } + + /* Agent disconnected */ + if (available == 0) { + char str[OS_SIZE_1024 + 1]; + + /* Send disconnected message */ + snprintf(str, OS_SIZE_1024 - 1, OS_AG_DISCON, *cr_agents); + if (SendMSG(mond.a_queue, str, ARGV0, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + } + } + + cr_agents++; + } + + /* Remove old agent list and add current one */ + free_agents(mond.agents); + mond.agents = av_agents; + return; +} diff --git a/src/monitord/monitord.c b/src/monitord/monitord.c new file mode 100644 index 000000000..9dbbf13ae --- /dev/null +++ b/src/monitord/monitord.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "monitord.h" + +/* Global variables */ +monitor_config mond; + + +void Monitord() +{ + time_t tm; + struct tm *p; + + int today = 0; + int thismonth = 0; + int thisyear = 0; + + char str[OS_SIZE_1024 + 1]; + + /* Wait a few seconds to settle */ + sleep(10); + + memset(str, '\0', OS_SIZE_1024 + 1); + + /* Get current time before starting */ + tm = time(NULL); + p = localtime(&tm); + + today = p->tm_mday; + thismonth = p->tm_mon; + thisyear = p->tm_year + 1900; + + /* Connect to the message queue or exit */ + if ((mond.a_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + + /* Send startup message */ + snprintf(str, OS_SIZE_1024 - 1, OS_AD_STARTED); + if (SendMSG(mond.a_queue, str, ARGV0, + LOCALFILE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + } + + /* Main monitor loop */ + while (1) { + tm = time(NULL); + p = localtime(&tm); + + /* Check for unavailable agents */ + if (mond.monitor_agents) { + monitor_agents(); + } + + /* Day changed, deal with log files */ + if (today != p->tm_mday) { + /* Generate reports */ + generate_reports(today, thismonth, thisyear); + + manage_files(today, thismonth, thisyear); + + today = p->tm_mday; + thismonth = p->tm_mon; + thisyear = p->tm_year + 1900; + } + + /* We only check every two minutes */ + sleep(120); + } +} + diff --git a/src/monitord/monitord.h b/src/monitord/monitord.h new file mode 100644 index 000000000..67b90b0ab --- /dev/null +++ b/src/monitord/monitord.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _MONITORD_H +#define _MONITORD_H + +#ifndef ARGV0 +#define ARGV0 "openarmor-monitord" +#endif + +#include "config/reports-config.h" + +/* Prototypes */ +void Monitord(void) __attribute__((noreturn)); +void manage_files(int cday, int cmon, int cyear); +void generate_reports(int cday, int cmon, int cyear); +void monitor_agents(void); +void OS_SignLog(const char *logfile, const char *logfile_old, int log_missing); +void OS_CompressLog(const char *logfile); + +int OS_SendCustomEmail2(char **to, char *subject, char *smtpserver, char *from, char *idsname, char *fname); + +/* Global variables */ +extern monitor_config mond; + +#endif + diff --git a/src/monitord/sendcustomemail.c b/src/monitord/sendcustomemail.c new file mode 100644 index 000000000..704b329f7 --- /dev/null +++ b/src/monitord/sendcustomemail.c @@ -0,0 +1,324 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Basic e-mailing operations */ + +#include "shared.h" +#include "os_net/os_net.h" + +/* Return codes (from SMTP server) */ +#define VALIDBANNER "220" +#define VALIDMAIL "250" +#define VALIDDATA "354" + +/* Default values used to connect */ +#define SMTP_DEFAULT_PORT "25" +#define HELOMSG "Helo notify.theopenarmor.org\r\n" +#define MAILFROM "Mail From: <%s>\r\n" +#define RCPTTO "Rcpt To: <%s>\r\n" +#define DATAMSG "DATA\r\n" +#define FROM "From: openarmor HIDS <%s>\r\n" +#define REPLYTO "Reply-To: openarmor HIDS <%s>\r\n" +#define TO "To: <%s>\r\n" +#define CC "Cc: <%s>\r\n" +#define SUBJECT "Subject: %s\r\n" +#define ENDHEADER "\r\n" +#define ENDDATA "\r\n.\r\n" +#define QUITMSG "QUIT\r\n" +#define XHEADER "X-IDS-openarmor: %s\r\n" + +/* Error messages - Can be translated */ +#define INTERNAL_ERROR "os_maild (1760): ERROR: Memory/configuration error" +#define BANNER_ERROR "os_sendmail(1762): WARN: Banner not received from server" +#define HELO_ERROR "os_sendmail(1763): WARN: Hello not accepted by server" +#define FROM_ERROR "os_sendmail(1764): WARN: Mail from not accepted by server" +#define TO_ERROR "os_sendmail(1765): WARN: RCPT TO not accepted by server - '%s'." +#define DATA_ERROR "os_sendmail(1766): WARN: DATA not accepted by server" +#define END_DATA_ERROR "os_sendmail(1767): WARN: End of DATA not accepted by server" + +#define MAIL_DEBUG_FLAG 0 +#define MAIL_DEBUG(x,y,z) if(MAIL_DEBUG_FLAG) merror(x,y,z) + + +int OS_SendCustomEmail2(char **to, char *subject, char *smtpserver, char *from, char *replyto, char *idsname, __attribute__((unused)) char *fname) +{ + FILE *sendmail = NULL; + int socket = -1, i = 0; + char *msg; + char snd_msg[128]; + char buffer[2049]; + + buffer[2048] = '\0'; + + if (smtpserver[0] == '/') { + sendmail = popen(smtpserver, "w"); + if (!sendmail) { + return (OS_INVALID); + } + } else { + /* Connect to the SMTP server */ + socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver); + if (socket < 0) { + return (socket); + } + + /* Receive the banner */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { + merror(BANNER_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); + free(msg); + + /* Send HELO message */ + OS_SendTCP(socket, HELOMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + if (msg) { + /* In some cases (with virus scans in the middle) + * we may get two banners. Check for that in here. + */ + if (OS_Match(VALIDBANNER, msg)) { + free(msg); + + /* Try again */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + } else { + merror("%s:%s", HELO_ERROR, msg); + free(msg); + close(socket); + return (OS_INVALID); + } + } else { + merror("%s:%s", HELO_ERROR, "null"); + close(socket); + return (OS_INVALID); + } + } + + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); + free(msg); + + /* Build "Mail from" msg */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, MAILFROM, from); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(FROM_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + /* Build "RCPT TO" msg */ + while (to[i]) { + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, to[i]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, to[i]); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + i++; + } + + /* Send the "DATA" msg */ + OS_SendTCP(socket, DATAMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { + merror(DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); + free(msg); + } + + /* Build "From" and "To" in the e-mail header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, to[0]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, FROM, from); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + if (replyto) { + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, REPLYTO, replyto); + if(sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + } + + /* Add CCs */ + if (to[1]) { + i = 1; + while (1) { + if (to[i] == NULL) { + break; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, to[i]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + i++; + } + } + + /* Send date */ + memset(snd_msg, '\0', 128); + time_t tm; + tm = time(NULL); + const struct tm *p; + p = localtime(&tm); + + /* Solaris doesn't have the "%z", so we set the timezone to 0 */ +#ifdef SOLARIS + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n", p); +#else + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); +#endif + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + if (idsname) { + /* Send server name header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, XHEADER, idsname); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + } + + /* Send subject */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, SUBJECT, subject); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + fprintf(sendmail, ENDHEADER); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + } + + + char fname2[256]; + fname2[255] = '\0'; + snprintf(fname2, 255, "/logs/.report-%d.log", getpid()); + + /* Send body */ + FILE *fp; + fp = fopen(fname2, "r"); + if(!fp) { + merror("%s: ERROR: Cannot open %s: %s", __local_name, fname2, strerror(errno)); + if(socket >= 0) { + close(socket); + } + if(sendmail) { + pclose(sendmail); + } + return(1); + } + + + while (fgets(buffer, 2048, fp) != NULL) { + if (sendmail) { + fprintf(sendmail, "%s", buffer); + } else { + OS_SendTCP(socket, buffer); + } + } + fclose(fp); + + if (sendmail) { + if (pclose(sendmail) == -1) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + } + } else { + /* Send end of data \r\n.\r\n */ + OS_SendTCP(socket, ENDDATA); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + /* Check msg, since it may be null */ + if (msg) { + free(msg); + } + + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + if (msg) { + free(msg); + } + + close(socket); + } + + memset_secure(snd_msg, '\0', 128); + return (0); +} + diff --git a/src/monitord/sign_log.c b/src/monitord/sign_log.c new file mode 100644 index 000000000..0aaec2903 --- /dev/null +++ b/src/monitord/sign_log.c @@ -0,0 +1,90 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/sha1/sha1_op.h" +#include "monitord.h" + + +/* Sign a log file */ +void OS_SignLog(const char *logfile, const char *logfile_old, int log_missing) +{ + os_md5 mf_sum; + os_md5 mf_sum_old; + + os_sha1 sf_sum; + os_sha1 sf_sum_old; + + char logfilesum[OS_FLSIZE + 1]; + char logfilesum_old[OS_FLSIZE + 1]; + + FILE *fp; + + /* Clear the memory */ + memset(logfilesum, '\0', OS_FLSIZE + 1); + memset(logfilesum_old, '\0', OS_FLSIZE + 1); + + /* Set umask */ + umask(0027); + + /* Create the checksum file names */ + snprintf(logfilesum, OS_FLSIZE, "%s.sum", logfile); + snprintf(logfilesum_old, OS_FLSIZE, "%s.sum", logfile_old); + + /* Generate MD5 of the old file */ + if (OS_MD5_File(logfilesum_old, mf_sum_old, OS_TEXT) < 0) { + merror("%s: No previous md5 checksum found: '%s'. " + "Starting over.", ARGV0, logfilesum_old); + strncpy(mf_sum_old, "none", 6); + } + + /* Generate SHA-1 of the old file */ + if (OS_SHA1_File(logfilesum_old, sf_sum_old, OS_TEXT) < 0) { + merror("%s: No previous sha1 checksum found: '%s'. " + "Starting over.", ARGV0, logfilesum_old); + strncpy(sf_sum_old, "none", 6); + } + + /* Generate MD5 of the current file */ + if (OS_MD5_File(logfile, mf_sum, OS_TEXT) < 0) { + if (log_missing) { + merror("%s: File '%s' not found. MD5 checksum skipped.", + ARGV0, logfile); + } + strncpy(mf_sum, "none", 6); + } + + /* Generate SHA-1 of the current file */ + if (OS_SHA1_File(logfile, sf_sum, OS_TEXT) < 0) { + if (log_missing) { + merror("%s: File '%s' not found. SHA1 checksum skipped.", + ARGV0, logfile); + } + strncpy(sf_sum, "none", 6); + } + + fp = fopen(logfilesum, "w"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, logfilesum, errno, strerror(errno)); + return; + } + + fprintf(fp, "Current checksum:\n"); + fprintf(fp, "MD5 (%s) = %s\n", logfile, mf_sum); + fprintf(fp, "SHA1 (%s) = %s\n\n", logfile, sf_sum); + + fprintf(fp, "Chained checksum:\n"); + fprintf(fp, "MD5 (%s) = %s\n", logfilesum_old, mf_sum_old); + fprintf(fp, "SHA1 (%s) = %s\n\n", logfilesum_old, sf_sum_old); + fclose(fp); + + return; +} + diff --git a/src/os_auth/auth.h b/src/os_auth/auth.h new file mode 100644 index 000000000..51c092783 --- /dev/null +++ b/src/os_auth/auth.h @@ -0,0 +1,59 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifndef _AUTHD_H +#define _AUTHD_H + +#ifndef ARGV0 +#define ARGV0 "openarmor-authd" +#endif + +#include +#include +#include + +#ifdef LIBOPENSSL_ENABLED + +#include +#include +#include + +#include "os_net/os_net.h" +#include "addagent/manage_agents.h" + +extern BIO *bio_err; +#define KEYFILE "/etc/sslmanager.key" +#define CERTFILE "/etc/sslmanager.cert" +#define DEFAULT_CIPHERS "HIGH:!ADH:!EXP:!MD5:!RC4:!3DES:!CAMELLIA:@STRENGTH" +#define DEFAULT_PORT "1515" + +SSL_CTX *os_ssl_keys(int is_server, const char *os_dir, const char *ciphers, const char *cert, const char *key, const char *ca_cert); +SSL_CTX *get_ssl_context(const char *ciphers); +int load_cert_and_key(SSL_CTX *ctx, const char *cert, const char *key); +int load_ca_cert(SSL_CTX *ctx, const char *ca_cert); +int verify_callback(int ok, X509_STORE_CTX *store); + +#endif /* LIBOPENSSL_ENABLED */ +#endif /* _AUTHD_H */ + diff --git a/src/os_auth/check_cert.c b/src/os_auth/check_cert.c new file mode 100644 index 000000000..365eeceea --- /dev/null +++ b/src/os_auth/check_cert.c @@ -0,0 +1,327 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifdef LIBOPENSSL_ENABLED + +#include +#include +#include +#include + +#include "shared.h" +#include "check_cert.h" + + +/* Compare the manager's name or IP address given on the command line with the + * subject alternative names and common names present in a received certificate. + * This could be replaced with X509_check_host() in future but this is only + * available in openssl 1.0.2. + */ +int check_x509_cert(const SSL *ssl, const char *manager) +{ + X509 *cert = NULL; + int verified = VERIFY_FALSE; + + if (!(cert = SSL_get_peer_certificate(ssl))) { + goto CERT_CHECK_ERROR; + } + + /* Check for a matching subject alt name entry in the extensions first and + * if no match is found there then check the subject CN. + */ + debug1("%s: DEBUG: Checking certificate's subject alternative names.", ARGV0); + if ((verified = check_subject_alt_names(cert, manager)) == VERIFY_ERROR) { + goto CERT_CHECK_ERROR; + } + + if (verified == VERIFY_FALSE) { + debug1("%s: DEBUG: No matching subject alternative names found. Checking common name.", ARGV0); + if ((verified = check_subject_cn(cert, manager)) == VERIFY_ERROR) { + goto CERT_CHECK_ERROR; + } + } + + X509_free(cert); + + return verified; + +CERT_CHECK_ERROR: + if (cert) { + X509_free(cert); + } + + return VERIFY_ERROR; +} + +/* Loop through all the subject_alt_name entries until we find a match or + * an error occurs. Only entries containing a normal domain name or IP + * address are considered. + */ +int check_subject_alt_names(X509 *cert, const char *manager) +{ + GENERAL_NAMES *names = NULL; + int result = VERIFY_FALSE; + int i = 0; + + if ((names = (GENERAL_NAMES *) X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL))) { + for (i = 0; i < sk_GENERAL_NAME_num(names) && result == VERIFY_FALSE; i++) { + GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i); + + if (name->type == GEN_DNS) { + result = check_hostname(name->d.dNSName, manager); + } else if (name->type == GEN_IPADD) { + result = check_ipaddr(name->d.iPAddress, manager); + } + } + + GENERAL_NAMES_free(names); + } + + return result; +} + +/* Loop through all the common name entries until we find a match or + * an error occurs. + */ +int check_subject_cn(X509 *cert, const char *manager) +{ + X509_NAME *name = NULL; + int result = VERIFY_FALSE; + int i = 0; + + if ((name = X509_get_subject_name(cert))) { + while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0 && result == VERIFY_FALSE) { + X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i); + result = check_hostname(X509_NAME_ENTRY_get_data(ne), manager); + } + } + + return result; +} + +/* Determine whether a string found in a subject alt name or common name + * field matches the manager's name specified on the command line. The + * domain name from the certificate and the domain name from the command + * line are broken down into a sequence of labels and each label is validated + * and compared. Matching is case insensitive and basic wildcard matching + * is supported. + */ +int check_hostname(ASN1_STRING *cert_astr, const char *manager) +{ + label c_labels[DNS_MAX_LABELS]; + label m_labels[DNS_MAX_LABELS]; + int c_label_num = 0; + int m_label_num = 0; + int wildcard_cert = 0; + int i = 0; + char *cert_cstr = NULL; + + if (!(cert_cstr = asn1_to_cstr(cert_astr))) { + return VERIFY_FALSE; + } + + /* Convert domain names to arrays of labels separated by '.' + */ + c_label_num = label_array(cert_cstr, c_labels); + m_label_num = label_array(manager, m_labels); + free(cert_cstr); + + /* Check that we have an appropriate number of labels and that the name + * from the certificate and the name given on the command line have + * the same number of labels. + */ + if (m_label_num <= 0 || c_label_num <= 0) { + return VERIFY_FALSE; + } + + if (m_label_num != c_label_num) { + return VERIFY_FALSE; + } + + /* Wildcards are accepted in the first label only. Partial wildcard + * matching is not supported. + */ + if (label_valid(&m_labels[0]) && !strcmp(c_labels[0].text, "*")) { + wildcard_cert = 1; + } + + /* Validate and match all labels. + */ + for (i = wildcard_cert; i < m_label_num; i++) { + if (!label_valid(&m_labels[i])) { + return VERIFY_FALSE; + } + + if (!label_match(&m_labels[i], &c_labels[i])) { + return VERIFY_FALSE; + } + } + + return VERIFY_TRUE; +} + +/* Determine whether a string found in a subject alt name or common name + * field matches the manager's IP address specified on the command line. + */ +int check_ipaddr(const ASN1_STRING *cert_astr, const char *manager) +{ + struct sockaddr_in iptest; + struct sockaddr_in6 iptest6; + + memset(&iptest, 0, sizeof(iptest)); + memset(&iptest6, 0, sizeof(iptest6)); + + if (inet_pton(AF_INET, manager, &iptest.sin_addr) == 1) { + if (cert_astr->length == 4 && !memcmp(cert_astr->data, (const void *)&iptest.sin_addr, 4)) { + return VERIFY_TRUE; + } + } else if (inet_pton(AF_INET6, manager, &iptest6.sin6_addr) == 1) { + if (cert_astr->length == 16 && !memcmp(cert_astr->data, (const void *)&iptest6.sin6_addr, 16)) { + return VERIFY_TRUE; + } + } + + return VERIFY_FALSE; +} + +/* Separate a domain name into a sequence of labels and return the number + * of labels found. strtok() is not used as we want to detect labels with + * length zero. + */ +int label_array(const char *domain_name, label result[DNS_MAX_LABELS]) +{ + int label_count = 0; + const char *label_start = domain_name; + const char *label_end = domain_name; + + do { + if (label_count == DNS_MAX_LABELS) { + return VERIFY_FALSE; + } + + if (*label_end == '.' || *label_end == '\0') { + label *new_label = &result[label_count]; + + if ((new_label->len = (size_t)(label_end - label_start)) > DNS_MAX_LABEL_LEN) { + return VERIFY_FALSE; + } + + strncpy(new_label->text, label_start, new_label->len); + new_label->text[new_label->len] = '\0'; + + label_start = label_end + 1; + label_count++; + } + } while (*label_end++ != '\0'); + + if (label_count == 0) { + return VERIFY_FALSE; + } + + /* If the length of the last label is zero ignore it. This is the only + * valid position for a label of length zero which occurs when a FQDN + * is given. + */ + return (result[label_count - 1].len > 0) ? label_count : label_count - 1; +} + +/* Validate a label according to the guidelines in RFC 1035. This could + * be relaxed if necessary. + */ +int label_valid(const label *l) +{ + size_t i; + + if (l->len <= 0 || l->len > DNS_MAX_LABEL_LEN) { + return VERIFY_FALSE; + } + + if (!isalpha(l->text[0]) || !isalnum(l->text[l->len - 1])) { + return VERIFY_FALSE; + } + + for (i = 0; i < l->len; i++) { + if (!isalnum(l->text[i]) && l->text[i] != '-') { + return VERIFY_FALSE; + } + } + + return VERIFY_TRUE; +} + +/* Compare two labels and determine whether they match. + */ +int label_match(const label *label1, const label *label2) +{ + size_t i; + + if (label1->len != label2->len) { + return VERIFY_FALSE; + } + + for (i = 0; i < label1->len; i++) { + if (tolower(label1->text[i]) != tolower(label2->text[i])) { + return VERIFY_FALSE; + } + } + + return VERIFY_TRUE; +} + +/* Convert an ASN1 string which may not be null terminated into a + * standard null terminated string. Also check for embedded null + * characters. + */ +char *asn1_to_cstr(ASN1_STRING *astr) +{ + unsigned int astr_len = 0; + char *tmp = NULL; + char *cstr = NULL; + + if (!(astr_len = (unsigned int) ASN1_STRING_length(astr))) { + return NULL; + } + + if (!(tmp = (char *)ASN1_STRING_data(astr))) { + return NULL; + } + + /* Verify that the string does not contain embedded null characters. + */ + if (memchr(tmp, '\0', astr_len)) { + return NULL; + } + + if ((cstr = (char *) malloc(astr_len + 1)) == NULL) { + return NULL; + } + + memcpy(cstr, tmp, astr_len); + cstr[astr_len] = '\0'; + + return cstr; +} + +#endif /* LIBOPENSSL_ENABLED */ + diff --git a/src/os_auth/check_cert.h b/src/os_auth/check_cert.h new file mode 100644 index 000000000..5a21ddd69 --- /dev/null +++ b/src/os_auth/check_cert.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifndef _CHECK_CERT_H +#define _CHECK_CERT_H + +#ifdef LIBOPENSSL_ENABLED + +#include +#include + +#define VERIFY_TRUE 1 +#define VERIFY_FALSE 0 +#define VERIFY_ERROR -1 + +#define DNS_MAX_LABELS 127 +#define DNS_MAX_LABEL_LEN 63 + +typedef struct label { + char text[DNS_MAX_LABEL_LEN + 1]; + size_t len; +} +label; + +int check_x509_cert(const SSL *ssl, const char *manager); +int check_subject_alt_names(X509 *cert, const char *manager); +int check_subject_cn(X509 *cert, const char *manager); +int check_hostname(ASN1_STRING *cert_astr, const char *manager); +int check_ipaddr(const ASN1_STRING *cert_astr, const char *manager); +int label_array(const char *domain_name, label result[DNS_MAX_LABELS]); +int label_valid(const label *label); +int label_match(const label *label1, const label *label2); +char *asn1_to_cstr(ASN1_STRING *astr); + +#endif /* LIBOPENSSL_ENABLED */ +#endif /* _CHECK_CERT_H */ + diff --git a/src/os_auth/main-client.c b/src/os_auth/main-client.c new file mode 100644 index 000000000..05051f554 --- /dev/null +++ b/src/os_auth/main-client.c @@ -0,0 +1,404 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#include +#include +#include "shared.h" +#include "check_cert.h" + +#ifndef LIBOPENSSL_ENABLED + +int main() +{ + printf("ERROR: Not compiled. Missing OpenSSL support.\n"); + exit(0); +} + +#else + +#include +#include "auth.h" + +static void help_agent_auth(void) __attribute__((noreturn)); + +/* Print help statement */ +static void help_agent_auth() +{ + print_header(); + print_out(" %s: -[Vhdt] [-g group] [-D dir] [-m IP address] [-p port] [-A name] [-c ciphers] [-v path] [-x path] [-k path]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" -m Manager IP address"); + print_out(" -p Manager port (default: %s)", DEFAULT_PORT); + print_out(" -A Agent name (default: hostname)"); + print_out(" -c SSL cipher list (default: %s)", DEFAULT_CIPHERS); + print_out(" -v Full path to CA certificate used to verify the server"); + print_out(" -x Full path to agent certificate"); + print_out(" -k Full path to agent key"); + print_out(" -P Authorization password file [default: /var/openarmor/etc/authd.pass"); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int key_added = 0; + int c; + int test_config = 0; + int authenticate = 0; +#ifndef WIN32 + gid_t gid = 0; +#endif + + int sock = 0, portnum, ret = 0; + char *port = DEFAULT_PORT; + char *ciphers = DEFAULT_CIPHERS; + const char *dir = DEFAULTDIR; + const char *group = GROUPGLOBAL; + char *authpass = NULL; + const char *manager = NULL; + const char *agentname = NULL; + const char *agent_cert = NULL; + const char *agent_key = NULL; + const char *ca_cert = NULL; + char lhostname[512 + 1]; + char buf[4096 + 1]; + SSL_CTX *ctx; + SSL *ssl; + BIO *sbio; + bio_err = 0; + buf[4096] = '\0'; + +#ifdef WIN32 + WSADATA wsaData; +#endif + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtg:m:p:A:c:v:x:k:D:P:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_agent_auth(); + break; + case 'd': + nowDebug(); + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + dir = optarg; + break; + case 't': + test_config = 1; + break; + case 'm': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + manager = optarg; + break; + case 'A': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + agentname = optarg; + break; + case 'p': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + portnum = atoi(optarg); + if (portnum <= 0 || portnum >= 65536) { + ErrorExit("%s: Invalid port: %s", ARGV0, optarg); + } + port = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + ciphers = optarg; + break; + case 'v': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + ca_cert = optarg; + break; + case 'x': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + agent_cert = optarg; + break; + case 'k': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + agent_key = optarg; + break; + case 'P': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + authpass = optarg; + authenticate++; + break; + default: + help_agent_auth(); + break; + } + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + +#ifndef WIN32 + /* Check if the user/group given are valid */ + gid = Privsep_GetGroup(group); + if (gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, "", group); + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } +#else + /* Initialize Windows socket stuff */ + if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { + ErrorExit("%s: WSAStartup() failed", ARGV0); + } +#endif /* WIN32 */ + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + if (agentname == NULL) { + lhostname[512] = '\0'; + if (gethostname(lhostname, 512 - 1) != 0) { + merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0); + exit(1); + } + agentname = lhostname; + } + + /* Start SSL */ + ctx = os_ssl_keys(0, dir, ciphers, agent_cert, agent_key, ca_cert); + if (!ctx) { + merror("%s: ERROR: SSL error. Exiting.", ARGV0); + exit(1); + } + + if (!manager) { + merror("%s: ERROR: Manager IP not set.", ARGV0); + exit(1); + } + + /* Checking if there is a custom password file */ + if (authpass != NULL && authenticate > 0) { + FILE *fp; + fp = fopen(authpass, "r"); + if(!fp) { + fprintf(stderr, "Cannot open %s: %s\n", authpass, strerror(errno)); + exit(1); + } + buf[0] = '\0'; + + if (fp) { + buf[4096] = '\0'; + fgets(buf, 4095, fp); + + if (strlen(buf) > 2) { + authpass = strndup(buf, 32); + if(!authpass) { + fprintf(stderr, "Could not set the authpass: %s", strerror(errno)); + exit(1); + } + } + + fclose(fp); + printf("INFO: Using specified password.\n"); + } + } + if (!authpass) { + printf("WARN: No authentication password provided. Insecure mode started.\n"); + } + + /* Connect via TCP */ + sock = OS_ConnectTCP(port, manager); + if (sock <= 0) { + merror("%s: Unable to connect to %s:%s", ARGV0, manager, port); + exit(1); + } + + /* Connect the SSL socket */ + ssl = SSL_new(ctx); + sbio = BIO_new_socket(sock, BIO_NOCLOSE); + SSL_set_bio(ssl, sbio, sbio); + + ret = SSL_connect(ssl); + if (ret <= 0) { + ERR_print_errors_fp(stderr); + merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret); + exit(1); + } + + printf("INFO: Connected to %s:%s\n", manager, port); + + /* Additional verification of the manager's certificate if a hostname + * rather than an IP address is given on the command line. Could change + * this to do the additional validation on IP addresses as well if needed. + */ + if (ca_cert) { + printf("INFO: Verifying manager's certificate\n"); + if (check_x509_cert(ssl, manager) != VERIFY_TRUE) { + debug1("%s: DEBUG: Unable to verify server certificate.", ARGV0); + exit(1); + } + } + + printf("INFO: Using agent name as: %s\n", agentname); + + memset(buf, 0, sizeof(buf)); + if (authpass) { + snprintf(buf, 2048, "openarmor PASS: %s openarmor A:'%s'\n", authpass, agentname); + } + else { + snprintf(buf, 2048, "openarmor A:'%s'\n", agentname); + } + + ret = SSL_write(ssl, buf, strlen(buf)); + if (ret < 0) { + printf("SSL write error (unable to send message.)\n"); + ERR_print_errors_fp(stderr); + exit(1); + } + + printf("INFO: Send request to manager. Waiting for reply.\n"); + + while (1) { + ret = SSL_read(ssl, buf, sizeof(buf) - 1); + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + buf[ret] = '\0'; + if (strncmp(buf, "ERROR", 5) == 0) { + char *tmpstr; + tmpstr = strchr(buf, '\n'); + if (tmpstr) { + *tmpstr = '\0'; + } + printf("%s (from manager)\n", buf); + } else if (strncmp(buf, "openarmor K:'", 9) == 0) { + char *key; + char *tmpstr; + char **entry; + printf("INFO: Received response with agent key\n"); + + key = buf; + key += 9; + tmpstr = strchr(key, '\''); + if (!tmpstr) { + printf("ERROR: Invalid key received. Closing connection.\n"); + exit(1); + } + *tmpstr = '\0'; + entry = OS_StrBreak(' ', key, 4); + if (!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) || + !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3])) { + printf("ERROR: Invalid key received (2). Closing connection.\n"); + exit(1); + } + + { + FILE *fp; + fp = fopen(KEYSFILE_PATH, "w"); + if (!fp) { + printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH); + exit(1); + } + fprintf(fp, "%s\n", key); + fclose(fp); + } + key_added = 1; + printf("INFO: Valid key created. Finished.\n"); + } + break; + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_SYSCALL: + if (key_added == 0) { + printf("ERROR: Unable to create key. Either wrong password or connection not accepted by the manager.\n"); + } + printf("INFO: Connection closed.\n"); + exit(0); + break; + default: + printf("ERROR: SSL read (unable to receive message)\n"); + exit(1); + break; + } + + } + + /* Shut down the socket */ + if (key_added == 0) { + printf("ERROR: Unable to create key. Either wrong password or connection not accepted by the manager.\n"); + } + SSL_CTX_free(ctx); + close(sock); + + exit(0); +} + +#endif /* LIBOPENSSL_ENABLED */ diff --git a/src/os_auth/main-server.c b/src/os_auth/main-server.c new file mode 100644 index 000000000..513a4fe7d --- /dev/null +++ b/src/os_auth/main-server.c @@ -0,0 +1,601 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifndef LIBOPENSSL_ENABLED + +#include +#include +int main() +{ + printf("ERROR: Not compiled. Missing OpenSSL support.\n"); + exit(0); +} + +#else + +#include +#include "auth.h" +#include "os_crypto/md5/md5_op.h" + +/* TODO: Pulled this value out of the sky, may or may not be sane */ +#define POOL_SIZE 512 + +/* Prototypes */ +static void help_authd(void) __attribute((noreturn)); +static int ssl_error(const SSL *ssl, int ret); +static void clean_exit(SSL_CTX *ctx, int sock) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_authd() +{ + print_header(); + print_out(" %s: -[Vhdti] [-g group] [-D dir] [-p port] [-c ciphers] [-v path] [-x path] [-k path]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground."); + print_out(" -i Use client's source IP address"); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" -p Manager port (default: %s)", DEFAULT_PORT); + print_out(" -n Disable shared password authentication (not recommended).\n"); + print_out(" -c SSL cipher list (default: %s)", DEFAULT_CIPHERS); + print_out(" -v Full path to CA certificate used to verify clients"); + print_out(" -x Full path to server certificate"); + print_out(" -k Full path to server key"); + print_out(" "); + exit(1); +} + +/* Generates a random and temporary shared pass to be used by the agents. */ +char *__generatetmppass() +{ + int rand1; + int rand2; + char *rand3; + char *rand4; + os_md5 md1; + os_md5 md3; + os_md5 md4; + char *fstring = NULL; + char str1[STR_SIZE +1]; + char *muname = NULL; + + #ifndef WIN32 + #ifdef __OpenBSD__ + srandomdev(); + #else + srandom(time(0) + getpid() + getppid()); + #endif + #else + srandom(time(0) + getpid()); + #endif + + rand1 = random(); + rand2 = random(); + + rand3 = GetRandomNoise(); + rand4 = GetRandomNoise(); + + OS_MD5_Str(rand3, md3); + OS_MD5_Str(rand4, md4); + + muname = getuname(); + + snprintf(str1, STR_SIZE, "%d%d%s%d%s%s",(int)time(0), rand1, muname, rand2, md3, md4); + OS_MD5_Str(str1, md1); + fstring = strdup(md1); + free(rand3); + free(rand4); + if(muname) { + free(muname); + } + return(fstring); +} + +/* Function to use with SSL on non blocking socket, + * to know if SSL operation failed for good + */ +static int ssl_error(const SSL *ssl, int ret) +{ + if (ret <= 0) { + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + usleep(100 * 1000); + return (0); + default: + merror("%s: ERROR: SSL Error (%d)", ARGV0, ret); + ERR_print_errors_fp(stderr); + return (1); + } + } + + return (0); +} + +static void clean_exit(SSL_CTX *ctx, int sock) +{ + SSL_CTX_free(ctx); + close(sock); + exit(0); +} + +/* Exit handler */ +static void cleanup(); + + + +int main(int argc, char **argv) +{ + FILE *fp; + char *authpass = NULL; + /* Bucket to keep pids in */ + int process_pool[POOL_SIZE]; + /* Count of pids we are wait()ing on */ + int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0; + int use_pass = 1; + int run_foreground = 0; + gid_t gid; + int client_sock = 0, sock = 0, portnum, ret = 0; + char *port = DEFAULT_PORT; + char *ciphers = DEFAULT_CIPHERS; + const char *dir = DEFAULTDIR; + const char *group = GROUPGLOBAL; + const char *server_cert = NULL; + const char *server_key = NULL; + const char *ca_cert = NULL; + char buf[4096 + 1]; + SSL_CTX *ctx; + SSL *ssl; + char srcip[IPSIZE + 1]; + struct sockaddr_storage _nc; + socklen_t _ncl; + fd_set fdsave, fdwork; /* select() work areas */ + int fdmax; /* max socket number + 1 */ + OSNetInfo *netinfo; /* bound network sockets */ + int esc = 0; /* while() escape flag */ + + /* Initialize some variables */ + memset(srcip, '\0', IPSIZE + 1); + memset(process_pool, 0x0, POOL_SIZE * sizeof(*process_pool)); + bio_err = 0; + + OS_PassEmptyKeyfile(); + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtfig:D:m:p:c:v:x:k:n")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_authd(); + break; + case 'd': + nowDebug(); + break; + case 'i': + use_ip_address = 1; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 't': + test_config = 1; + break; + case 'f': + run_foreground = 1; + break; + case 'n': + use_pass = 0; + break; + case 'p': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + portnum = atoi(optarg); + if (portnum <= 0 || portnum >= 65536) { + ErrorExit("%s: Invalid port: %s", ARGV0, optarg); + } + port = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + ciphers = optarg; + break; + case 'v': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + ca_cert = optarg; + break; + case 'x': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + server_cert = optarg; + break; + case 'k': + if (!optarg) { + ErrorExit("%s: -%c needs an argument", ARGV0, c); + } + server_key = optarg; + break; + default: + help_authd(); + break; + } + } + + /* Start daemon -- NB: need to double fork and setsid */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the user/group given are valid */ + gid = Privsep_GetGroup(group); + if (gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, "", group); + } + + if (!run_foreground) { + nowDaemon(); + goDaemon(); + } + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot -- TODO: this isn't a chroot. Should also close + * unneeded open file descriptors (like stdin/stdout) + */ + if (chdir(dir) == -1) { + ErrorExit(CHDIR_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + /* Signal manipulation */ + StartSIG(ARGV0); + + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + atexit(cleanup); + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + if (use_pass) { + + /* Checking if there is a custom password file */ + fp = fopen(AUTHDPASS_PATH, "r"); + buf[0] = '\0'; + if (fp) { + buf[4096] = '\0'; + char *ret = fgets(buf, 4095, fp); + + if (ret && strlen(buf) > 2) { + /* Remove newline */ + buf[strlen(buf) - 1] = '\0'; + authpass = strdup(buf); + } + + fclose(fp); + } + + if (buf[0] != '\0') + verbose("Accepting connections. Using password specified on file: %s",AUTHDPASS_PATH); + else { + /* Getting temporary pass. */ + authpass = __generatetmppass(); + verbose("Accepting connections. Random password chosen for agent authentication: %s", authpass); + } + } else { + verbose("Accepting connections. No password required (not recommended)"); + } + + /* Getting SSL cert. */ + + fp = fopen(KEYSFILE_PATH, "a"); + if (!fp) { + merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH); + exit(1); + } + fclose(fp); + + /* Start SSL */ + ctx = os_ssl_keys(1, dir, ciphers, server_cert, server_key, ca_cert); + if (!ctx) { + merror("%s: ERROR: SSL error. Exiting.", ARGV0); + exit(1); + } + + /* Connect via TCP */ + netinfo = OS_Bindporttcp(port, NULL); + if (netinfo->status < 0) { + merror("%s: Unable to bind to port %s", ARGV0, port); + exit(1); + } + + /* initialize select() save area */ + fdsave = netinfo->fdset; + fdmax = netinfo->fdmax; /* value preset to max fd + 1 */ + + debug1("%s: DEBUG: Going into listening mode.", ARGV0); + + /* Setup random */ + srandom_init(); + + /* Chroot */ +/* + if (Privsep_Chroot(dir) < 0) + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + + nowChroot(); +*/ + + while (1) { + /* No need to completely pin the cpu, 100ms should be fast enough */ + usleep(100 * 1000); + + /* Only check process-pool if we have active processes */ + if (active_processes > 0) { + for (i = 0; i < POOL_SIZE; i++) { + int rv = 0; + status = 0; + if (process_pool[i]) { + rv = waitpid(process_pool[i], &status, WNOHANG); + if (rv != 0) { + debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]); + process_pool[i] = 0; + active_processes = active_processes - 1; + } + } + } + } + memset(&_nc, 0, sizeof(_nc)); + _ncl = sizeof(_nc); + + fdwork = fdsave; + if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) { + ErrorExit("ERROR: Call to os_auth select() failed, errno %d - %s", + errno, strerror (errno)); + } + + /* read through socket list for active socket */ + for (sock = 0; sock <= fdmax; sock++) { + if (FD_ISSET (sock, &fdwork)) { + if ((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0) { + if (active_processes >= POOL_SIZE) { + merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0); + esc = 1; /* exit while(1) loop */ + break; + } + pid = fork(); + if (pid) { + active_processes = active_processes + 1; + close(client_sock); + for (i = 0; i < POOL_SIZE; i++) { + if (! process_pool[i]) { + process_pool[i] = pid; + break; + } + } + } else { + satop((struct sockaddr *) &_nc, srcip, IPSIZE); + char *agentname = NULL; + ssl = SSL_new(ctx); + SSL_set_fd(ssl, client_sock); + + do { + ret = SSL_accept(ssl); + + if (ssl_error(ssl, ret)) { + clean_exit(ctx, client_sock); + } + + } while (ret <= 0); + verbose("%s: INFO: New connection from %s", ARGV0, srcip); + buf[0] = '\0'; + + do { + ret = SSL_read(ssl, buf, sizeof(buf)); + + if (ssl_error(ssl, ret)) { + clean_exit(ctx, client_sock); + } + + } while (ret <= 0); + + int parseok = 0; + char *tmpstr = buf; + + /* Checking for shared password authentication. */ + if(authpass) { + /* Format is pretty simple: openarmor PASS: PASS WHATEVERACTION */ + if (strncmp(tmpstr, "openarmor PASS: ", 12) == 0) { + tmpstr = tmpstr + 12; + + if (strlen(tmpstr) > strlen(authpass) && strncmp(tmpstr, authpass, strlen(authpass)) == 0) { + tmpstr += strlen(authpass); + + if (*tmpstr == ' ') { + tmpstr++; + parseok = 1; + } + } + } + if (parseok == 0) { + merror("%s: ERROR: Invalid password provided by %s. Closing connection.", ARGV0, srcip); + SSL_CTX_free(ctx); + close(client_sock); + exit(0); + } + } + + /* Checking for action A (add agent) */ + parseok = 0; + if (strncmp(tmpstr, "openarmor A:'", 9) == 0) { + agentname = tmpstr + 9; + tmpstr += 9; + while (*tmpstr != '\0') { + if (*tmpstr == '\'') { + *tmpstr = '\0'; + verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip); + parseok = 1; + break; + } + tmpstr++; + } + } + if (parseok == 0) { + merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip); + } else { + int acount = 2; + char fname[2048 + 1]; + char response[2048 + 1]; + char *finalkey = NULL; + response[2048] = '\0'; + fname[2048] = '\0'; + if (!OS_IsValidName(agentname)) { + merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip); + snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname); + SSL_write(ssl, response, strlen(response)); + snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); + SSL_write(ssl, response, strlen(response)); + sleep(1); + exit(0); + } + + /* Check for duplicate names */ + strncpy(fname, agentname, 2048); + while (NameExist(fname)) { + snprintf(fname, 2048, "%s%d", agentname, acount); + acount++; + if (acount > 256) { + merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname); + snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname); + SSL_write(ssl, response, strlen(response)); + snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); + SSL_write(ssl, response, strlen(response)); + sleep(1); + exit(0); + } + } + agentname = fname; + + /* Check for duplicate IP addresses */ + char *check_ip_address = NULL; + check_ip_address = IPExist(srcip); + if(check_ip_address) { + merror("%s: ERROR: Invalid IP address %s (duplicated)", ARGV0, check_ip_address); + snprintf(response, 2048, "ERROR: Invalid IP address: %s\n\n", check_ip_address); + SSL_write(ssl, response, strlen(response)); + snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); + SSL_write(ssl, response, strlen(response)); + sleep(1); + exit(0); + } + + /* Add the new agent */ + if (use_ip_address) { + finalkey = OS_AddNewAgent(agentname, srcip, NULL); + } else { + finalkey = OS_AddNewAgent(agentname, NULL, NULL); + } + if (!finalkey) { + merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname); + snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname); + SSL_write(ssl, response, strlen(response)); + snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); + SSL_write(ssl, response, strlen(response)); + sleep(1); + exit(0); + } + + snprintf(response, 2048, "openarmor K:'%s'\n\n", finalkey); + verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip); + ret = SSL_write(ssl, response, strlen(response)); + if (ret < 0) { + merror("%s: ERROR: SSL write error (%d)", ARGV0, ret); + merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname); + ERR_print_errors_fp(stderr); + } else { + verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip); + } + } + + clean_exit(ctx, client_sock); + } + } + } /* if active socket */ + } /* for() loop on available sockets */ + + /* check for while() escape flag */ + if (esc == 1) + break; + + } /* while(1) loop for messages */ + + /* Shut down the socket */ + clean_exit(ctx, sock); + + return (0); +} + +/* Exit handler */ +static void cleanup() { + DeletePID(ARGV0); +} +#endif /* LIBOPENSSL_ENABLED */ diff --git a/src/os_auth/ssl-test.c b/src/os_auth/ssl-test.c new file mode 100644 index 000000000..d33a4bd8d --- /dev/null +++ b/src/os_auth/ssl-test.c @@ -0,0 +1,168 @@ +/* Copyright (C) 2011 Trend Micro Inc. All rights reserved. + * + * openarmor HIDS is a free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2) as + * published by the FSF - Free Software Foundation. + * + * Note that this license applies to the source code, as well as + * decoders, rules and any other data file included with openarmor (unless + * otherwise specified). + * + * This program is distributed in the hope that it will be useful, but + * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and + * NON-INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TEST "GET / HTTP/1.0\r\n\r\n\r\n" + + +int main(int argc, char **argv) +{ + int c; + int sock = 0, portnum, ret = 0; + char *host = NULL, *port = "443"; + SSL_CTX *ctx; + SSL *ssl; + SSL_METHOD *sslmeth; + BIO *sbio; + BIO *bio_err = 0; + + while ((c = getopt(argc, argv, "h:p:")) != -1) { + switch (c) { + case 'h': + host = optarg; + break; + case 'p': + portnum = atoi(optarg); + if (portnum <= 0 || portnum >= 65536) { + exit(1); + } + port = optarg; + break; + default: + exit(1); + break; + } + } + + if (!bio_err) { + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + } + + sslmeth = SSLv23_method(); + ctx = SSL_CTX_new(sslmeth); + if (!ctx) { + printf("CTX ERROR\n"); + exit(1); + } + + if (!host) { + printf("ERROR - host not set.\n"); + exit(1); + } + + /* Connect via TCP */ + sock = OS_ConnectTCP(port, host); + if (sock <= 0) { + printf("connect error\n"); + exit(1); + } + + /* Connect the SSL socket */ + ssl = SSL_new(ctx); + sbio = BIO_new_socket(sock, BIO_NOCLOSE); + SSL_set_bio(ssl, sbio, sbio); + ret = SSL_connect(ssl); + if (ret <= 0) { + printf("SSL connect error\n"); + ERR_print_errors_fp(stderr); + exit(1); + } + + printf("Connected!\n"); + + ret = SSL_write(ssl, TEST, sizeof(TEST)); + if (ret < 0) { + printf("SSL write error\n"); + ERR_print_errors_fp(stderr); + exit(1); + } + + while (1) { + char buf[2048]; + ret = SSL_read(ssl, buf, sizeof(buf) - 1); + printf("ret: %d\n", ret); + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + buf[ret] = '\0'; + printf("no error: %s\n", buf); + break; + case SSL_ERROR_ZERO_RETURN: + printf("no return\n"); + exit(1); + break; + case SSL_ERROR_SYSCALL: + fprintf(stderr, + "SSL Error: Premature close\n"); + exit(1); + break; + default: + printf("default error\n"); + exit(1); + break; + } + + } + + exit(0); +} + diff --git a/src/os_auth/ssl.c b/src/os_auth/ssl.c new file mode 100644 index 000000000..c9b017cc3 --- /dev/null +++ b/src/os_auth/ssl.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifdef LIBOPENSSL_ENABLED + +#include "shared.h" +#include "auth.h" + +/* Global variables */ +BIO *bio_err; + + +/* Create an SSL context. If certificate verification is requested + * then load the file containing the CA chain and verify the certificate + * sent by the peer. + */ +SSL_CTX *os_ssl_keys(int is_server, const char *os_dir, const char *ciphers, const char *cert, const char *key, const char *ca_cert) +{ + SSL_CTX *ctx = NULL; + + if (!(ctx = get_ssl_context(ciphers))) { + goto SSL_ERROR; + } + + /* If a CA certificate has been specified then load it and verify the peer */ + if (ca_cert) { + debug1("%s: DEBUG: Peer verification requested.", ARGV0); + + if (!load_ca_cert(ctx, ca_cert)) { + goto SSL_ERROR; + } + + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); + } + + /* Loading a certificate and key is mandatory for the server and optional for clients */ + if (is_server) { + char default_cert[PATH_MAX + 1]; + char default_key[PATH_MAX + 1]; + + if (!cert) { + snprintf(default_cert, PATH_MAX + 1, "%s%s", os_dir, CERTFILE); + cert = default_cert; + } + + if (!key) { + snprintf(default_key, PATH_MAX + 1, "%s%s", os_dir, KEYFILE); + key = default_key; + } + + if (!load_cert_and_key(ctx, cert, key)) { + goto SSL_ERROR; + } + + debug1("%s: DEBUG: Returning CTX for server.", ARGV0); + } else { + if (cert && key) { + if (!load_cert_and_key(ctx, cert, key)) { + goto SSL_ERROR; + } + } + + debug1("%s: DEBUG: Returning CTX for client.", ARGV0); + } + + return ctx; + +SSL_ERROR: + if (ctx) { + SSL_CTX_free(ctx); + } + + return (SSL_CTX *)NULL; +} + +SSL_CTX *get_ssl_context(const char *ciphers) +{ + const SSL_METHOD *sslmeth = NULL; + SSL_CTX *ctx = NULL; + + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + + /* Create our context */ + sslmeth = TLSv1_2_method(); + if (!(ctx = SSL_CTX_new(sslmeth))) { + goto CONTEXT_ERR; + } + + /* Explicitly set options and cipher list */ + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); + if (!(SSL_CTX_set_cipher_list(ctx, ciphers))) { + goto CONTEXT_ERR; + } + + return ctx; + +CONTEXT_ERR: + if (ctx) { + SSL_CTX_free(ctx); + } + + return (SSL_CTX *)NULL; +} + +int load_cert_and_key(SSL_CTX *ctx, const char *cert, const char *key) +{ + if (File_DateofChange(cert) <= 0) { + merror("%s: ERROR: Unable to read certificate file (not found): %s", ARGV0, cert); + return 0; + } + + if (!(SSL_CTX_use_certificate_chain_file(ctx, cert))) { + merror("%s: ERROR: Unable to read certificate file: %s", ARGV0, cert); + ERR_print_errors_fp(stderr); + return 0; + } + + if (!(SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))) { + merror("%s: ERROR: Unable to read private key file: %s", ARGV0, key); + ERR_print_errors_fp(stderr); + return 0; + } + + if (!SSL_CTX_check_private_key(ctx)) { + merror("%s: ERROR: Unable to verify private key file", ARGV0); + ERR_print_errors_fp(stderr); + return 0; + } + +#if(OPENSSL_VERSION_NUMBER < 0x00905100L) + SSL_CTX_set_verify_depth(ctx, 1); +#endif + + return 1; +} + +int load_ca_cert(SSL_CTX *ctx, const char *ca_cert) +{ + if (!ca_cert) { + merror("%s: ERROR: Verification requested but no CA certificate file specified", ARGV0); + return 0; + } + + if (SSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1) { + merror("%s: ERROR: Unable to read CA certificate file \"%s\"", ARGV0, ca_cert); + return 0; + } + + return 1; +} + +/* No extra verification is done here. This function provides more + * information in the case that certificate verification fails + * for any reason. + */ +int verify_callback(int ok, X509_STORE_CTX *store) +{ + char data[256]; + + if (!ok) { + X509 *cert = X509_STORE_CTX_get_current_cert(store); + int depth = X509_STORE_CTX_get_error_depth(store); + int err = X509_STORE_CTX_get_error(store); + + merror("%s: ERROR: Problem with certificate at depth %i", ARGV0, depth); + + X509_NAME_oneline(X509_get_issuer_name(cert), data, 256); + merror("%s: ERROR: issuer = %s", ARGV0, data); + + X509_NAME_oneline(X509_get_subject_name(cert), data, 256); + merror("%s: ERROR: subject = %s", ARGV0, data); + + merror("%s: ERROR: %i:%s", ARGV0, err, X509_verify_cert_error_string(err)); + } + + return ok; +} + +#endif /* LIBOPENSSL_ENABLED */ + diff --git a/src/os_crypto/blowfish/bf_enc.c b/src/os_crypto/blowfish/bf_enc.c new file mode 100644 index 000000000..ed2472267 --- /dev/null +++ b/src/os_crypto/blowfish/bf_enc.c @@ -0,0 +1,300 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "blowfish.h" +#include "bf_locl.h" + +/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper' + * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, + * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) + */ + +#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) +#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ +to modify the code. +#endif + + +void BF_encrypt(BF_LONG *data, const BF_KEY *key) +{ +#ifndef BF_PTR2 + register BF_LONG l, r; + register const BF_LONG *p, *s; + + p = key->P; + s = &(key->S[0]); + l = data[0]; + r = data[1]; + + l ^= p[0]; + BF_ENC(r, l, s, p[ 1]); + BF_ENC(l, r, s, p[ 2]); + BF_ENC(r, l, s, p[ 3]); + BF_ENC(l, r, s, p[ 4]); + BF_ENC(r, l, s, p[ 5]); + BF_ENC(l, r, s, p[ 6]); + BF_ENC(r, l, s, p[ 7]); + BF_ENC(l, r, s, p[ 8]); + BF_ENC(r, l, s, p[ 9]); + BF_ENC(l, r, s, p[10]); + BF_ENC(r, l, s, p[11]); + BF_ENC(l, r, s, p[12]); + BF_ENC(r, l, s, p[13]); + BF_ENC(l, r, s, p[14]); + BF_ENC(r, l, s, p[15]); + BF_ENC(l, r, s, p[16]); +#if BF_ROUNDS == 20 + BF_ENC(r, l, s, p[17]); + BF_ENC(l, r, s, p[18]); + BF_ENC(r, l, s, p[19]); + BF_ENC(l, r, s, p[20]); +#endif + r ^= p[BF_ROUNDS + 1]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#else + register BF_LONG l, r, t, *k; + + l = data[0]; + r = data[1]; + k = (BF_LONG *)key; + + l ^= k[0]; + BF_ENC(r, l, k, 1); + BF_ENC(l, r, k, 2); + BF_ENC(r, l, k, 3); + BF_ENC(l, r, k, 4); + BF_ENC(r, l, k, 5); + BF_ENC(l, r, k, 6); + BF_ENC(r, l, k, 7); + BF_ENC(l, r, k, 8); + BF_ENC(r, l, k, 9); + BF_ENC(l, r, k, 10); + BF_ENC(r, l, k, 11); + BF_ENC(l, r, k, 12); + BF_ENC(r, l, k, 13); + BF_ENC(l, r, k, 14); + BF_ENC(r, l, k, 15); + BF_ENC(l, r, k, 16); +#if BF_ROUNDS == 20 + BF_ENC(r, l, k, 17); + BF_ENC(l, r, k, 18); + BF_ENC(r, l, k, 19); + BF_ENC(l, r, k, 20); +#endif + r ^= k[BF_ROUNDS + 1]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#endif +} + +#ifndef BF_DEFAULT_OPTIONS + +void BF_decrypt(BF_LONG *data, const BF_KEY *key) +{ +#ifndef BF_PTR2 + register const BF_LONG *p, *s; + register BF_LONG l, r; + + p = key->P; + s = &(key->S[0]); + l = data[0]; + r = data[1]; + + l ^= p[BF_ROUNDS + 1]; +#if BF_ROUNDS == 20 + BF_ENC(r, l, s, p[20]); + BF_ENC(l, r, s, p[19]); + BF_ENC(r, l, s, p[18]); + BF_ENC(l, r, s, p[17]); +#endif + BF_ENC(r, l, s, p[16]); + BF_ENC(l, r, s, p[15]); + BF_ENC(r, l, s, p[14]); + BF_ENC(l, r, s, p[13]); + BF_ENC(r, l, s, p[12]); + BF_ENC(l, r, s, p[11]); + BF_ENC(r, l, s, p[10]); + BF_ENC(l, r, s, p[ 9]); + BF_ENC(r, l, s, p[ 8]); + BF_ENC(l, r, s, p[ 7]); + BF_ENC(r, l, s, p[ 6]); + BF_ENC(l, r, s, p[ 5]); + BF_ENC(r, l, s, p[ 4]); + BF_ENC(l, r, s, p[ 3]); + BF_ENC(r, l, s, p[ 2]); + BF_ENC(l, r, s, p[ 1]); + r ^= p[0]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#else + register BF_LONG l, r, t, *k; + + l = data[0]; + r = data[1]; + k = (BF_LONG *)key; + + l ^= k[BF_ROUNDS + 1]; +#if BF_ROUNDS == 20 + BF_ENC(r, l, k, 20); + BF_ENC(l, r, k, 19); + BF_ENC(r, l, k, 18); + BF_ENC(l, r, k, 17); +#endif + BF_ENC(r, l, k, 16); + BF_ENC(l, r, k, 15); + BF_ENC(r, l, k, 14); + BF_ENC(l, r, k, 13); + BF_ENC(r, l, k, 12); + BF_ENC(l, r, k, 11); + BF_ENC(r, l, k, 10); + BF_ENC(l, r, k, 9); + BF_ENC(r, l, k, 8); + BF_ENC(l, r, k, 7); + BF_ENC(r, l, k, 6); + BF_ENC(l, r, k, 5); + BF_ENC(r, l, k, 4); + BF_ENC(l, r, k, 3); + BF_ENC(r, l, k, 2); + BF_ENC(l, r, k, 1); + r ^= k[0]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#endif +} + +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int encrypt) +{ + register BF_LONG tin0, tin1; + register BF_LONG tout0, tout1, xor0, xor1; + register long l = length; + BF_LONG tin[2]; + + if (encrypt) { + n2l(ivec, tout0); + n2l(ivec, tout1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, ivec); + l2n(tout1, ivec); + } else { + n2l(ivec, xor0); + n2l(ivec, xor1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, ivec); + l2n(xor1, ivec); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +#endif + diff --git a/src/os_crypto/blowfish/bf_locl.h b/src/os_crypto/blowfish/bf_locl.h new file mode 100644 index 000000000..5c0370943 --- /dev/null +++ b/src/os_crypto/blowfish/bf_locl.h @@ -0,0 +1,227 @@ +/* Modified to work without OPENSSL + * os_crypto (www.theopenarmor.org/c/os_crypto) + * Daniel B. Cid, danielcid@gmail.com + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BF_LOCL_H +#define HEADER_BF_LOCL_H + +/* Only include if OPENSSL is present */ +#ifdef LIBOPENSSL_ENABLED +#include /* BF_PTR, BF_PTR2 */ +#endif + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* This is actually a big endian algorithm, the most significant byte + * is used to lookup array 0 */ + +#if defined(BF_PTR2) + +/* + * This is basically a special Intel version. Point is that Intel + * doesn't have many registers, but offers a reach choice of addressing + * modes. So we spare some registers by directly traversing BF_KEY + * structure and hiring the most decorated addressing mode. The code + * generated by EGCS is *perfectly* competitive with assembler + * implementation! + */ +#define BF_ENC(LL,R,KEY,Pi) (\ + LL^=KEY[Pi], \ + t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ + t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ + LL^=t \ + ) + +#elif defined(BF_PTR) + +#ifndef BF_LONG_LOG2 +#define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ +#endif +#define BF_M (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely + * rlwinm. So let'em double-check if their compiler does it. + */ + +#define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ + LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ + *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ + *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ + *(BF_LONG *)((unsigned char *)&(S[768])+((R<>24)&0xff)] + \ + S[0x0100+((int)(R>>16)&0xff)])^ \ + S[0x0200+((int)(R>> 8)&0xff)])+ \ + S[0x0300+((int)(R )&0xff)])&0xffffffffL \ + ) +#endif + +#endif diff --git a/src/os_crypto/blowfish/bf_op.c b/src/os_crypto/blowfish/bf_op.c new file mode 100644 index 000000000..fe29f7f0e --- /dev/null +++ b/src/os_crypto/blowfish/bf_op.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* OS_crypto/blowfish Library + * APIs for many crypto operations + */ + +#include +#include +#include + +#include "blowfish.h" +#include "bf_op.h" + +typedef unsigned char uchar; + + +int OS_BF_Str(const char *input, char *output, const char *charkey, + long size, short int action) +{ + BF_KEY key; + static unsigned char cbc_iv [8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; + unsigned char iv[8]; + + memcpy(iv, cbc_iv, sizeof(iv)); + + BF_set_key(&key, (int)strlen(charkey), (const uchar *)charkey); + + BF_cbc_encrypt((const uchar *)input, (uchar *)output, (long)size, + &key, iv, action); + + return (1); +} + diff --git a/src/os_crypto/blowfish/bf_op.h b/src/os_crypto/blowfish/bf_op.h new file mode 100644 index 000000000..117e8f9b6 --- /dev/null +++ b/src/os_crypto/blowfish/bf_op.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* OS_crypto/blowfish Library + * APIs for many crypto operations + */ + +#ifndef __BF_OP_H +#define __BF_OP_H + +#define OS_ENCRYPT 1 +#define OS_DECRYPT 0 + +int OS_BF_Str(const char *input, char *output, const char *charkey, + long size, short int action) __attribute((nonnull)); + +#endif + diff --git a/src/os_crypto/blowfish/bf_pi.h b/src/os_crypto/blowfish/bf_pi.h new file mode 100644 index 000000000..333a9b579 --- /dev/null +++ b/src/os_crypto/blowfish/bf_pi.h @@ -0,0 +1,324 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static const BF_KEY bf_init = { + { + 0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, + 0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L, + 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL, + 0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, + 0x9216d5d9L, 0x8979fb1b + }, { + 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L, + 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L, + 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L, + 0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL, + 0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL, + 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L, + 0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL, + 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL, + 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L, + 0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L, + 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL, + 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL, + 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL, + 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L, + 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L, + 0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L, + 0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L, + 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L, + 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL, + 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L, + 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L, + 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L, + 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L, + 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL, + 0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L, + 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL, + 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL, + 0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L, + 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL, + 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L, + 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL, + 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L, + 0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L, + 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL, + 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L, + 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L, + 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL, + 0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L, + 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL, + 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L, + 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L, + 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL, + 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L, + 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L, + 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L, + 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L, + 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L, + 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL, + 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL, + 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L, + 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L, + 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L, + 0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L, + 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL, + 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L, + 0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL, + 0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL, + 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L, + 0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L, + 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L, + 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L, + 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L, + 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L, + 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL, + 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L, + 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L, + 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L, + 0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL, + 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L, + 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L, + 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL, + 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L, + 0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L, + 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L, + 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL, + 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL, + 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L, + 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L, + 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L, + 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L, + 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL, + 0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL, + 0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL, + 0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L, + 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL, + 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L, + 0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L, + 0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL, + 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL, + 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L, + 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL, + 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L, + 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL, + 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL, + 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L, + 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L, + 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L, + 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L, + 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L, + 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L, + 0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L, + 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL, + 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L, + 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL, + 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L, + 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L, + 0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L, + 0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L, + 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L, + 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L, + 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L, + 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L, + 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L, + 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L, + 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L, + 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L, + 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L, + 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L, + 0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L, + 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L, + 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL, + 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL, + 0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L, + 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL, + 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L, + 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L, + 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L, + 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L, + 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L, + 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L, + 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL, + 0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L, + 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L, + 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L, + 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL, + 0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL, + 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL, + 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L, + 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L, + 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL, + 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L, + 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL, + 0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L, + 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL, + 0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L, + 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL, + 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L, + 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL, + 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L, + 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L, + 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL, + 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L, + 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L, + 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L, + 0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L, + 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL, + 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L, + 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL, + 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L, + 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL, + 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L, + 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL, + 0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL, + 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL, + 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L, + 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L, + 0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL, + 0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL, + 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL, + 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL, + 0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL, + 0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L, + 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L, + 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L, + 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L, + 0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL, + 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL, + 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L, + 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L, + 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L, + 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L, + 0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L, + 0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L, + 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L, + 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L, + 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L, + 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L, + 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL, + 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L, + 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL, + 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L, + 0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L, + 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL, + 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL, + 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL, + 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L, + 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L, + 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L, + 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L, + 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L, + 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L, + 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L, + 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L, + 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L, + 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L, + 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L, + 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L, + 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL, + 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL, + 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L, + 0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL, + 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL, + 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL, + 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L, + 0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL, + 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL, + 0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L, + 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L, + 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L, + 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L, + 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL, + 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL, + 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L, + 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L, + 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L, + 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL, + 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L, + 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L, + 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L, + 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL, + 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L, + 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L, + 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L, + 0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL, + 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL, + 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L, + 0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L, + 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L, + 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L, + 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL, + 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L, + 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL, + 0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL, + 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L, + 0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L, + 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL, + 0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L, + 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL, + 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L, + 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL, + 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L, + 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L, + 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL, + 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L, + 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL, + 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L, + } +}; + diff --git a/src/os_crypto/blowfish/bf_skey.c b/src/os_crypto/blowfish/bf_skey.c new file mode 100644 index 000000000..9dc2f7905 --- /dev/null +++ b/src/os_crypto/blowfish/bf_skey.c @@ -0,0 +1,124 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "blowfish.h" +#include "bf_locl.h" +#include "bf_pi.h" + + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data) +{ + int i; + BF_LONG *p, ri, in[2]; + const unsigned char *d, *end; + + + memcpy(key, &bf_init, sizeof(BF_KEY)); + p = key->P; + + if (len > ((BF_ROUNDS + 2) * 4)) { + len = (BF_ROUNDS + 2) * 4; + } + + d = data; + end = &(data[len]); + for (i = 0; i < (BF_ROUNDS + 2); i++) { + ri = *(d++); + if (d >= end) { + d = data; + } + + ri <<= 8; + ri |= *(d++); + if (d >= end) { + d = data; + } + + ri <<= 8; + ri |= *(d++); + if (d >= end) { + d = data; + } + + ri <<= 8; + ri |= *(d++); + if (d >= end) { + d = data; + } + + p[i] ^= ri; + } + + in[0] = 0L; + in[1] = 0L; + for (i = 0; i < (BF_ROUNDS + 2); i += 2) { + BF_encrypt(in, key); + p[i ] = in[0]; + p[i + 1] = in[1]; + } + + p = key->S; + for (i = 0; i < 4 * 256; i += 2) { + BF_encrypt(in, key); + p[i ] = in[0]; + p[i + 1] = in[1]; + } +} + diff --git a/src/os_crypto/blowfish/blowfish.h b/src/os_crypto/blowfish/blowfish.h new file mode 100644 index 000000000..c8523ee44 --- /dev/null +++ b/src/os_crypto/blowfish/blowfish.h @@ -0,0 +1,126 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +#define HEADER_BLOWFISH_H + +/* #include */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_BF +#error BF is disabled. +#endif + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#define BF_LONG unsigned long +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +#define BF_LONG unsigned long +#define BF_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +#else +#define BF_LONG unsigned int +#endif + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num); +const char *BF_options(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/os_crypto/blowfish/main.c b/src/os_crypto/blowfish/main.c new file mode 100644 index 000000000..50dc2e7ec --- /dev/null +++ b/src/os_crypto/blowfish/main.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "bf_op.h" + + +int main(int argc, char **argv) +{ + int i; + char output[1024]; + char output2[1024]; + + memset(output, '\0', 1024); + memset(output2, '\0', 1024); + + if (argc < 3) { + printf("%s: string key\n", argv[0]); + exit(1); + } + + if ((strlen(argv[1]) > 1020) || (strlen(argv[2]) > 512)) { + printf("%s: size err\n", argv[0]); + exit(1); + } + + /* Encrypt */ + OS_BF_Str(argv[1], output, argv[2], strlen(argv[1]), OS_ENCRYPT); + + /* Decrypt */ + OS_BF_Str(output, output2, argv[2], strlen(argv[1]), OS_DECRYPT); + + printf("finished.\n"); + printf("input: '%s'\n", argv[1]); + printf("crpt: "); + for (i = 0; i <= strlen(argv[1]); i++) { + printf("%d", output[i]); + } + printf("\n"); + printf("output2: '%s'\n", output2); + return (0); +} + diff --git a/src/os_crypto/md5/main.c b/src/os_crypto/md5/main.c new file mode 100644 index 000000000..7fb22a862 --- /dev/null +++ b/src/os_crypto/md5/main.c @@ -0,0 +1,37 @@ +#include +#include +#include + +#include "md5_op.h" + + +void usage(char **argv) +{ + printf("%s file str\n%s str string\n", argv[0], argv[0]); + exit(1); +} + +int main(int argc, char **argv) +{ + os_md5 filesum; + + if (argc < 3) { + usage(argv); + } + + if (strcmp(argv[1], "file") == 0) { + OS_MD5_File(argv[2], filesum, OS_BINARY); + } + + else if (strcmp(argv[1], "str") == 0) { + OS_MD5_Str(argv[2], filesum); + } + + else { + usage(argv); + } + + printf("MD5Sum for \"%s\" is: %s\n", argv[2], filesum); + return (0); +} + diff --git a/src/os_crypto/md5/md5.c b/src/os_crypto/md5/md5.c new file mode 100644 index 000000000..02b848ecd --- /dev/null +++ b/src/os_crypto/md5/md5.c @@ -0,0 +1,256 @@ +/* This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#include +#include + +#include "md5.h" + +/* Checking for endiannes */ +#ifdef __BYTE_ORDER +#if __BYTE_ORDER == __BIG_ENDIAN +#define HIGHFIRST +#endif /* BIG ENDIAN */ +#endif /* byte order */ + +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + + +#ifndef ASM_MD5 +/* Note: this code is harmless on little-endian machines */ +void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* Update context to reflect the concatenation of another buffer full of bytes */ +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32 t; + + /* Update bitcount */ + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) { + ctx->bits[1]++; /* Carry from low to high */ + } + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + + /* Process data in 64-byte chunks */ + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data */ + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + * always at least one byte free + */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in32[14] = ctx->bits[0]; + ctx->in32[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif + diff --git a/src/os_crypto/md5/md5.h b/src/os_crypto/md5/md5.h new file mode 100644 index 000000000..435be6c7d --- /dev/null +++ b/src/os_crypto/md5/md5.h @@ -0,0 +1,58 @@ +/* This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#ifndef MD5_H +#define MD5_H + +#include +#if defined SOLARIS +typedef uint32_t u_int32_t; +typedef uint16_t u_int16_t; +typedef uint8_t u_int8_t; +#endif + +#if defined HPUX +typedef uint32_t u_int32_t; +typedef uint16_t u_int16_t; +typedef uint8_t u_int8_t; +#endif + +#ifdef WIN32 +typedef unsigned int u_int32_t; +#endif + +typedef u_int32_t uint32; + +struct MD5Context { + uint32 buf[4]; + uint32 bits[2]; + union { + unsigned char in[64]; + uint32 in32[16]; + }; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* This is needed to make RSAREF happy on some MS-DOS compilers */ +typedef struct MD5Context MD5_CTX; + +#endif /* MD5_H */ + diff --git a/src/os_crypto/md5/md5_op.c b/src/os_crypto/md5/md5_op.c new file mode 100644 index 000000000..c299aa47e --- /dev/null +++ b/src/os_crypto/md5/md5_op.c @@ -0,0 +1,74 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* OS_crypto/md5 Library + * APIs for many crypto operations + */ + +#include +#include + +#include "md5_op.h" +#include "md5.h" +#include "headers/defs.h" + + +int OS_MD5_File(const char *fname, os_md5 output, int mode) +{ + FILE *fp; + MD5_CTX ctx; + unsigned char buf[1024 + 1]; + unsigned char digest[16]; + size_t n; + + memset(output, 0, 33); + buf[1024] = '\0'; + + fp = fopen(fname, mode == OS_BINARY ? "rb" : "r"); + if (!fp) { + return (-1); + } + + MD5Init(&ctx); + while ((n = fread(buf, 1, sizeof(buf) - 1, fp)) > 0) { + buf[n] = '\0'; + MD5Update(&ctx, buf, (unsigned)n); + } + + MD5Final(digest, &ctx); + + for (n = 0; n < 16; n++) { + snprintf(output, 3, "%02x", digest[n]); + output += 2; + } + + fclose(fp); + + return (0); +} + +int OS_MD5_Str(const char *str, os_md5 output) +{ + unsigned char digest[16]; + + int n; + + MD5_CTX ctx; + MD5Init(&ctx); + MD5Update(&ctx, (const unsigned char *)str, (unsigned)strlen(str)); + MD5Final(digest, &ctx); + + output[32] = '\0'; + for (n = 0; n < 16; n++) { + snprintf(output, 3, "%02x", digest[n]); + output += 2; + } + + return (0); +} diff --git a/src/os_crypto/md5/md5_op.h b/src/os_crypto/md5/md5_op.h new file mode 100644 index 000000000..c7efe18df --- /dev/null +++ b/src/os_crypto/md5/md5_op.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* OS_crypto/md5 Library + * APIs for many crypto operations + */ + +#ifndef __MD5_OP_H +#define __MD5_OP_H + +typedef char os_md5[33]; + +int OS_MD5_File(const char *fname, os_md5 output, int mode) __attribute((nonnull)); +int OS_MD5_Str(const char *str, os_md5 output) __attribute((nonnull)); + +#endif + diff --git a/src/os_crypto/md5_sha1/main.c b/src/os_crypto/md5_sha1/main.c new file mode 100644 index 000000000..468b8a45c --- /dev/null +++ b/src/os_crypto/md5_sha1/main.c @@ -0,0 +1,36 @@ +#include +#include +#include + +#include "../md5/md5_op.h" +#include "../sha1/sha1_op.h" +#include "md5_sha1_op.h" + + +void usage(char **argv) +{ + printf("%s prefilter_cmd file str\n%s str string\n", argv[0], argv[0]); + exit(1); +} + +int main(int argc, char **argv) +{ + os_md5 filesum1; + os_sha1 filesum2; + + if (argc < 4) { + usage(argv); + } + + if (strcmp(argv[2], "file") == 0) { + OS_MD5_SHA1_File(argv[3], argv[1], filesum1, filesum2, OS_BINARY); + } + + else { + usage(argv); + } + + printf("MD5Sha1Sum for \"%s\" is: %s - %s\n", argv[2], filesum1, filesum2); + return (0); +} + diff --git a/src/os_crypto/md5_sha1/md5_sha1_op.c b/src/os_crypto/md5_sha1/md5_sha1_op.c new file mode 100644 index 000000000..dd367c7a0 --- /dev/null +++ b/src/os_crypto/md5_sha1/md5_sha1_op.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include + +#include "md5_sha1_op.h" +#include "../md5/md5.h" +#include "../sha1/sha.h" +#include "headers/defs.h" + + +int OS_MD5_SHA1_File(const char *fname, const char *prefilter_cmd, os_md5 md5output, os_sha1 sha1output, int mode) +{ + size_t n; + FILE *fp; + unsigned char buf[2048 + 2]; + unsigned char sha1_digest[SHA_DIGEST_LENGTH]; + unsigned char md5_digest[16]; + + SHA_CTX sha1_ctx; + MD5_CTX md5_ctx; + + /* Clear the memory */ + md5output[0] = '\0'; + sha1output[0] = '\0'; + buf[2048 + 1] = '\0'; + + /* Use prefilter_cmd if set */ + if (prefilter_cmd == NULL) { + fp = fopen(fname, mode == OS_BINARY ? "rb" : "r"); + if (!fp) { + return (-1); + } + } else { + char cmd[OS_MAXSTR]; + size_t target_length = strlen(prefilter_cmd) + 1 + strlen(fname); + int res = snprintf(cmd, sizeof(cmd), "%s %s", prefilter_cmd, fname); + if (res < 0 || (unsigned int)res != target_length) { + return (-1); + } + fp = popen(cmd, "r"); + if (!fp) { + return (-1); + } + } + + /* Initialize both hashes */ + MD5Init(&md5_ctx); + SHA1_Init(&sha1_ctx); + + /* Update for each one */ + while ((n = fread(buf, 1, 2048, fp)) > 0) { + buf[n] = '\0'; + SHA1_Update(&sha1_ctx, buf, n); + MD5Update(&md5_ctx, buf, (unsigned)n); + } + + SHA1_Final(&(sha1_digest[0]), &sha1_ctx); + MD5Final(md5_digest, &md5_ctx); + + /* Set output for MD5 */ + for (n = 0; n < 16; n++) { + snprintf(md5output, 3, "%02x", md5_digest[n]); + md5output += 2; + } + + /* Set output for SHA-1 */ + for (n = 0; n < SHA_DIGEST_LENGTH; n++) { + snprintf(sha1output, 3, "%02x", sha1_digest[n]); + sha1output += 2; + } + + /* Close it */ + if (prefilter_cmd == NULL) { + fclose(fp); + } else { + pclose(fp); + } + + return (0); +} diff --git a/src/os_crypto/md5_sha1/md5_sha1_op.h b/src/os_crypto/md5_sha1/md5_sha1_op.h new file mode 100644 index 000000000..81c113224 --- /dev/null +++ b/src/os_crypto/md5_sha1/md5_sha1_op.h @@ -0,0 +1,19 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __MD5SHA1_OP_H +#define __MD5SHA1_OP_H + +#include "../md5/md5_op.h" +#include "../sha1/sha1_op.h" + +int OS_MD5_SHA1_File(const char *fname, const char *prefilter_cmd, os_md5 md5output, os_sha1 sha1output, int mode) __attribute((nonnull(1, 3, 4))); + +#endif + diff --git a/src/os_crypto/sha1/main.c b/src/os_crypto/sha1/main.c new file mode 100644 index 000000000..846297919 --- /dev/null +++ b/src/os_crypto/sha1/main.c @@ -0,0 +1,29 @@ +#include +#include +#include + +#include "sha1_op.h" + + +void usage(char **argv) +{ + printf("%s file\n", argv[0]); + exit(1); +} + +int main(int argc, char **argv) +{ + os_sha1 filesum; + + if (argc < 2) { + usage(argv); + } + + if (OS_SHA1_File(argv[1], filesum, OS_BINARY) == 0) { + printf("SHA1Sum for \"%s\" is: %s\n", argv[1], filesum); + } else { + printf("SHA1Sum for \"%s\" failed\n", argv[1]); + } + return (0); +} + diff --git a/src/os_crypto/sha1/md32_common.h b/src/os_crypto/sha1/md32_common.h new file mode 100644 index 000000000..d9c739f27 --- /dev/null +++ b/src/os_crypto/sha1/md32_common.h @@ -0,0 +1,632 @@ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at lest 32 bit wide, if it's wider, then + * HASH_LONG_LOG2 *has to* be defined along + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * HASH_LONG data[HASH_LBLOCK]; + * unsigned int num; + * ... + * } HASH_CTX; + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_HOST_ORDER + * name of "block" function treating *aligned* input message + * in host byte order, implemented externally. + * HASH_BLOCK_DATA_ORDER + * name of "block" function treating *unaligned* input message + * in original (data) byte order, implemented externally (it + * actually is optional if data and host are of the same + * "endianess"). + * HASH_MAKE_STRING + * macro convering context variables to an ASCII hash string. + * + * Optional macros: + * + * B_ENDIAN or L_ENDIAN + * defines host byte-order. + * HASH_LONG_LOG2 + * defaults to 2 if not states otherwise. + * HASH_LBLOCK + * assumed to be HASH_CBLOCK/4 if not stated otherwise. + * HASH_BLOCK_DATA_ORDER_ALIGNED + * alternative "block" function capable of treating + * aligned input message in original (data) order, + * implemented externally. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_LONG_LOG2 MD5_LONG_LOG2 + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_LBLOCK MD5_LBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_HOST_ORDER md5_block_host_order + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + * + * + */ + + +#ifndef _MD32_COMMON__H +#define _MD32_COMMON__H + + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +#error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +#error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +#error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +#error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +#error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +#error "HASH_TRANSFORM must be defined!" +#endif +#ifndef HASH_FINAL +#error "HASH_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_HOST_ORDER +#error "HASH_BLOCK_HOST_ORDER must be defined!" +#endif + +#if 0 +/* + * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED + * isn't defined. + */ +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif +#endif + +#ifndef HASH_LBLOCK +#define HASH_LBLOCK (HASH_CBLOCK/4) +#endif + +#ifndef HASH_LONG_LOG2 +#define HASH_LONG_LOG2 2 +#endif + +/* + * Engage compiler specific rotate intrinsic function if available. + */ +#undef ROTATE +#ifndef PEDANTIC +# if defined(_MSC_VER) || defined(__ICC) +# define ROTATE(a,n) _lrotl(a,n) +# elif defined(__MWERKS__) +# if defined(__POWERPC__) +# define ROTATE(a,n) __rlwinm(a,n,0,31) +# elif defined(__MC68K__) +/* Motorola specific tweak. */ +# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) +# else +# define ROTATE(a,n) __rol(a,n) +# endif +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +/* + * Some GNU C inline assembler templates. Note that these are + * rotates by *constant* number of bits! But that's exactly + * what we need here... + * + */ +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"(a) \ + : "cc"); \ + ret; \ + }) +# elif defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# endif +# endif +#endif /* PEDANTIC */ + +#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ +/* A nice byte order reversal from Wei Dai */ +#ifdef ROTATE +/* 5 instructions with rotate instruction, else 9 */ +#define REVERSE_FETCH32(a,l) ( \ + l=*(const HASH_LONG *)(a), \ + ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ + ) +#else +/* 6 instructions with rotate instruction, else 8 */ +#define REVERSE_FETCH32(a,l) ( \ + l=*(const HASH_LONG *)(a), \ + l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ + ROTATE(l,16) \ + ) +/* + * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... + * It's rewritten as above for two reasons: + * - RISCs aren't good at long constants and have to explicitely + * compose 'em with several (well, usually 2) instructions in a + * register before performing the actual operation and (as you + * already realized:-) having same constant should inspire the + * compiler to permanently allocate the only register for it; + * - most modern CPUs have two ALUs, but usually only one has + * circuitry for shifts:-( this minor tweak inspires compiler + * to schedule shift instructions in a better way... + * + * + */ +#endif +#endif + +#ifndef ROTATE +#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +/* + * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED + * and HASH_BLOCK_HOST_ORDER ought to be the same if input data + * and host are of the same "endianess". It's possible to mask + * this with blank #define HASH_BLOCK_DATA_ORDER though... + * + * + */ +#if defined(B_ENDIAN) +# if defined(DATA_ORDER_IS_BIG_ENDIAN) +# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 +# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER +# endif +# endif +#elif defined(L_ENDIAN) +# if defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 +# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER +# endif +# endif +#endif + +#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ + (defined(__x86_64) || defined(__x86_64__)) +/* + * This gives ~30-40% performance improvement in SHA-256 compiled + * with gcc [on P4]. Well, first macro to be frank. We can pull + * this trick on x86* platforms only, because these CPUs can fetch + * unaligned data without raising an exception. + */ +# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r=(l); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + *((unsigned int *)(c))=r; (c)+=4; r; }) +# endif +# endif +#endif + +#ifndef HOST_c2l +#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ), \ + l) +#endif +#define HOST_p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + case 3: l|=((unsigned long)(*((c)++))); \ + } } +#define HOST_p_c2l_p(c,l,sc,len) { \ + switch (sc) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + } } +/* NOTE the pointer is not incremented at the end of this */ +#define HOST_c2l_p(c,l,n) { \ + l=0; (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<< 8; \ + case 2: l|=((unsigned long)(*(--(c))))<<16; \ + case 1: l|=((unsigned long)(*(--(c))))<<24; \ + } } +#ifndef HOST_l2c +#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) +#endif + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# ifndef B_ENDIAN +/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) +# endif +#endif + +#ifndef HOST_c2l +#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24), \ + l) +#endif +#define HOST_p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++))); \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + case 3: l|=((unsigned long)(*((c)++)))<<24; \ + } } +#define HOST_p_c2l_p(c,l,sc,len) { \ + switch (sc) { \ + case 0: l =((unsigned long)(*((c)++))); \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + } } +/* NOTE the pointer is not incremented at the end of this */ +#define HOST_c2l_p(c,l,n) { \ + l=0; (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<<16; \ + case 2: l|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l|=((unsigned long)(*(--(c)))); \ + } } +#ifndef HOST_l2c +#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + l) +#endif + +#endif + +/* + * Time for some action:-) + */ + +int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = (const unsigned char *)data_; + register HASH_LONG *p; + register HASH_LONG l; + size_t sw, sc, ew, ec; + + if (len == 0) { + return 1; + } + + l = (c->Nl + (((HASH_LONG)len) << 3)) & 0xffffffffUL; + /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to + * Wei Dai for pointing it out. */ + if (l < c->Nl) { /* overflow */ + c->Nh++; + } + c->Nh += (len >> 29); /* might cause compiler warning on 16-bit */ + c->Nl = l; + + if (c->num != 0) { + p = c->data; + sw = c->num >> 2; + sc = c->num & 0x03; + + if ((c->num + len) >= HASH_CBLOCK) { + l = p[sw]; + HOST_p_c2l(data, l, sc); + p[sw++] = l; + for (; sw < HASH_LBLOCK; sw++) { + HOST_c2l(data, l); + p[sw] = l; + } + HASH_BLOCK_HOST_ORDER (c, p, 1); + len -= (HASH_CBLOCK - c->num); + c->num = 0; + /* drop through and do the rest */ + } else { + c->num += (unsigned int)len; + if ((sc + len) < 4) { /* ugly, add char's to a word */ + l = p[sw]; + HOST_p_c2l_p(data, l, sc, len); + p[sw] = l; + } else { + ew = (c->num >> 2); + ec = (c->num & 0x03); + if (sc) { + l = p[sw]; + } + HOST_p_c2l(data, l, sc); + p[sw++] = l; + for (; sw < ew; sw++) { + HOST_c2l(data, l); + p[sw] = l; + } + if (ec) { + HOST_c2l_p(data, l, ec); + p[sw] = l; + } + } + return 1; + } + } + + sw = len / HASH_CBLOCK; + if (sw > 0) { +#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) + /* + * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined + * only if sizeof(HASH_LONG)==4. + */ + if ((((size_t)data) % 4) == 0) { + /* data is properly aligned so that we can cast it: */ + HASH_BLOCK_DATA_ORDER_ALIGNED (c, (const HASH_LONG *)data, sw); + sw *= HASH_CBLOCK; + data += sw; + len -= sw; + } else +#if !defined(HASH_BLOCK_DATA_ORDER) + while (sw--) { + memcpy (p = c->data, data, HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER_ALIGNED(c, p, 1); + data += HASH_CBLOCK; + len -= HASH_CBLOCK; + } +#endif +#endif +#if defined(HASH_BLOCK_DATA_ORDER) + { + HASH_BLOCK_DATA_ORDER(c, data, sw); + sw *= HASH_CBLOCK; + data += sw; + len -= sw; + } +#endif + } + + if (len != 0) { + p = c->data; + c->num = len; + ew = len >> 2; /* words to copy */ + ec = len & 0x03; + for (; ew; ew--, p++) { + HOST_c2l(data, l); + *p = l; + } + HOST_c2l_p(data, l, ec); + *p = l; + } + return 1; +} + + +void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) +{ +#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) + if ((((size_t)data) % 4) == 0) + /* data is properly aligned so that we can cast it: */ + { + HASH_BLOCK_DATA_ORDER_ALIGNED (c, (const HASH_LONG *)data, 1); + } else +#if !defined(HASH_BLOCK_DATA_ORDER) + { + memcpy (c->data, data, HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER_ALIGNED (c, c->data, 1); + } +#endif +#endif +#if defined(HASH_BLOCK_DATA_ORDER) + HASH_BLOCK_DATA_ORDER (c, data, 1); +#endif +} + + +int HASH_FINAL (unsigned char *md, HASH_CTX *c) +{ + register HASH_LONG *p; + register unsigned long l; + register int i, j; + static const unsigned char end[4] = {0x80, 0x00, 0x00, 0x00}; + const unsigned char *cp = end; + + /* c->num should definitly have room for at least one more byte. */ + p = c->data; + i = c->num >> 2; + j = c->num & 0x03; + +#if 0 + /* purify often complains about the following line as an + * Uninitialized Memory Read. While this can be true, the + * following p_c2l macro will reset l when that case is true. + * This is because j&0x03 contains the number of 'valid' bytes + * already in p[i]. If and only if j&0x03 == 0, the UMR will + * occur but this is also the only time p_c2l will do + * l= *(cp++) instead of l|= *(cp++) + * Many thanks to Alex Tang for pickup this + * 'potential bug' */ +#ifdef PURIFY + if (j == 0) { + p[i] = 0; /* Yeah, but that's not the way to fix it:-) */ + } +#endif + l = p[i]; +#else + l = (j == 0) ? 0 : p[i]; +#endif + HOST_p_c2l(cp, l, j); + p[i++] = l; /* i is the next 'undefined word' */ + + if (i > (HASH_LBLOCK - 2)) { /* save room for Nl and Nh */ + if (i < HASH_LBLOCK) { + p[i] = 0; + } + HASH_BLOCK_HOST_ORDER (c, p, 1); + i = 0; + } + for (; i < (HASH_LBLOCK - 2); i++) { + p[i] = 0; + } + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + p[HASH_LBLOCK - 2] = c->Nh; + p[HASH_LBLOCK - 1] = c->Nl; +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + p[HASH_LBLOCK - 2] = c->Nl; + p[HASH_LBLOCK - 1] = c->Nh; +#endif + HASH_BLOCK_HOST_ORDER (c, p, 1); + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#else + HASH_MAKE_STRING(c, md); +#endif + + c->num = 0; + /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack + * but I'm not worried :-) + OPENSSL_cleanse((void *)c,sizeof(HASH_CTX)); + */ + return 1; +} + +#ifndef MD32_REG_T +#define MD32_REG_T int +/* + * This comment was originaly written for MD5, which is why it + * discusses A-D. But it basically applies to all 32-bit digests, + * which is why it was moved to common header file. + * + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * + * Apparently there're LP64 compilers that generate better + * code if A-D are declared int. Most notably GCC-x86_64 + * generates better code. + * + */ +#endif + + +#endif /* _MD32_COMMON__H */ diff --git a/src/os_crypto/sha1/sha.h b/src/os_crypto/sha1/sha.h new file mode 100644 index 000000000..87b5e5d30 --- /dev/null +++ b/src/os_crypto/sha1/sha.h @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +#define HEADER_SHA_H + + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(__LP32__) +#define SHA_LONG unsigned long +#elif defined(__ILP64__) +#define SHA_LONG unsigned long +#define SHA_LONG_LOG2 3 +#else +#define SHA_LONG unsigned int +#endif + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK-8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); + +#endif diff --git a/src/os_crypto/sha1/sha1_op.c b/src/os_crypto/sha1/sha1_op.c new file mode 100644 index 000000000..85a3a70fa --- /dev/null +++ b/src/os_crypto/sha1/sha1_op.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include + +#include "sha1_op.h" +#include "headers/defs.h" + +/* OpenSSL SHA-1 + * Only use if OpenSSL is not available +#ifndef LIBOPENSSL_ENABLED +#include "sha.h" +#include "sha_locl.h" +#else +#include +#endif +*/ + +#include "sha_locl.h" + + +int OS_SHA1_File(const char *fname, os_sha1 output, int mode) +{ + SHA_CTX c; + FILE *fp; + unsigned char buf[2048 + 2]; + unsigned char md[SHA_DIGEST_LENGTH]; + size_t n; + + memset(output, 0, 65); + buf[2049] = '\0'; + + fp = fopen(fname, mode == OS_BINARY ? "rb" : "r"); + if (!fp) { + return (-1); + } + + SHA1_Init(&c); + while ((n = fread(buf, 1, 2048, fp)) > 0) { + buf[n] = '\0'; + SHA1_Update(&c, buf, n); + } + + SHA1_Final(&(md[0]), &c); + + for (n = 0; n < SHA_DIGEST_LENGTH; n++) { + snprintf(output, 3, "%02x", md[n]); + output += 2; + } + + fclose(fp); + + return (0); +} diff --git a/src/os_crypto/sha1/sha1_op.h b/src/os_crypto/sha1/sha1_op.h new file mode 100644 index 000000000..3e7fa16cc --- /dev/null +++ b/src/os_crypto/sha1/sha1_op.h @@ -0,0 +1,18 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __SHA1_OP_H +#define __SHA1_OP_H + +typedef char os_sha1[65]; + +int OS_SHA1_File(const char *fname, os_sha1 output, int mode) __attribute((nonnull)); + +#endif + diff --git a/src/os_crypto/sha1/sha_locl.h b/src/os_crypto/sha1/sha_locl.h new file mode 100644 index 000000000..8900c7f26 --- /dev/null +++ b/src/os_crypto/sha1/sha_locl.h @@ -0,0 +1,660 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +#ifndef _SHA_LOCL__H +#define _SHA_LOCL__H + + +#include +#include + +#include "sha.h" + +#define SHA_1 +#ifndef SHA_LONG_LOG2 +#define SHA_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_LONG_LOG2 SHA_LONG_LOG2 +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK SHA_CBLOCK +#define HASH_LBLOCK SHA_LBLOCK +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->h0; HOST_l2c(ll,(s)); \ + ll=(c)->h1; HOST_l2c(ll,(s)); \ + ll=(c)->h2; HOST_l2c(ll,(s)); \ + ll=(c)->h3; HOST_l2c(ll,(s)); \ + ll=(c)->h4; HOST_l2c(ll,(s)); \ + } while (0) + +#if defined(SHA_0) + +# define HASH_UPDATE SHA_Update +# define HASH_TRANSFORM SHA_Transform +# define HASH_FINAL SHA_Final +# define HASH_INIT SHA_Init +# define HASH_BLOCK_HOST_ORDER sha_block_host_order +# define HASH_BLOCK_DATA_ORDER sha_block_data_order +# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id)) + +void sha_block_host_order (SHA_CTX *c, const void *p, size_t num); +void sha_block_data_order (SHA_CTX *c, const void *p, size_t num); + +#elif defined(SHA_1) + +# define HASH_UPDATE SHA1_Update +# define HASH_TRANSFORM SHA1_Transform +# define HASH_FINAL SHA1_Final +# define HASH_INIT SHA1_Init +# define HASH_BLOCK_HOST_ORDER sha1_block_host_order +# define HASH_BLOCK_DATA_ORDER sha1_block_data_order +# if defined(__MWERKS__) && defined(__MC68K__) +/* Metrowerks for Motorola fails otherwise:-( */ +# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \ + ix=(a)=ROTATE((a),1); \ + } while (0) +# else +# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ + ix=(a)=ROTATE((a),1) \ + ) +# endif + +# ifdef SHA1_ASM +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) +# if !defined(B_ENDIAN) +# define sha1_block_host_order sha1_block_asm_host_order +# define DONT_IMPLEMENT_BLOCK_HOST_ORDER +# define sha1_block_data_order sha1_block_asm_data_order +# define DONT_IMPLEMENT_BLOCK_DATA_ORDER +# define HASH_BLOCK_DATA_ORDER_ALIGNED sha1_block_asm_data_order +# endif +# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define sha1_block_host_order sha1_block_asm_host_order +# define DONT_IMPLEMENT_BLOCK_HOST_ORDER +# define sha1_block_data_order sha1_block_asm_data_order +# define DONT_IMPLEMENT_BLOCK_DATA_ORDER +# endif +# endif +void sha1_block_host_order (SHA_CTX *c, const void *p, size_t num); +void sha1_block_data_order (SHA_CTX *c, const void *p, size_t num); + +#else +# error "Either SHA_0 or SHA_1 must be defined." +#endif + +#include "md32_common.h" + +#define INIT_DATA_h0 0x67452301UL +#define INIT_DATA_h1 0xefcdab89UL +#define INIT_DATA_h2 0x98badcfeUL +#define INIT_DATA_h3 0x10325476UL +#define INIT_DATA_h4 0xc3d2e1f0UL + +int HASH_INIT (SHA_CTX *c) +{ + c->h0 = INIT_DATA_h0; + c->h1 = INIT_DATA_h1; + c->h2 = INIT_DATA_h2; + c->h3 = INIT_DATA_h3; + c->h4 = INIT_DATA_h4; + c->Nl = 0; + c->Nh = 0; + c->num = 0; + return 1; +} + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +/* As pointed out by Wei Dai , F() below can be + * simplified to the code in F_00_19. Wei attributes these optimisations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) + * I've just become aware of another tweak to be made, again from Wei Dai, + * in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#ifndef OPENSSL_SMALL_FOOTPRINT + +#define BODY_00_15(i,a,b,c,d,e,f,xi) \ + (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#ifdef X +#undef X +#endif +#ifndef MD32_XARRAY +/* + * Originally X was an array. As it's automatic it's natural + * to expect RISC compiler to accomodate at least part of it in + * the register bank, isn't it? Unfortunately not all compilers + * "find" this expectation reasonable:-( On order to make such + * compilers generate better code I replace X[] with a bunch of + * X0, X1, etc. See the function body below... + * + */ +# define X(i) XX##i +#else +/* + * However! Some compilers (most notably HP C) get overwhelmed by + * that many local variables so that we have to have the way to + * fall down to the original behavior. + */ +# define X(i) XX[i] +#endif + +#ifndef DONT_IMPLEMENT_BLOCK_HOST_ORDER +void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, size_t num) +{ + const SHA_LONG *W = (const SHA_LONG *)d; + register unsigned MD32_REG_T A, B, C, D, E, T; +#ifndef MD32_XARRAY + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +#else + SHA_LONG XX[16]; +#endif + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + BODY_00_15( 0, A, B, C, D, E, T, W[ 0]); + BODY_00_15( 1, T, A, B, C, D, E, W[ 1]); + BODY_00_15( 2, E, T, A, B, C, D, W[ 2]); + BODY_00_15( 3, D, E, T, A, B, C, W[ 3]); + BODY_00_15( 4, C, D, E, T, A, B, W[ 4]); + BODY_00_15( 5, B, C, D, E, T, A, W[ 5]); + BODY_00_15( 6, A, B, C, D, E, T, W[ 6]); + BODY_00_15( 7, T, A, B, C, D, E, W[ 7]); + BODY_00_15( 8, E, T, A, B, C, D, W[ 8]); + BODY_00_15( 9, D, E, T, A, B, C, W[ 9]); + BODY_00_15(10, C, D, E, T, A, B, W[10]); + BODY_00_15(11, B, C, D, E, T, A, W[11]); + BODY_00_15(12, A, B, C, D, E, T, W[12]); + BODY_00_15(13, T, A, B, C, D, E, W[13]); + BODY_00_15(14, E, T, A, B, C, D, W[14]); + BODY_00_15(15, D, E, T, A, B, C, W[15]); + + BODY_16_19(16, C, D, E, T, A, B, X( 0), W[ 0], W[ 2], W[ 8], W[13]); + BODY_16_19(17, B, C, D, E, T, A, X( 1), W[ 1], W[ 3], W[ 9], W[14]); + BODY_16_19(18, A, B, C, D, E, T, X( 2), W[ 2], W[ 4], W[10], W[15]); + BODY_16_19(19, T, A, B, C, D, E, X( 3), W[ 3], W[ 5], W[11], X( 0)); + + BODY_20_31(20, E, T, A, B, C, D, X( 4), W[ 4], W[ 6], W[12], X( 1)); + BODY_20_31(21, D, E, T, A, B, C, X( 5), W[ 5], W[ 7], W[13], X( 2)); + BODY_20_31(22, C, D, E, T, A, B, X( 6), W[ 6], W[ 8], W[14], X( 3)); + BODY_20_31(23, B, C, D, E, T, A, X( 7), W[ 7], W[ 9], W[15], X( 4)); + BODY_20_31(24, A, B, C, D, E, T, X( 8), W[ 8], W[10], X( 0), X( 5)); + BODY_20_31(25, T, A, B, C, D, E, X( 9), W[ 9], W[11], X( 1), X( 6)); + BODY_20_31(26, E, T, A, B, C, D, X(10), W[10], W[12], X( 2), X( 7)); + BODY_20_31(27, D, E, T, A, B, C, X(11), W[11], W[13], X( 3), X( 8)); + BODY_20_31(28, C, D, E, T, A, B, X(12), W[12], W[14], X( 4), X( 9)); + BODY_20_31(29, B, C, D, E, T, A, X(13), W[13], W[15], X( 5), X(10)); + BODY_20_31(30, A, B, C, D, E, T, X(14), W[14], X( 0), X( 6), X(11)); + BODY_20_31(31, T, A, B, C, D, E, X(15), W[15], X( 1), X( 7), X(12)); + + BODY_32_39(32, E, T, A, B, C, D, X( 0), X( 2), X( 8), X(13)); + BODY_32_39(33, D, E, T, A, B, C, X( 1), X( 3), X( 9), X(14)); + BODY_32_39(34, C, D, E, T, A, B, X( 2), X( 4), X(10), X(15)); + BODY_32_39(35, B, C, D, E, T, A, X( 3), X( 5), X(11), X( 0)); + BODY_32_39(36, A, B, C, D, E, T, X( 4), X( 6), X(12), X( 1)); + BODY_32_39(37, T, A, B, C, D, E, X( 5), X( 7), X(13), X( 2)); + BODY_32_39(38, E, T, A, B, C, D, X( 6), X( 8), X(14), X( 3)); + BODY_32_39(39, D, E, T, A, B, C, X( 7), X( 9), X(15), X( 4)); + + BODY_40_59(40, C, D, E, T, A, B, X( 8), X(10), X( 0), X( 5)); + BODY_40_59(41, B, C, D, E, T, A, X( 9), X(11), X( 1), X( 6)); + BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X( 2), X( 7)); + BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X( 3), X( 8)); + BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X( 4), X( 9)); + BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X( 5), X(10)); + BODY_40_59(46, C, D, E, T, A, B, X(14), X( 0), X( 6), X(11)); + BODY_40_59(47, B, C, D, E, T, A, X(15), X( 1), X( 7), X(12)); + BODY_40_59(48, A, B, C, D, E, T, X( 0), X( 2), X( 8), X(13)); + BODY_40_59(49, T, A, B, C, D, E, X( 1), X( 3), X( 9), X(14)); + BODY_40_59(50, E, T, A, B, C, D, X( 2), X( 4), X(10), X(15)); + BODY_40_59(51, D, E, T, A, B, C, X( 3), X( 5), X(11), X( 0)); + BODY_40_59(52, C, D, E, T, A, B, X( 4), X( 6), X(12), X( 1)); + BODY_40_59(53, B, C, D, E, T, A, X( 5), X( 7), X(13), X( 2)); + BODY_40_59(54, A, B, C, D, E, T, X( 6), X( 8), X(14), X( 3)); + BODY_40_59(55, T, A, B, C, D, E, X( 7), X( 9), X(15), X( 4)); + BODY_40_59(56, E, T, A, B, C, D, X( 8), X(10), X( 0), X( 5)); + BODY_40_59(57, D, E, T, A, B, C, X( 9), X(11), X( 1), X( 6)); + BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X( 2), X( 7)); + BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X( 3), X( 8)); + + BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X( 4), X( 9)); + BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X( 5), X(10)); + BODY_60_79(62, E, T, A, B, C, D, X(14), X( 0), X( 6), X(11)); + BODY_60_79(63, D, E, T, A, B, C, X(15), X( 1), X( 7), X(12)); + BODY_60_79(64, C, D, E, T, A, B, X( 0), X( 2), X( 8), X(13)); + BODY_60_79(65, B, C, D, E, T, A, X( 1), X( 3), X( 9), X(14)); + BODY_60_79(66, A, B, C, D, E, T, X( 2), X( 4), X(10), X(15)); + BODY_60_79(67, T, A, B, C, D, E, X( 3), X( 5), X(11), X( 0)); + BODY_60_79(68, E, T, A, B, C, D, X( 4), X( 6), X(12), X( 1)); + BODY_60_79(69, D, E, T, A, B, C, X( 5), X( 7), X(13), X( 2)); + BODY_60_79(70, C, D, E, T, A, B, X( 6), X( 8), X(14), X( 3)); + BODY_60_79(71, B, C, D, E, T, A, X( 7), X( 9), X(15), X( 4)); + BODY_60_79(72, A, B, C, D, E, T, X( 8), X(10), X( 0), X( 5)); + BODY_60_79(73, T, A, B, C, D, E, X( 9), X(11), X( 1), X( 6)); + BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X( 2), X( 7)); + BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X( 3), X( 8)); + BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X( 4), X( 9)); + BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X( 5), X(10)); + BODY_60_79(78, A, B, C, D, E, T, X(14), X( 0), X( 6), X(11)); + BODY_60_79(79, T, A, B, C, D, E, X(15), X( 1), X( 7), X(12)); + + c->h0 = (c->h0 + E) & 0xffffffffL; + c->h1 = (c->h1 + T) & 0xffffffffL; + c->h2 = (c->h2 + A) & 0xffffffffL; + c->h3 = (c->h3 + B) & 0xffffffffL; + c->h4 = (c->h4 + C) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + W += SHA_LBLOCK; + } +} +#endif + +#ifndef DONT_IMPLEMENT_BLOCK_DATA_ORDER +void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = (const unsigned char *)p; + register unsigned MD32_REG_T A, B, C, D, E, T, l; +#ifndef MD32_XARRAY + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +#else + SHA_LONG XX[16]; +#endif + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + + HOST_c2l(data, l); + X( 0) = l; + HOST_c2l(data, l); + X( 1) = l; + BODY_00_15( 0, A, B, C, D, E, T, X( 0)); + HOST_c2l(data, l); + X( 2) = l; + BODY_00_15( 1, T, A, B, C, D, E, X( 1)); + HOST_c2l(data, l); + X( 3) = l; + BODY_00_15( 2, E, T, A, B, C, D, X( 2)); + HOST_c2l(data, l); + X( 4) = l; + BODY_00_15( 3, D, E, T, A, B, C, X( 3)); + HOST_c2l(data, l); + X( 5) = l; + BODY_00_15( 4, C, D, E, T, A, B, X( 4)); + HOST_c2l(data, l); + X( 6) = l; + BODY_00_15( 5, B, C, D, E, T, A, X( 5)); + HOST_c2l(data, l); + X( 7) = l; + BODY_00_15( 6, A, B, C, D, E, T, X( 6)); + HOST_c2l(data, l); + X( 8) = l; + BODY_00_15( 7, T, A, B, C, D, E, X( 7)); + HOST_c2l(data, l); + X( 9) = l; + BODY_00_15( 8, E, T, A, B, C, D, X( 8)); + HOST_c2l(data, l); + X(10) = l; + BODY_00_15( 9, D, E, T, A, B, C, X( 9)); + HOST_c2l(data, l); + X(11) = l; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + HOST_c2l(data, l); + X(12) = l; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + HOST_c2l(data, l); + X(13) = l; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + HOST_c2l(data, l); + X(14) = l; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + HOST_c2l(data, l); + X(15) = l; + BODY_00_15(14, E, T, A, B, C, D, X(14)); + BODY_00_15(15, D, E, T, A, B, C, X(15)); + + BODY_16_19(16, C, D, E, T, A, B, X( 0), X( 0), X( 2), X( 8), X(13)); + BODY_16_19(17, B, C, D, E, T, A, X( 1), X( 1), X( 3), X( 9), X(14)); + BODY_16_19(18, A, B, C, D, E, T, X( 2), X( 2), X( 4), X(10), X(15)); + BODY_16_19(19, T, A, B, C, D, E, X( 3), X( 3), X( 5), X(11), X( 0)); + + BODY_20_31(20, E, T, A, B, C, D, X( 4), X( 4), X( 6), X(12), X( 1)); + BODY_20_31(21, D, E, T, A, B, C, X( 5), X( 5), X( 7), X(13), X( 2)); + BODY_20_31(22, C, D, E, T, A, B, X( 6), X( 6), X( 8), X(14), X( 3)); + BODY_20_31(23, B, C, D, E, T, A, X( 7), X( 7), X( 9), X(15), X( 4)); + BODY_20_31(24, A, B, C, D, E, T, X( 8), X( 8), X(10), X( 0), X( 5)); + BODY_20_31(25, T, A, B, C, D, E, X( 9), X( 9), X(11), X( 1), X( 6)); + BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X( 2), X( 7)); + BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X( 3), X( 8)); + BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X( 4), X( 9)); + BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X( 5), X(10)); + BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X( 0), X( 6), X(11)); + BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X( 1), X( 7), X(12)); + + BODY_32_39(32, E, T, A, B, C, D, X( 0), X( 2), X( 8), X(13)); + BODY_32_39(33, D, E, T, A, B, C, X( 1), X( 3), X( 9), X(14)); + BODY_32_39(34, C, D, E, T, A, B, X( 2), X( 4), X(10), X(15)); + BODY_32_39(35, B, C, D, E, T, A, X( 3), X( 5), X(11), X( 0)); + BODY_32_39(36, A, B, C, D, E, T, X( 4), X( 6), X(12), X( 1)); + BODY_32_39(37, T, A, B, C, D, E, X( 5), X( 7), X(13), X( 2)); + BODY_32_39(38, E, T, A, B, C, D, X( 6), X( 8), X(14), X( 3)); + BODY_32_39(39, D, E, T, A, B, C, X( 7), X( 9), X(15), X( 4)); + + BODY_40_59(40, C, D, E, T, A, B, X( 8), X(10), X( 0), X( 5)); + BODY_40_59(41, B, C, D, E, T, A, X( 9), X(11), X( 1), X( 6)); + BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X( 2), X( 7)); + BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X( 3), X( 8)); + BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X( 4), X( 9)); + BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X( 5), X(10)); + BODY_40_59(46, C, D, E, T, A, B, X(14), X( 0), X( 6), X(11)); + BODY_40_59(47, B, C, D, E, T, A, X(15), X( 1), X( 7), X(12)); + BODY_40_59(48, A, B, C, D, E, T, X( 0), X( 2), X( 8), X(13)); + BODY_40_59(49, T, A, B, C, D, E, X( 1), X( 3), X( 9), X(14)); + BODY_40_59(50, E, T, A, B, C, D, X( 2), X( 4), X(10), X(15)); + BODY_40_59(51, D, E, T, A, B, C, X( 3), X( 5), X(11), X( 0)); + BODY_40_59(52, C, D, E, T, A, B, X( 4), X( 6), X(12), X( 1)); + BODY_40_59(53, B, C, D, E, T, A, X( 5), X( 7), X(13), X( 2)); + BODY_40_59(54, A, B, C, D, E, T, X( 6), X( 8), X(14), X( 3)); + BODY_40_59(55, T, A, B, C, D, E, X( 7), X( 9), X(15), X( 4)); + BODY_40_59(56, E, T, A, B, C, D, X( 8), X(10), X( 0), X( 5)); + BODY_40_59(57, D, E, T, A, B, C, X( 9), X(11), X( 1), X( 6)); + BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X( 2), X( 7)); + BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X( 3), X( 8)); + + BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X( 4), X( 9)); + BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X( 5), X(10)); + BODY_60_79(62, E, T, A, B, C, D, X(14), X( 0), X( 6), X(11)); + BODY_60_79(63, D, E, T, A, B, C, X(15), X( 1), X( 7), X(12)); + BODY_60_79(64, C, D, E, T, A, B, X( 0), X( 2), X( 8), X(13)); + BODY_60_79(65, B, C, D, E, T, A, X( 1), X( 3), X( 9), X(14)); + BODY_60_79(66, A, B, C, D, E, T, X( 2), X( 4), X(10), X(15)); + BODY_60_79(67, T, A, B, C, D, E, X( 3), X( 5), X(11), X( 0)); + BODY_60_79(68, E, T, A, B, C, D, X( 4), X( 6), X(12), X( 1)); + BODY_60_79(69, D, E, T, A, B, C, X( 5), X( 7), X(13), X( 2)); + BODY_60_79(70, C, D, E, T, A, B, X( 6), X( 8), X(14), X( 3)); + BODY_60_79(71, B, C, D, E, T, A, X( 7), X( 9), X(15), X( 4)); + BODY_60_79(72, A, B, C, D, E, T, X( 8), X(10), X( 0), X( 5)); + BODY_60_79(73, T, A, B, C, D, E, X( 9), X(11), X( 1), X( 6)); + BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X( 2), X( 7)); + BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X( 3), X( 8)); + BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X( 4), X( 9)); + BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X( 5), X(10)); + BODY_60_79(78, A, B, C, D, E, T, X(14), X( 0), X( 6), X(11)); + BODY_60_79(79, T, A, B, C, D, E, X(15), X( 1), X( 7), X(12)); + + c->h0 = (c->h0 + E) & 0xffffffffL; + c->h1 = (c->h1 + T) & 0xffffffffL; + c->h2 = (c->h2 + A) & 0xffffffffL; + c->h3 = (c->h3 + B) & 0xffffffffL; + c->h4 = (c->h4 + C) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +#endif + +#else /* OPENSSL_SMALL_FOOTPRINT */ + +#define BODY_00_15(xi) do { \ + T=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xi; } while(0) + +#define BODY_16_19(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +#define BODY_20_39(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_20_39+F_20_39(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +#define BODY_40_59(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_40_59+F_40_59(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +#define BODY_60_79(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T=E+K_60_79+F_60_79(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xa; } while(0) + +#ifndef DONT_IMPLEMENT_BLOCK_HOST_ORDER +void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, size_t num) +{ + const SHA_LONG *W = d; + register unsigned MD32_REG_T A, B, C, D, E, T; + int i; + SHA_LONG X[16]; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + for (i = 0; i < 16; i++) { + X[i] = W[i]; + BODY_00_15(X[i]); + } + for (i = 0; i < 4; i++) { + BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]); + } + for (; i < 24; i++) { + BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15], X[(i + 13) & 15]); + } + for (i = 0; i < 20; i++) { + BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], X[(i + 5) & 15]); + } + for (i = 4; i < 24; i++) { + BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], X[(i + 5) & 15]); + } + + c->h0 = (c->h0 + A) & 0xffffffffL; + c->h1 = (c->h1 + B) & 0xffffffffL; + c->h2 = (c->h2 + C) & 0xffffffffL; + c->h3 = (c->h3 + D) & 0xffffffffL; + c->h4 = (c->h4 + E) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + W += SHA_LBLOCK; + } +} +#endif + +#ifndef DONT_IMPLEMENT_BLOCK_DATA_ORDER +void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E, T, l; + int i; + SHA_LONG X[16]; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + for (i = 0; i < 16; i++) { + HOST_c2l(data, l); + X[i] = l; + BODY_00_15(X[i]); + } + for (i = 0; i < 4; i++) { + BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]); + } + for (; i < 24; i++) { + BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15], X[(i + 13) & 15]); + } + for (i = 0; i < 20; i++) { + BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], X[(i + 5) & 15]); + } + for (i = 4; i < 24; i++) { + BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], X[(i + 5) & 15]); + } + + c->h0 = (c->h0 + A) & 0xffffffffL; + c->h1 = (c->h1 + B) & 0xffffffffL; + c->h2 = (c->h2 + C) & 0xffffffffL; + c->h3 = (c->h3 + D) & 0xffffffffL; + c->h4 = (c->h4 + E) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +#endif + +#endif + + +#endif /* _SHA_LOCL__H */ diff --git a/src/os_crypto/shared/keys.c b/src/os_crypto/shared/keys.c new file mode 100644 index 000000000..5d37b23d2 --- /dev/null +++ b/src/os_crypto/shared/keys.c @@ -0,0 +1,430 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "headers/shared.h" +#include "headers/sec.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/blowfish/bf_op.h" + +/* Prototypes */ +static void __memclear(char *id, char *name, char *ip, char *key, size_t size) __attribute((nonnull)); +static void __chash(keystore *keys, const char *id, const char *name, char *ip, const char *key) __attribute((nonnull)); + +static int pass_empty_keyfile = 0; + +/* Clear keys entries */ +static void __memclear(char *id, char *name, char *ip, char *key, size_t size) +{ + memset(id, '\0', size); + memset(name, '\0', size); + memset(key, '\0', size); + memset(ip, '\0', size); +} + +/* Create the final key */ +static void __chash(keystore *keys, const char *id, const char *name, char *ip, const char *key) +{ + os_md5 filesum1; + os_md5 filesum2; + + char *tmp_str; + char _finalstr[KEYSIZE]; + + /* Allocate for the whole structure */ + keys->keyentries = (keyentry **)realloc(keys->keyentries, + (keys->keysize + 2) * sizeof(keyentry *)); + if (!keys->keyentries) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + os_calloc(1, sizeof(keyentry), keys->keyentries[keys->keysize]); + + /* Set configured values for id */ + os_strdup(id, keys->keyentries[keys->keysize]->id); + OSHash_Add(keys->keyhash_id, + keys->keyentries[keys->keysize]->id, + keys->keyentries[keys->keysize]); + + /* Agent IP */ + os_calloc(1, sizeof(os_ip), keys->keyentries[keys->keysize]->ip); + if (OS_IsValidIP(ip, keys->keyentries[keys->keysize]->ip) == 0) { + ErrorExit(INVALID_IP, __local_name, ip); + } + + /* We need to remove the "/" from the CIDR */ + if ((tmp_str = strchr(keys->keyentries[keys->keysize]->ip->ip, '/')) != NULL) { + *tmp_str = '\0'; + } + OSHash_Add(keys->keyhash_ip, + keys->keyentries[keys->keysize]->ip->ip, + keys->keyentries[keys->keysize]); + + /* Agent name */ + os_strdup(name, keys->keyentries[keys->keysize]->name); + + /* Initialize the variables */ + keys->keyentries[keys->keysize]->rcvd = 0; + keys->keyentries[keys->keysize]->local = 0; + keys->keyentries[keys->keysize]->keyid = keys->keysize; + keys->keyentries[keys->keysize]->global = 0; + keys->keyentries[keys->keysize]->fp = NULL; + + /** Generate final symmetric key **/ + + /* MD5 from name, id and key */ + OS_MD5_Str(name, filesum1); + OS_MD5_Str(id, filesum2); + + /* Generate new filesum1 */ + snprintf(_finalstr, sizeof(_finalstr) - 1, "%s%s", filesum1, filesum2); + + /* Use just half of the first MD5 (name/id) */ + OS_MD5_Str(_finalstr, filesum1); + filesum1[15] = '\0'; + filesum1[16] = '\0'; + + /* Second md is just the key */ + OS_MD5_Str(key, filesum2); + + /* Generate final key */ + snprintf(_finalstr, 49, "%s%s", filesum2, filesum1); + + /* Final key is 48 * 4 = 192bits */ + os_strdup(_finalstr, keys->keyentries[keys->keysize]->key); + + /* Clean final string from memory */ + memset_secure(_finalstr, '\0', sizeof(_finalstr)); + + /* Ready for next */ + keys->keysize++; + + return; +} + +/* Check if the authentication key file is present */ +int OS_CheckKeys() +{ + FILE *fp; + + if (File_DateofChange(KEYSFILE_PATH) < 0) { + merror(NO_AUTHFILE, __local_name, KEYSFILE_PATH); + merror(NO_CLIENT_KEYS, __local_name); + return (0); + } + + fp = fopen(KEYSFILE_PATH, "r"); + if (!fp) { + /* We can leave from here */ + merror(FOPEN_ERROR, __local_name, KEYSFILE_PATH, errno, strerror(errno)); + merror(NO_AUTHFILE, __local_name, KEYSFILE_PATH); + merror(NO_CLIENT_KEYS, __local_name); + return (0); + } + + fclose(fp); + + /* Authentication keys are present */ + return (1); +} + +/* Read the authentication keys */ +void OS_ReadKeys(keystore *keys) +{ + FILE *fp; + + char buffer[OS_BUFFER_SIZE + 1]; + + char name[KEYSIZE + 1]; + char ip[KEYSIZE + 1]; + char id[KEYSIZE + 1]; + char key[KEYSIZE + 1]; + + /* Check if the keys file is present and we can read it */ + if ((keys->file_change = File_DateofChange(KEYS_FILE)) < 0) { + merror(NO_AUTHFILE, __local_name, KEYS_FILE); + ErrorExit(NO_CLIENT_KEYS, __local_name); + + } + fp = fopen(KEYS_FILE, "r"); + if (!fp) { + /* We can leave from here */ + merror(FOPEN_ERROR, __local_name, KEYS_FILE, errno, strerror(errno)); + ErrorExit(NO_CLIENT_KEYS, __local_name); + + } + + /* Initialize hashes */ + keys->keyhash_id = OSHash_Create(); + keys->keyhash_ip = OSHash_Create(); + if (!keys->keyhash_id || !keys->keyhash_ip) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + + /* Initialize structure */ + os_calloc(1, sizeof(keyentry*), keys->keyentries); + keys->keysize = 0; + + /* Zero the buffers */ + __memclear(id, name, ip, key, KEYSIZE + 1); + memset(buffer, '\0', OS_BUFFER_SIZE + 1); + + /* Read each line. Lines are divided as "id name ip key" */ + while (fgets(buffer, OS_BUFFER_SIZE, fp) != NULL) { + char *tmp_str; + char *valid_str; + + if ((buffer[0] == '#') || (buffer[0] == ' ')) { + continue; + } + + /* Get ID */ + valid_str = buffer; + tmp_str = strchr(buffer, ' '); + if (!tmp_str) { + merror(INVALID_KEY, __local_name, buffer); + continue; + } + + *tmp_str = '\0'; + tmp_str++; + strncpy(id, valid_str, KEYSIZE - 1); + + /* Removed entry */ + if (*tmp_str == '#') { + continue; + } + + /* Get name */ + valid_str = tmp_str; + tmp_str = strchr(tmp_str, ' '); + if (!tmp_str) { + merror(INVALID_KEY, __local_name, buffer); + continue; + } + + *tmp_str = '\0'; + tmp_str++; + strncpy(name, valid_str, KEYSIZE - 1); + + /* Get IP address */ + valid_str = tmp_str; + tmp_str = strchr(tmp_str, ' '); + if (!tmp_str) { + merror(INVALID_KEY, __local_name, buffer); + continue; + } + + *tmp_str = '\0'; + tmp_str++; + strncpy(ip, valid_str, KEYSIZE - 1); + + /* Get key */ + valid_str = tmp_str; + tmp_str = strchr(tmp_str, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + strncpy(key, valid_str, KEYSIZE - 1); + + /* Generate the key hash */ + __chash(keys, id, name, ip, key); + + /* Clear the memory */ + __memclear(id, name, ip, key, KEYSIZE + 1); + + /* Check for maximum agent size */ + if (keys->keysize >= (MAX_AGENTS - 2)) { + merror(AG_MAX_ERROR, __local_name, MAX_AGENTS - 2); + ErrorExit(CONFIG_ERROR, __local_name, KEYS_FILE); + } + + continue; + } + + /* Close key file */ + fclose(fp); + + /* Clear one last time before leaving */ + __memclear(id, name, ip, key, KEYSIZE + 1); + + /* Check if there are any agents available */ + if (keys->keysize == 0) { + merror(NO_CLIENT_KEYS, __local_name); + if (!pass_empty_keyfile) { + exit(1); + } + } + + /* Add additional entry for sender == keysize */ + os_calloc(1, sizeof(keyentry), keys->keyentries[keys->keysize]); + + return; +} + +/* Free the auth keys */ +void OS_FreeKeys(keystore *keys) +{ + unsigned int i = 0; + unsigned int _keysize = 0; + OSHash *hashid; + OSHash *haship; + + _keysize = keys->keysize; + hashid = keys->keyhash_id; + haship = keys->keyhash_ip; + + /* Zero the entries */ + keys->keysize = 0; + keys->keyhash_id = NULL; + keys->keyhash_ip = NULL; + + /* Sleep to give time to other threads to stop using them */ + sleep(1); + + /* Free the hashes */ + OSHash_Free(hashid); + OSHash_Free(haship); + + for (i = 0; i <= _keysize; i++) { + if (keys->keyentries[i]) { + if (keys->keyentries[i]->ip) { + free(keys->keyentries[i]->ip->ip); + free(keys->keyentries[i]->ip); + } + + if (keys->keyentries[i]->id) { + free(keys->keyentries[i]->id); + } + + if (keys->keyentries[i]->key) { + free(keys->keyentries[i]->key); + } + + if (keys->keyentries[i]->name) { + free(keys->keyentries[i]->name); + } + + /* Close counter */ + if (keys->keyentries[i]->fp) { + fclose(keys->keyentries[i]->fp); + } + + free(keys->keyentries[i]); + keys->keyentries[i] = NULL; + } + } + + /* Free structure */ + free(keys->keyentries); + keys->keyentries = NULL; + keys->keysize = 0; +} + +/* Check if key changed */ +int OS_CheckUpdateKeys(const keystore *keys) +{ + if (keys->file_change != File_DateofChange(KEYS_FILE)) { + return (1); + } + return (0); +} + +/* Update the keys if changed */ +int OS_UpdateKeys(keystore *keys) +{ + if (keys->file_change != File_DateofChange(KEYS_FILE)) { + merror(ENCFILE_CHANGED, __local_name); + debug1("%s: DEBUG: Freekeys", __local_name); + + OS_FreeKeys(keys); + debug1("%s: DEBUG: OS_ReadKeys", __local_name); + + /* Read keys */ + verbose(ENC_READ, __local_name); + + OS_ReadKeys(keys); + debug1("%s: DEBUG: OS_StartCounter", __local_name); + + OS_StartCounter(keys); + debug1("%s: DEBUG: OS_UpdateKeys completed", __local_name); + + return (1); + } + return (0); +} + +/* Check if an IP address is allowed to connect */ +int OS_IsAllowedIP(keystore *keys, const char *srcip) +{ + keyentry *entry; + + if (srcip == NULL) { + return (-1); + } + + entry = (keyentry *) OSHash_Get(keys->keyhash_ip, srcip); + if (entry) { + return ((int)entry->keyid); + } + + return (-1); +} + +/* Check if the agent name is valid */ +int OS_IsAllowedName(const keystore *keys, const char *name) +{ + unsigned int i = 0; + + for (i = 0; i < keys->keysize; i++) { + if (strcmp(keys->keyentries[i]->name, name) == 0) { + return ((int)i); + } + } + + return (-1); +} + +int OS_IsAllowedID(keystore *keys, const char *id) +{ + keyentry *entry; + + if (id == NULL) { + return (-1); + } + + entry = (keyentry *) OSHash_Get(keys->keyhash_id, id); + if (entry) { + return ((int)entry->keyid); + } + return (-1); +} + + +/* Used for dynamic IP addresses */ +int OS_IsAllowedDynamicID(keystore *keys, const char *id, const char *srcip) +{ + keyentry *entry; + + if (id == NULL) { + return (-1); + } + + entry = (keyentry *) OSHash_Get(keys->keyhash_id, id); + if (entry) { + if (OS_IPFound(srcip, entry->ip)) { + return ((int)entry->keyid); + } + } + + return (-1); +} + /* Configure to pass if keys file is empty */ + void OS_PassEmptyKeyfile() { + pass_empty_keyfile = 1; + } diff --git a/src/os_crypto/shared/msgs.c b/src/os_crypto/shared/msgs.c new file mode 100644 index 000000000..6d4bffff0 --- /dev/null +++ b/src/os_crypto/shared/msgs.c @@ -0,0 +1,482 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "headers/sec.h" +#include "os_zlib/os_zlib.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/blowfish/bf_op.h" + +/* Prototypes */ +static void StoreSenderCounter(const keystore *keys, unsigned int global, unsigned int local) __attribute((nonnull)); +static void StoreCounter(const keystore *keys, int id, unsigned int global, unsigned int local) __attribute((nonnull)); +static char *CheckSum(char *msg) __attribute((nonnull)); + +/* Sending counts */ +static unsigned int global_count = 0; +static unsigned int local_count = 0; + +/* Average compression rates */ +static unsigned int evt_count = 0; +static unsigned int rcv_count = 0; +static size_t c_orig_size = 0; +static size_t c_comp_size = 0; + +/* Static variables (read from define file) */ +static unsigned int _s_comp_print = 0; +static unsigned int _s_recv_flush = 0; + +static int _s_verify_counter = 1; + + +/* Read counters for each agent */ +void OS_StartCounter(keystore *keys) +{ + unsigned int i; + char rids_file[OS_FLSIZE + 1]; + + rids_file[OS_FLSIZE] = '\0'; + + debug1("%s: OS_StartCounter: keysize: %u", __local_name, keys->keysize); + + /* Start receiving counter */ + for (i = 0; i <= keys->keysize; i++) { + /* On i == keysize, we deal with the sender counter */ + if (i == keys->keysize) { + snprintf(rids_file, OS_FLSIZE, "%s/%s", + RIDS_DIR, + SENDER_COUNTER); + } else { + snprintf(rids_file, OS_FLSIZE, "%s/%s", + RIDS_DIR, + keys->keyentries[i]->id); + } + + keys->keyentries[i]->fp = fopen(rids_file, "r+"); + + /* If nothing is there, try to open as write only */ + if (!keys->keyentries[i]->fp) { + keys->keyentries[i]->fp = fopen(rids_file, "w"); + if (!keys->keyentries[i]->fp) { + int my_error = errno; + + /* Just in case we run out of file descriptors */ + if ((i > 10) && (keys->keyentries[i - 1]->fp)) { + fclose(keys->keyentries[i - 1]->fp); + + if (keys->keyentries[i - 2]->fp) { + fclose(keys->keyentries[i - 2]->fp); + } + } + + merror("%s: Unable to open agent file. errno: %d", + __local_name, my_error); + ErrorExit(FOPEN_ERROR, __local_name, rids_file, errno, strerror(errno)); + } + } else { + unsigned int g_c = 0, l_c = 0; + if (fscanf(keys->keyentries[i]->fp, "%u:%u", &g_c, &l_c) != 2) { + if (i == keys->keysize) { + verbose("%s: INFO: No previous sender counter.", __local_name); + } else { + verbose("%s: INFO: No previous counter available for '%s'.", + __local_name, + keys->keyentries[i]->name); + } + + g_c = 0; + l_c = 0; + } + + if (i == keys->keysize) { + verbose("%s: INFO: Assigning sender counter: %u:%u", + __local_name, g_c, l_c); + global_count = g_c; + local_count = l_c; + } else { + verbose("%s: INFO: Assigning counter for agent %s: '%u:%u'.", + __local_name, keys->keyentries[i]->name, g_c, l_c); + + keys->keyentries[i]->global = g_c; + keys->keyentries[i]->local = l_c; + } + } + } + + debug2("%s: DEBUG: Stored counter.", __local_name); + + /* Get counter values */ + if (_s_recv_flush == 0) { + _s_recv_flush = (unsigned int) getDefine_Int("remoted", + "recv_counter_flush", + 10, 999999); + } + + /* Average printout values */ + if (_s_comp_print == 0) { + _s_comp_print = (unsigned int) getDefine_Int("remoted", + "comp_average_printout", + 10, 999999); + } + + + _s_verify_counter = getDefine_Int("remoted", "verify_msg_id" , 0, 1); +} + +/* Remove the ID counter */ +void OS_RemoveCounter(const char *id) +{ + char rids_file[OS_FLSIZE + 1]; + snprintf(rids_file, OS_FLSIZE, "%s/%s", RIDS_DIR, id); + if ((unlink(rids_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, rids_file, strerror(errno)); + } +} + +/* Store sender counter */ +static void StoreSenderCounter(const keystore *keys, unsigned int global, unsigned int local) +{ + /* Write to the beginning of the file */ + fseek(keys->keyentries[keys->keysize]->fp, 0, SEEK_SET); + fprintf(keys->keyentries[keys->keysize]->fp, "%u:%u:", global, local); +} + +/* Store the global and local count of events */ +static void StoreCounter(const keystore *keys, int id, unsigned int global, unsigned int local) +{ + /* Write to the beginning of the file */ + fseek(keys->keyentries[id]->fp, 0, SEEK_SET); + fprintf(keys->keyentries[id]->fp, "%u:%u:", global, local); +} + +/* Verify the checksum of the message + * Returns NULL on error or the message on success + */ +static char *CheckSum(char *msg) +{ + os_md5 recvd_sum; + os_md5 checksum; + + /* Better way */ + strncpy(recvd_sum, msg, 32); + recvd_sum[32] = '\0'; + + msg += 32; + + OS_MD5_Str(msg, checksum); + if (strncmp(checksum, recvd_sum, 32) != 0) { + return (NULL); + } + + return (msg); +} + +char *ReadSecMSG(keystore *keys, char *buffer, char *cleartext, + int id, unsigned int buffer_size) +{ + unsigned int msg_global = 0; + unsigned int msg_local = 0; + char *f_msg; + + if (*buffer == ':') { + buffer++; + } else { + merror(ENCFORMAT_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + + /* Decrypt message */ + if (!OS_BF_Str(buffer, cleartext, keys->keyentries[id]->key, + buffer_size, OS_DECRYPT)) { + merror(ENCKEY_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + + /* Compressed */ + else if (cleartext[0] == '!') { + cleartext[buffer_size] = '\0'; + cleartext++; + buffer_size--; + + /* Remove padding */ + while (*cleartext == '!') { + cleartext++; + buffer_size--; + } + + /* Uncompress */ + if (!os_zlib_uncompress(cleartext, buffer, buffer_size, OS_MAXSTR)) { + merror(UNCOMPRESS_ERR, __local_name); + return (NULL); + } + + /* Check checksum */ + f_msg = CheckSum(buffer); + if (f_msg == NULL) { + merror(ENCSUM_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + + /* Remove random */ + f_msg += 5; + + /* Check count -- protect against replay attacks */ + msg_global = (unsigned int) atoi(f_msg); + f_msg += 10; + + /* Check for the right message format */ + if (*f_msg != ':') { + merror(ENCFORMAT_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + f_msg++; + + msg_local = (unsigned int) atoi(f_msg); + f_msg += 5; + + /* Return the message if we don't need to verify the counter */ + if (!_s_verify_counter) { + /* Update current counts */ + keys->keyentries[id]->global = msg_global; + keys->keyentries[id]->local = msg_local; + if (rcv_count >= _s_recv_flush) { + StoreCounter(keys, id, msg_global, msg_local); + rcv_count = 0; + } + rcv_count++; + return (f_msg); + } + + + if ((msg_global > keys->keyentries[id]->global) || + ((msg_global == keys->keyentries[id]->global) && + (msg_local > keys->keyentries[id]->local))) { + /* Update current counts */ + keys->keyentries[id]->global = msg_global; + keys->keyentries[id]->local = msg_local; + + if (rcv_count >= _s_recv_flush) { + StoreCounter(keys, id, msg_global, msg_local); + rcv_count = 0; + } + rcv_count++; + return (f_msg); + } + + /* Check if it is a duplicated message */ + if (msg_global == keys->keyentries[id]->global) { + /* Warn about duplicated messages */ + merror("%s: WARN: Duplicate error: global: %u, local: %u, " + "saved global: %u, saved local:%u", + __local_name, + msg_global, + msg_local, + keys->keyentries[id]->global, + keys->keyentries[id]->local); + + merror(ENCTIME_ERROR, __local_name, keys->keyentries[id]->name); + return (NULL); + } + } + + /* Old format */ + else if (cleartext[0] == ':') { + unsigned int msg_count; + unsigned int msg_time; + + /* Close string */ + cleartext[buffer_size] = '\0'; + + /* Check checksum */ + cleartext++; + f_msg = CheckSum(cleartext); + if (f_msg == NULL) { + merror(ENCSUM_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + + /* Check time -- protect against replay attacks */ + msg_time = (unsigned int) atoi(f_msg); + f_msg += 11; + + msg_count = (unsigned int) atoi(f_msg); + f_msg += 5; + + + /* Return the message if we don't need to verify the counter */ + if (!_s_verify_counter) { + /* Update current counts */ + keys->keyentries[id]->global = msg_time; + keys->keyentries[id]->local = msg_local; + + f_msg = strchr(f_msg, ':'); + if (f_msg) { + f_msg++; + return (f_msg); + } else { + merror(ENCFORMAT_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + } + + + if ((msg_time > keys->keyentries[id]->global) || + ((msg_time == keys->keyentries[id]->global) && + (msg_count > keys->keyentries[id]->local))) { + /* Update current time and count */ + keys->keyentries[id]->global = msg_time; + keys->keyentries[id]->local = msg_count; + + f_msg = strchr(f_msg, ':'); + if (f_msg) { + f_msg++; + return (f_msg); + } else { + merror(ENCFORMAT_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); + } + } + + /* Check if it is a duplicated message */ + if ((msg_count == keys->keyentries[id]->local) && + (msg_time == keys->keyentries[id]->global)) { + return (NULL); + } + + /* Warn about duplicated message */ + merror("%s: WARN: Duplicate error: msg_count: %u, time: %u, " + "saved count: %u, saved_time:%u", + __local_name, + msg_count, + msg_time, + keys->keyentries[id]->local, + keys->keyentries[id]->global); + + merror(ENCTIME_ERROR, __local_name, keys->keyentries[id]->name); + return (NULL); + } + + merror(ENCFORMAT_ERROR, __local_name, keys->keyentries[id]->ip->ip); + return (NULL); +} + +/* Create an encrypted message + * Returns the size + */ +size_t CreateSecMSG(const keystore *keys, const char *msg, char *msg_encrypted, unsigned int id) +{ + size_t bfsize; + size_t msg_size; + unsigned long int cmp_size; + u_int16_t rand1; + char _tmpmsg[OS_MAXSTR + 2]; + char _finmsg[OS_MAXSTR + 2]; + os_md5 md5sum; + + msg_size = strlen(msg); + + /* Check for invalid msg sizes */ + if ((msg_size > (OS_MAXSTR - OS_HEADER_SIZE)) || (msg_size < 1)) { + merror(ENCSIZE_ERROR, __local_name, msg); + return (0); + } + + /* Random number, take only 5 chars ~= 2^16=65536*/ + rand1 = (u_int16_t) random(); + + _tmpmsg[OS_MAXSTR + 1] = '\0'; + _finmsg[OS_MAXSTR + 1] = '\0'; + msg_encrypted[OS_MAXSTR] = '\0'; + + /* Increase local and global counters */ + if (local_count >= 9997) { + local_count = 0; + global_count++; + } + local_count++; + + snprintf(_tmpmsg, OS_MAXSTR, "%05hu%010u:%04u:%s", + rand1, global_count, local_count, + msg); + + /* Generate MD5 of the unencrypted string */ + OS_MD5_Str(_tmpmsg, md5sum); + + /* Generate final msg to be compressed */ + snprintf(_finmsg, OS_MAXSTR, "%s%s", md5sum, _tmpmsg); + msg_size = strlen(_finmsg); + + /* Compress the message + * We assign the first 8 bytes for padding + */ + cmp_size = os_zlib_compress(_finmsg, _tmpmsg + 8, msg_size, OS_MAXSTR - 12); + if (!cmp_size) { + merror(COMPRESS_ERR, __local_name, _finmsg); + return (0); + } + cmp_size++; + + /* Pad the message (needs to be div by 8) */ + bfsize = 8 - (cmp_size % 8); + if (bfsize == 8) { + bfsize = 0; + } + + _tmpmsg[0] = '!'; + _tmpmsg[1] = '!'; + _tmpmsg[2] = '!'; + _tmpmsg[3] = '!'; + _tmpmsg[4] = '!'; + _tmpmsg[5] = '!'; + _tmpmsg[6] = '!'; + _tmpmsg[7] = '!'; + + cmp_size += bfsize; + + /* Get average sizes */ + c_orig_size += msg_size; + c_comp_size += cmp_size; + if (evt_count > _s_comp_print) { + verbose("%s: INFO: Event count after '%u': %lu->%lu (%lu%%)", __local_name, + evt_count, + (unsigned long)c_orig_size, + (unsigned long)c_comp_size, + (unsigned long)((c_comp_size * 100) / c_orig_size)); + evt_count = 0; + c_orig_size = 0; + c_comp_size = 0; + } + evt_count++; + + /* If the IP is dynamic (not single host), append agent ID to the message */ + if (!isSingleHost(keys->keyentries[id]->ip) && isAgent) { + snprintf(msg_encrypted, 16, "!%s!:", keys->keyentries[id]->id); + msg_size = strlen(msg_encrypted); + } else { + /* Set beginning of the message */ + msg_encrypted[0] = ':'; + msg_size = 1; + } + + /* msg_size is the amount of non-encrypted message appended to the buffer + * On dynamic IPs, it will include the agent ID + */ + + /* Encrypt everything */ + OS_BF_Str(_tmpmsg + (7 - bfsize), msg_encrypted + msg_size, + keys->keyentries[id]->key, + (long) cmp_size, + OS_ENCRYPT); + + /* Store before leaving */ + StoreSenderCounter(keys, global_count, local_count); + + return (cmp_size + msg_size); +} + diff --git a/src/os_csyslogd/alert.c b/src/os_csyslogd/alert.c new file mode 100644 index 000000000..43a21eac7 --- /dev/null +++ b/src/os_csyslogd/alert.c @@ -0,0 +1,393 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include + +#include "csyslogd.h" +#include "cJSON.h" +#include "config/config.h" +#include "os_net/os_net.h" + + +/* Escape CEF messages according to the standards */ +char *cefescape(const char *msg, const bool header) +{ + static char *buffer = NULL; + const char *ptr; + char *buffptr; + size_t size; + + /* Recycle the buffer */ + if (buffer) { + os_free(buffer); + buffer = NULL; + } + + /* Test if the string needs escaping */ + if ((NULL == msg) || /* Cleanup call or empty string */ + ((header && (NULL == strchr(msg, '|'))) && /* | in the header must be escaped */ + (!header && (NULL == strchr(msg, '='))) && /* = in the extension must be escaped */ + (NULL == strchr(msg, '\\')) && /* \ must be escaped */ + (NULL == strchr(msg, '\r')) && /* \r removed from header, escaped in extension */ + (NULL == strchr(msg, '\n')))) { /* \n removed from header, escaped in extension */ + return buffer; + } + + /* Calculate the size of the escaped message + * + * In the header we replace \r and \n with a + * space, so there's no change in size. + */ + ptr = msg; + size = 1; + while (*ptr) { + if (('\\' == *ptr) || + (header && ('|' == *ptr)) || + (!header && ( + ('=' == *ptr) || + ('\r' == *ptr) || + ('\n' == *ptr) + ))) + { + size += 2; + } else { + size += 1; + } + ptr++; + } + + /* Allocate the new buffer and start escaping */ + buffer = (char*) malloc(size); + buffer[size-1] = '\0'; + ptr = msg; + buffptr = buffer; + while (*ptr) { + if ('\\' == *ptr) { + *buffptr = '\\'; + *(buffptr + 1) = '\\'; + buffptr += 2; + } else if ('\r' == *ptr) { + *buffptr = header ? ' ' : '\\'; + buffptr++; + if (!header) { + *buffptr = 'r'; + buffptr++; + } + } else if ('\n' == *ptr) { + *buffptr = header ? ' ' : '\\'; + buffptr++; + if (!header) { + *buffptr = 'n'; + buffptr++; + } + } else if (header && ('|' == *ptr)) { + *buffptr = '\\'; + *(buffptr + 1) = '|'; + buffptr += 2; + } else if (!header && ('=' == *ptr)) { + *buffptr = '\\'; + *(buffptr + 1) = '='; + buffptr += 2; + } else { + *buffptr = *ptr; + buffptr++; + } + ptr++; + } + + return buffer; +} + +/* Send an alert via syslog + * Returns 1 on success or 0 on error + */ +int OS_Alert_SendSyslog(alert_data *al_data, const SyslogConfig *syslog_config) +{ + char *logmsg = NULL; + char *tstamp; + char *hostname; + char syslog_msg[OS_SIZE_2048]; + + /* Invalid socket */ + if (syslog_config->socket < 0) { + return (0); + } + + /* Clear the memory before insert */ + memset(syslog_msg, '\0', OS_SIZE_2048); + + /* Look if location is set */ + if (syslog_config->location) { + if (!OSMatch_Execute(al_data->location, + strlen(al_data->location), + syslog_config->location)) { + return (0); + } + } + + /* Look for the level */ + if (syslog_config->level) { + if (al_data->level < syslog_config->level) { + return (0); + } + } + + /* Look for rule id */ + if (syslog_config->rule_id) { + int id_i = 0; + while (syslog_config->rule_id[id_i] != 0) { + if (syslog_config->rule_id[id_i] == al_data->rule) { + break; + } + id_i++; + } + + /* If we found, id is going to be a valid rule */ + if (!syslog_config->rule_id[id_i]) { + return (0); + } + } + + /* Look for the group */ + if (syslog_config->group) { + if (!OSMatch_Execute(al_data->group, + strlen(al_data->group), + syslog_config->group)) { + return (0); + } + } + + /* Fix the timestamp to be syslog compatible + * We have 2008 Jul 10 10:11:23 + * Should be: Jul 10 10:11:23 + */ + tstamp = al_data->date; + if (strlen(al_data->date) > 14) { + tstamp += 5; + + /* Fix first digit if the day is < 10 */ + if (tstamp[4] == '0') { + tstamp[4] = ' '; + } + } + + if (syslog_config->use_fqdn) { + hostname = __shost_long; + } else { + hostname = __shost; + } + + /* Walk the log lines */ + if (al_data->log && al_data->log[0]) { + if (NULL == al_data->log[1]) { + logmsg = al_data->log[0]; + } else { + short int i = 0; + while (NULL != al_data->log[i]) { + logmsg = os_LoadString(logmsg, al_data->log[i]); + i++; + if (NULL != al_data->log[i]) { + logmsg = os_LoadString(logmsg, "\n"); + } + /* Save on memory and processing since it's going to get truncated anyway */ + if (OS_SIZE_2048 <= strlen(logmsg)) { + break; + } + } + } + } + + /* Insert data */ + if (syslog_config->format == DEFAULT_CSYSLOG) { + /* Build syslog message */ + snprintf(syslog_msg, OS_SIZE_2048, + "<%u>%s %s openarmor: Alert Level: %u; Rule: %u - %s; Location: %s;", + syslog_config->priority, tstamp, hostname, + al_data->level, + al_data->rule, al_data->comment, + al_data->location + ); + field_add_string(syslog_msg, OS_SIZE_2048, " classification: %s;", al_data->group); + field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip); +#ifdef LIBGEOIP_ENABLED + field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->srcgeoip); + field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->dstgeoip); +#endif + field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip); + field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user); + field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5); + field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5); + field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1); + field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1); + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + field_add_string(syslog_msg, OS_SIZE_2048, " Size changed: from %s;", al_data->file_size); + field_add_string(syslog_msg, OS_SIZE_2048, " User ownership: was %s;", al_data->owner_chg); + field_add_string(syslog_msg, OS_SIZE_2048, " Group ownership: was %s;", al_data->group_chg); + field_add_string(syslog_msg, OS_SIZE_2048, " Permissions changed: from %s;", al_data->perm_chg); + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", logmsg, 2); + } else if (syslog_config->format == CEF_CSYSLOG) { + /* Start with headers */ + snprintf(syslog_msg, OS_SIZE_2048, + "<%u>%s CEF:0|%s|%s|%s|%u|%s|%u|", + syslog_config->priority, + tstamp, + __author, + __openarmor_name, + __openarmor_version, + al_data->rule, + cefescape(al_data->comment, true), + (al_data->level > 10) ? 10 : al_data->level); + /* Add extensions */ + field_add_string(syslog_msg, OS_SIZE_2048, "dvc=%s", cefescape(hostname, false)); + field_add_string(syslog_msg, OS_SIZE_2048, " cs1Label=Location cs1=%s", cefescape(al_data->location, false)); + field_add_string(syslog_msg, OS_SIZE_2048, " classification=%s", cefescape(al_data->group, false)); + field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip); + field_add_int(syslog_msg, OS_SIZE_2048, " dpt=%d", al_data->dstport); + field_add_int(syslog_msg, OS_SIZE_2048, " spt=%d", al_data->srcport); + field_add_string(syslog_msg, OS_SIZE_2048, " fname=%s", cefescape(al_data->filename, false)); + field_add_string(syslog_msg, OS_SIZE_2048, " dhost=%s", al_data->dstip); + field_add_string(syslog_msg, OS_SIZE_2048, " shost=%s", al_data->srcip); + field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", cefescape(al_data->user, false)); + field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", cefescape(al_data->dstip, false)); +#ifdef LIBGEOIP_ENABLED + field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=SrcCity cs4=%s", cefescape(al_data->srcgeoip, false)); + field_add_string(syslog_msg, OS_SIZE_2048, " cs5Label=DstCity cs5=%s", cefescape(al_data->dstgeoip, false)); +#endif + if (al_data->new_md5 && al_data->new_sha1) { + field_add_string(syslog_msg, OS_SIZE_2048, " cs2Label=OldMD5 cs2=%s", al_data->old_md5); + field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=NewMD5 cs3=%s", al_data->new_md5); + field_add_string(syslog_msg, OS_SIZE_2048, " oldFileHash=%s", al_data->old_sha1); + field_add_string(syslog_msg, OS_SIZE_2048, " fhash=%s", al_data->new_sha1); + field_add_string(syslog_msg, OS_SIZE_2048, " fileHash=%s", al_data->new_sha1); + } + field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", cefescape(logmsg, false), 2); + cefescape(NULL,0); /* Clean up the escaping buffer */ + } else if (syslog_config->format == JSON_CSYSLOG) { + /* Build a JSON Object for logging */ + cJSON *root; + char *json_string; + root = cJSON_CreateObject(); + + /* Data guaranteed to be there */ + cJSON_AddNumberToObject(root, "crit", al_data->level); + cJSON_AddNumberToObject(root, "id", al_data->rule); + cJSON_AddStringToObject(root, "component", al_data->location); + + /* Rule Meta Data */ + if (al_data->group) { + cJSON_AddStringToObject(root, "classification", al_data->group); + } + if (al_data->comment) { + cJSON_AddStringToObject(root, "description", al_data->comment); + } + + /* Raw log message generating event */ + if (logmsg) { + cJSON_AddStringToObject(root, "message", logmsg); + } + + /* Add data if it exists */ + if (al_data->user) { + cJSON_AddStringToObject(root, "acct", al_data->user); + } + if (al_data->srcip) { + cJSON_AddStringToObject(root, "src_ip", al_data->srcip); + } + if (al_data->srcport) { + cJSON_AddNumberToObject(root, "src_port", al_data->srcport); + } + if (al_data->dstip) { + cJSON_AddStringToObject(root, "dst_ip", al_data->dstip); + } + if (al_data->dstport) { + cJSON_AddNumberToObject(root, "dst_port", al_data->dstport); + } + if (al_data->filename) { + cJSON_AddStringToObject(root, "file", al_data->filename); + } + if (al_data->old_md5) { + cJSON_AddStringToObject(root, "md5_old", al_data->old_md5); + } + if (al_data->new_md5) { + cJSON_AddStringToObject(root, "md5_new", al_data->new_md5); + } + if (al_data->old_sha1) { + cJSON_AddStringToObject(root, "sha1_old", al_data->old_sha1); + } + if (al_data->new_sha1) { + cJSON_AddStringToObject(root, "sha1_new", al_data->new_sha1); + } +#ifdef LIBGEOIP_ENABLED + if (al_data->srcgeoip) { + cJSON_AddStringToObject(root, "src_city", al_data->srcgeoip); + } + if (al_data->dstgeoip) { + cJSON_AddStringToObject(root, "dst_city", al_data->dstgeoip); + } +#endif + + /* Create the JSON string */ + json_string = cJSON_PrintUnformatted(root); + + /* Create the syslog message */ + snprintf(syslog_msg, OS_SIZE_2048, + "<%u>%s %s openarmor: %s", + + /* syslog header */ + syslog_config->priority, tstamp, hostname, + + /* JSON Encoded Data */ + json_string + ); + /* Clean up the memory for the JSON structure */ + free(json_string); + cJSON_Delete(root); + } else if (syslog_config->format == SPLUNK_CSYSLOG) { + /* Build a Splunk Style Key/Value string for logging */ + snprintf(syslog_msg, OS_SIZE_2048, + "<%u>%s %s openarmor: crit=%u id=%u description=\"%s\" component=\"%s\",", + + /* syslog header */ + syslog_config->priority, tstamp, hostname, + + /* openarmor metadata */ + al_data->level, al_data->rule, al_data->comment, + al_data->location + ); + /* Event specifics */ + field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group); + + if (field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip) > 0) { + field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport); + } + +#ifdef LIBGEOIP_ENABLED + field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->srcgeoip); + field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->dstgeoip); +#endif + + if (field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip) > 0) { + field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport); + } + + field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename); + field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user); + field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5); + field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5); + field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1); + field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1); + /* Message */ + field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", logmsg, 2); + } + + OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg); + return (1); +} + diff --git a/src/os_csyslogd/config.c b/src/os_csyslogd/config.c new file mode 100644 index 000000000..122abf5ae --- /dev/null +++ b/src/os_csyslogd/config.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "csyslogd.h" +#include "config/global-config.h" +#include "config/config.h" + + +/* Read configuration */ +SyslogConfig **OS_ReadSyslogConf(__attribute__((unused)) int test_config, const char *cfgfile) +{ + int modules = 0; + struct SyslogConfig_holder config; + SyslogConfig **syslog_config = NULL; + + /* Modules for the configuration */ + modules |= CSYSLOGD; + config.data = syslog_config; + + /* Read configuration */ + if (ReadConfig(modules, cfgfile, &config, NULL) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfgfile); + return (NULL); + } + + syslog_config = config.data; + + return (syslog_config); +} + diff --git a/src/os_csyslogd/csyslogd.c b/src/os_csyslogd/csyslogd.c new file mode 100644 index 000000000..21cf651b9 --- /dev/null +++ b/src/os_csyslogd/csyslogd.c @@ -0,0 +1,178 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "csyslogd.h" +#include "os_net/os_net.h" + +/* Global variables */ +char __shost[512]; +char __shost_long[512]; + + +/* Monitor the alerts and send them via syslog + * Only return in case of error + */ +void OS_CSyslogD(SyslogConfig **syslog_config) +{ + int s = 0; + time_t tm; + struct tm *p; + int tries = 0; + file_queue *fileq; + alert_data *al_data; + + /* Get current time before starting */ + tm = time(NULL); + p = localtime(&tm); + + /* Initialize file queue to read the alerts */ + os_calloc(1, sizeof(file_queue), fileq); + while ( (Init_FileQueue(fileq, p, 0) ) < 0 ) { + tries++; + if ( tries > OS_CSYSLOGD_MAX_TRIES ) { + merror("%s: ERROR: Could not open queue after %d tries, exiting!", + ARGV0, tries + ); + exit(1); + } + sleep(1); + } + debug1("%s: INFO: File queue connected.", ARGV0 ); + + /* Connect to syslog */ + s = 0; + while (syslog_config[s]) { + syslog_config[s]->socket = OS_ConnectUDP(syslog_config[s]->port, + syslog_config[s]->server); + if (syslog_config[s]->socket < 0) { + merror(CONNS_ERROR, ARGV0, syslog_config[s]->server); + } else { + merror("%s: INFO: Forwarding alerts via syslog to: '%s:%s'.", + ARGV0, syslog_config[s]->server, syslog_config[s]->port); + } + + s++; + } + + /* Infinite loop reading the alerts and inserting them */ + while (1) { + tm = time(NULL); + p = localtime(&tm); + + /* Get message if available (timeout of 5 seconds) */ + al_data = Read_FileMon(fileq, p, 5); + if (!al_data) { + continue; + } + + /* Send via syslog */ + s = 0; + while (syslog_config[s]) { + OS_Alert_SendSyslog(al_data, syslog_config[s]); + s++; + } + + /* Clear the memory */ + FreeAlertData(al_data); + } +} + +/* Format Field for output */ +int field_add_string(char *dest, size_t size, const char *format, const char *value ) +{ + char buffer[OS_SIZE_2048]; + int len = 0; + int dest_sz = size - strlen(dest); + + /* Not enough room in the buffer? */ + if (dest_sz <= 0 ) { + return -1; + } + + if (value != NULL && + ( + ((value[0] != '(') && (value[1] != 'n') && (value[2] != 'o')) || + ((value[0] != '(') && (value[1] != 'u') && (value[2] != 'n')) || + ((value[0] != 'u') && (value[1] != 'n') && (value[4] != 'k')) + ) + ) { + len = snprintf(buffer, sizeof(buffer) - dest_sz - 1, format, value); + strncat(dest, buffer, dest_sz); + } + + return len; +} + +/* Add a field, but truncate if too long */ +int field_add_truncated(char *dest, size_t size, const char *format, const char *value, int fmt_size ) +{ + char buffer[OS_SIZE_2048]; + + int available_sz = size - strlen(dest); + int total_sz = strlen(value) + strlen(format) - fmt_size; + int field_sz = available_sz - strlen(format) + fmt_size; + + int len = 0; + char trailer[] = "..."; + char *truncated = NULL; + + /* Not enough room in the buffer? */ + if (available_sz <= 0 ) { + return -1; + } + + if ( + ((value[0] != '(') && (value[1] != 'n') && (value[2] != 'o')) || + ((value[0] != '(') && (value[1] != 'u') && (value[2] != 'n')) || + ((value[0] != 'u') && (value[1] != 'n') && (value[4] != 'k')) + ) { + + if ( (truncated = (char *) malloc(field_sz + 1)) != NULL ) { + if ( total_sz > available_sz ) { + /* Truncate and add a trailer */ + os_substr(truncated, value, 0, field_sz - strlen(trailer)); + strcat(truncated, trailer); + } else { + strncpy(truncated, value, field_sz); + } + + len = snprintf(buffer, available_sz, format, truncated); + strncat(dest, buffer, available_sz); + } else { + /* Memory Error */ + len = -3; + } + } + /* Free the temporary pointer */ + free(truncated); + + return len; +} + +/* Handle integers in the second position */ +int field_add_int(char *dest, size_t size, const char *format, const int value ) +{ + char buffer[255]; + int len = 0; + int dest_sz = size - strlen(dest); + + /* Not enough room in the buffer? */ + if (dest_sz <= 0 ) { + return -1; + } + + if ( value > 0 ) { + len = snprintf(buffer, sizeof(buffer), format, value); + strncat(dest, buffer, dest_sz); + } + + return len; +} + diff --git a/src/os_csyslogd/csyslogd.h b/src/os_csyslogd/csyslogd.h new file mode 100644 index 000000000..c2fb91996 --- /dev/null +++ b/src/os_csyslogd/csyslogd.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _CSYSLOGD_H +#define _CSYSLOGD_H + +#include "config/csyslogd-config.h" + +#define OS_CSYSLOGD_MAX_TRIES 10 + +/** Prototypes **/ + +/* Read syslog config */ +SyslogConfig **OS_ReadSyslogConf(int test_config, const char *cfgfile); + +/* Send alerts via syslog */ +int OS_Alert_SendSyslog(alert_data *al_data, const SyslogConfig *syslog_config); + +/* Database inserting main function */ +void OS_CSyslogD(SyslogConfig **syslog_config) __attribute__((noreturn)); + +/* Conditional Field Formatting */ +int field_add_int(char *dest, size_t size, const char *format, const int value ); +int field_add_string(char *dest, size_t size, const char *format, const char *value ); +int field_add_truncated(char *dest, size_t size, const char *format, const char *value, int fmt_size ); + +/** Global variables **/ + +/* System hostname */ +extern char __shost[512]; +/* System hostname (full length) */ +extern char __shost_long[512]; + +#endif /* _CSYSLOGD_H */ + diff --git a/src/os_csyslogd/main.c b/src/os_csyslogd/main.c new file mode 100644 index 000000000..1aa35dea5 --- /dev/null +++ b/src/os_csyslogd/main.c @@ -0,0 +1,185 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "csyslogd.h" + +/* Prototypes */ +static void help_csyslogd(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_csyslogd() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", MAILUSER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, test_config = 0, run_foreground = 0; + uid_t uid; + gid_t gid; + + /* Use MAILUSER (read only) */ + const char *dir = DEFAULTDIR; + const char *user = MAILUSER; + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + /* Database Structure */ + SyslogConfig **syslog_config; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_csyslogd(); + break; + case 'd': + nowDebug(); + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_csyslogd(); + break; + } + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Read configuration */ + syslog_config = OS_ReadSyslogConf(test_config, cfg); + + /* Get server hostname */ + memset(__shost, '\0', 512); + if (gethostname(__shost, 512 - 1) != 0) { + ErrorExit("%s: ERROR: gethostname() failed", ARGV0); + } else { + /* Save the full hostname */ + memcpy(__shost_long, __shost, 512); + + char *ltmp; + + /* Remove domain part if available */ + ltmp = strchr(__shost, '.'); + if (ltmp) { + *ltmp = '\0'; + } + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + if (!run_foreground) { + /* Going on daemon mode */ + nowDaemon(); + goDaemon(); + } + + /* Not configured */ + if (!syslog_config || !syslog_config[0]) { + verbose("%s: INFO: Remote syslog server not configured. " + "Clean exit.", ARGV0); + exit(0); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + /* Now in chroot */ + nowChroot(); + + /* Change user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + /* Basic start up completed */ + debug1(CHROOT_MSG, ARGV0, dir); + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real daemon now */ + OS_CSyslogD(syslog_config); +} + diff --git a/src/os_dbd/README b/src/os_dbd/README new file mode 100644 index 000000000..881d65636 --- /dev/null +++ b/src/os_dbd/README @@ -0,0 +1,46 @@ +# Simple readme with some query examples. +# Examples for MySQL and PostgreSQL + + +1- View all rules: + +> SELECT rule_id, level, description FROM signature; + + +2- View all categories (groups) + +> SELECT * FROM category; + + +3- View all categories of a specific rule (1002 for example): + +> SELECT rule_id, cat_name from category, signature_category_mapping WHERE rule_id = 1002 AND signature_category_mapping.cat_id = category.cat_id; + + +4- View all alerts (without data): + +> SELECT * FROM alert; + + +5- View all alerts (with IP as string): + +> SELECT rule_id, timestamp, INET_NTOA(src_ip) srcip from alert; + + +6- View all alerts, including locations (IP as string and time as string): + +MySQL: +>SELECT FROM_UNIXTIME(timestamp) time, rule_id,location.name location, INET_NTOA(src_ip) srcip, full_log FROM alert,location, data WHERE location.id = alert.location_id AND data.id = alert.id AND data.server_id = alert.server_id; + +PostgreSQL: +>SELECT to_timestamp(timestamp), rule_id, location.name, full_log FROM alert,location, data WHERE location.id = alert.location_id AND data.id = alert.id AND data.server_id = alert.server_id; + +Output: + ++---------------------+---------+---------------------------+--------------+--------------------------------------------------------------------------------------------------+ +| time | rule_id | location | srcip | full_log | ++---------------------+---------+---------------------------+--------------+--------------------------------------------------------------------------------------------------+ +| 2007-08-18 00:28:49 | 1002 | enigma->/var/log/messages | 0.0.0.0 | Aug 18 00:28:49 enigma dcid: Segmentation Fault 1q2 | +| 2007-08-18 00:38:06 | 5715 | enigma->/var/log/authlog | 192.168.2.10 | Aug 18 00:38:02 enigma sshd[24284]: Accepted password for dcid from 192.168.2.10 port 34631 ssh2 | +| 2007-08-18 00:38:21 | 5715 | enigma->/var/log/authlog | 192.168.2.10 | Aug 18 00:38:15 enigma sshd[20749]: Accepted password for dcid from 192.168.2.10 port 35755 ssh2 | ++---------------------+---------+---------------------------+--------------+--------------------------------------------------------------------------------------------------+ diff --git a/src/os_dbd/alert.c b/src/os_dbd/alert.c new file mode 100644 index 000000000..b37fae3bc --- /dev/null +++ b/src/os_dbd/alert.c @@ -0,0 +1,206 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "dbd.h" +#include "config/config.h" +#include "config/dbd-config.h" +#include "rules_op.h" + +/* Prototypes */ +static int __DBSelectLocation(const char *location, const DBConfig *db_config) __attribute__((nonnull)); +static int __DBInsertLocation(const char *location, const DBConfig *db_config) __attribute__((nonnull)); + + +/* Select the maximum ID from the alert table + * Returns 0 if not found + */ +int OS_SelectMaxID(const DBConfig *db_config) +{ + int result = 0; + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "SELECT MAX(id) FROM " + "alert WHERE server_id = '%u'", + db_config->server_id); + + result = osdb_query_select(db_config->conn, sql_query); + + return (result); +} + + +/* Select the location ID from the db + * Returns 0 if not found + */ +static int __DBSelectLocation(const char *location, const DBConfig *db_config) +{ + int result = 0; + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "SELECT id FROM " + "location WHERE name = '%s' AND server_id = '%d' " + "LIMIT 1", + location, db_config->server_id); + + result = osdb_query_select(db_config->conn, sql_query); + + return (result); +} + +/* Insert location in to the db */ +static int __DBInsertLocation(const char *location, const DBConfig *db_config) +{ + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "INSERT INTO " + "location(server_id, name) " + "VALUES ('%u', '%s')", + db_config->server_id, location); + + if (!osdb_query_insert(db_config->conn, sql_query)) { + merror(DB_GENERROR, ARGV0); + } + + return (0); +} + +/* Insert alert into to the db + * Returns 1 on success or 0 on error + */ +int OS_Alert_InsertDB(const alert_data *al_data, DBConfig *db_config) +{ + int i; + unsigned int location_id = 0; + unsigned short s_port = 0, d_port = 0; + int *loc_id; + char sql_query[OS_SIZE_8192 + 1]; + char *fulllog = NULL; + + /* Clear the memory before insert */ + sql_query[0] = '\0'; + sql_query[OS_SIZE_8192] = '\0'; + + /* Source Port */ + s_port = al_data->srcport; + + /* Destination Port */ + d_port = al_data->dstport; + + /* Escape strings */ + osdb_escapestr(al_data->user); + osdb_escapestr(al_data->location); + + /* We first need to insert the location */ + loc_id = (int *) OSHash_Get(db_config->location_hash, al_data->location); + + /* If we dont have location id, we must select and/or insert in the db */ + if (!loc_id) { + location_id = __DBSelectLocation(al_data->location, db_config); + if (location_id == 0) { + /* Insert it */ + __DBInsertLocation(al_data->location, db_config); + location_id = __DBSelectLocation(al_data->location, db_config); + } + + if (!location_id) { + merror("%s: Unable to insert location: '%s'.", + ARGV0, al_data->location); + return (0); + } + + /* Add to hash */ + os_calloc(1, sizeof(int), loc_id); + *loc_id = location_id; + OSHash_Add(db_config->location_hash, al_data->location, loc_id); + } + + i = 0; + while (al_data->log[i]) { + size_t len = strlen(al_data->log[i]); + char templog[len + 2]; + if (al_data->log[i + 1]) { + snprintf(templog, len + 2, "%s\n", al_data->log[i]); + } else { + snprintf(templog, len + 1, "%s", al_data->log[i]); + } + fulllog = os_LoadString(fulllog, templog); + i++; + } + + if (fulllog == NULL) { + merror("%s: Unable to process log.", ARGV0); + return (0); + } + + osdb_escapestr(fulllog); + if (strlen(fulllog) > 7456) { + fulllog[7454] = '.'; + fulllog[7455] = '.'; + fulllog[7456] = '\0'; + } + + /* Generate final SQL */ + switch (db_config->db_type) { + case MYSQLDB: + snprintf(sql_query, OS_SIZE_8192, + "INSERT INTO " + "alert(server_id,rule_id,level,timestamp,location_id,src_ip,src_port,dst_ip,dst_port,alertid,user,full_log,tld) " + "VALUES ('%u', '%u','%u','%u', '%u', '%s', '%u', '%s', '%u', '%s', '%s', '%s','%.2s')", + db_config->server_id, al_data->rule, + al_data->level, + (unsigned int)time(0), *loc_id, + al_data->srcip, + (unsigned short)s_port, + al_data->dstip, + (unsigned short)d_port, + al_data->alertid, + al_data->user, fulllog, al_data->srcgeoip); + break; + + case POSTGDB: + snprintf(sql_query, OS_SIZE_8192, + "INSERT INTO " + "alert(server_id,rule_id,level,timestamp,location_id,src_ip,src_port,dst_ip,dst_port,alertid,\"user\",full_log) " + "VALUES ('%u', '%u','%u','%u', '%u', '%s', '%u', '%s', '%u', '%s', '%s', '%s')", + db_config->server_id, al_data->rule, + al_data->level, + (unsigned int)time(0), *loc_id, + al_data->srcip != NULL ? al_data->srcip : "NULL", + (unsigned short)s_port, + al_data->dstip != NULL ? al_data->dstip : "NULL", + (unsigned short)d_port, + al_data->alertid, + al_data->user != NULL ? al_data->user : "NULL", + fulllog); + break; + } + + free(fulllog); + fulllog = NULL; + + /* Insert into the db */ + if (!osdb_query_insert(db_config->conn, sql_query)) { + merror(DB_GENERROR, ARGV0); + } + + db_config->alert_id++; + return (1); +} diff --git a/src/os_dbd/config.c b/src/os_dbd/config.c new file mode 100644 index 000000000..5d30a0ed4 --- /dev/null +++ b/src/os_dbd/config.c @@ -0,0 +1,112 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "dbd.h" +#include "config/global-config.h" +#include "config/config.h" + + +/* Read database configuration */ +int OS_ReadDBConf(__attribute__((unused)) int test_config, const char *cfgfile, DBConfig *db_config) +{ + int modules = 0; + _Config *tmp_config; + + /* Modules for the configuration */ + modules |= CDBD; + modules |= CRULES; + + /* Allocate config just to get the rules */ + os_calloc(1, sizeof(_Config), tmp_config); + + /* Clear configuration variables */ + tmp_config->includes = NULL; + db_config->includes = NULL; + db_config->host = NULL; + db_config->user = NULL; + db_config->pass = NULL; + db_config->db = NULL; + db_config->port = 0; + db_config->sock = NULL; + db_config->db_type = 0; + db_config->maxreconnect = 0; + + /* Read configuration */ + if (ReadConfig(modules, cfgfile, tmp_config, db_config) < 0) { + return (OS_INVALID); + } + + /* Assign the rules to db_config and free the rest of the Config */ + db_config->includes = tmp_config->includes; + free(tmp_config); + + /* Check if dbd isn't supposed to run */ + if (!db_config->host && + !db_config->user && + !db_config->pass && + !db_config->db && + !db_config->sock && + !db_config->port && + !db_config->db_type) { + return (0); + } + + /* Check for a valid config */ + if (!db_config->host || + !db_config->user || + !db_config->pass || + !db_config->db || + !db_config->db_type) { + merror(DB_MISS_CONFIG, ARGV0); + return (OS_INVALID); + } + + osdb_connect = NULL; + + /* Assign the proper location for the function calls */ + +#ifdef MYSQL_DATABASE_ENABLED + if (db_config->db_type == MYSQLDB) { + osdb_connect = mysql_osdb_connect; + osdb_query_insert = mysql_osdb_query_insert; + osdb_query_select = mysql_osdb_query_select; + osdb_close = mysql_osdb_close; + } +#endif + +#ifdef PGSQL_DATABASE_ENABLED + if (db_config->db_type == POSTGDB) { + osdb_connect = postgresql_osdb_connect; + osdb_query_insert = postgresql_osdb_query_insert; + osdb_query_select = postgresql_osdb_query_select; + osdb_close = postgresql_osdb_close; + } +#endif + + /* Check for config errors */ + if (db_config->db_type == MYSQLDB) { +#ifndef MYSQL_DATABASE_ENABLED + merror(DB_COMPILED, ARGV0, "mysql"); + return (OS_INVALID); +#endif + } else if (db_config->db_type == POSTGDB) { +#ifndef PGSQL_DATABASE_ENABLED + merror(DB_COMPILED, ARGV0, "postgresql"); + return (OS_INVALID); +#endif + } + + if (osdb_connect == NULL) { + merror("%s: Invalid DB configuration (Internal error?). ", ARGV0); + return (OS_INVALID); + } + + return (1); +} + diff --git a/src/os_dbd/convert-db-ipv6.sql b/src/os_dbd/convert-db-ipv6.sql new file mode 100644 index 000000000..ef07007d6 --- /dev/null +++ b/src/os_dbd/convert-db-ipv6.sql @@ -0,0 +1,67 @@ +# SQL script for converting existing agent and alert tables to the new +# schema for handling longer IPv6 addresses. This creates two tables +# agent_ipv6 and alert_ipv6 which will replace agent and alert. + +use openarmor; + +CREATE TABLE IF NOT EXISTS agent_ipv6 + ( + id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, + server_id SMALLINT UNSIGNED NOT NULL, + last_contact INT UNSIGNED NOT NULL, + ip_address VARCHAR(46) NOT NULL, + version VARCHAR(32) NOT NULL, + name VARCHAR(64) NOT NULL, + information VARCHAR(128) NOT NULL, + PRIMARY KEY (id, server_id) + ); + +CREATE TABLE IF NOT EXISTS alert_ipv6 + ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + server_id SMALLINT UNSIGNED NOT NULL, + rule_id MEDIUMINT UNSIGNED NOT NULL, + level TINYINT UNSIGNED, + timestamp INT UNSIGNED NOT NULL, + location_id SMALLINT UNSIGNED NOT NULL, + src_ip VARCHAR(46), + dst_ip VARCHAR(46), + src_port SMALLINT UNSIGNED, + dst_port SMALLINT UNSIGNED, + alertid VARCHAR(30) DEFAULT NULL, + user TEXT NOT NULL, + full_log TEXT NOT NULL, + is_hidden TINYINT NOT NULL DEFAULT '0', + tld VARCHAR(5) NOT NULL DEFAULT '', + PRIMARY KEY (id, server_id), + INDEX (alertid), + INDEX (level), + INDEX time (timestamp), + INDEX (rule_id), + INDEX (src_ip), + INDEX (tld) + ); + +insert agent_ipv6 + select id, server_id, last_contact, inet_ntoa(ip_address), + version, name, information + from agent; + +insert alert_ipv6 + select id, server_id, rule_id, level, timestamp, location_id, + inet_ntoa(src_ip), inet_ntoa(dst_ip), src_port, dst_port, + alertid, user, full_log, is_hidden, tld + from alert; + +# Move the converted tables into place: +# +# rename table agent to agent_old; +# rename table agent_ipv6 to agent; +# +# rename table alert to alert_old; +# rename table alert_ipv6 to alert; + +# If everything looks ok, the old tables can deleted using: +# +# drop table agent_old; +# drop table alert_old; diff --git a/src/os_dbd/db_op.c b/src/os_dbd/db_op.c new file mode 100644 index 000000000..64d85e27d --- /dev/null +++ b/src/os_dbd/db_op.c @@ -0,0 +1,378 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common lib for dealing with databases */ + +#include "dbd.h" + +/* Prototypes */ +void *(*osdb_connect)(const char *host, const char *user, const char *pass, const char *db, unsigned int port, const char *sock); +int (* osdb_query_insert)(void *db_conn, const char *query); +int (* osdb_query_select)(void *db_conn, const char *query); +void *(*osdb_close)(void *db_conn); +const unsigned char insert_map[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +#ifdef MYSQL_DATABASE_ENABLED +#include +#endif + +#ifdef PGSQL_DATABASE_ENABLED +#include +#endif + +#if defined(MYSQL_DATABASE_ENABLED) || defined(PGSQL_DATABASE_ENABLED) +static void osdb_checkerror(void); +static void osdb_seterror(void); +#endif + +/* Config pointer */ +static DBConfig *db_config_pt = NULL; + + +/* Escapes a null terminated string before inserting into the database + * We built a allow list of allowed characters at insert_map. Everything + * not allowed will become a space. + */ +void osdb_escapestr(char *str) +{ + if (!str) { + return; + } + + while (*str) { + if (*str == '\'') { + *str = '`'; + } else if (*str == '\\') { + *str = '/'; + } else if (insert_map[(unsigned char)*str] != '\001') { + *str = ' '; + } + str++; + } + + /* It can not end with \\ */ + if (*(str - 1) == '\\') { + *(str - 1) = '\0'; + } +} + +#if defined(MYSQL_DATABASE_ENABLED) || defined(PGSQL_DATABASE_ENABLED) + +/* Check for errors and handle them appropriately */ +static void osdb_checkerror() +{ + if (!db_config_pt || db_config_pt->error_count > 20) { + ErrorExit(DB_MAINERROR, ARGV0); + } + + /* If error count is too large, we try to reconnect */ + if (db_config_pt->error_count > 0) { + unsigned int i = 0, sleep_time = 2; + + if (db_config_pt->conn) { + osdb_close(db_config_pt->conn); + db_config_pt->conn = NULL; + } + + while (i <= db_config_pt->maxreconnect) { + merror(DB_ATTEMPT, ARGV0); + db_config_pt->conn = osdb_connect(db_config_pt->host, + db_config_pt->user, + db_config_pt->pass, + db_config_pt->db, + db_config_pt->port, + db_config_pt->sock); + + /* If we were able to reconnect, keep going */ + if (db_config_pt->conn) { + break; + } + sleep(sleep_time); + sleep_time *= 2; + i++; + } + + /* If we weren't able to connect, exit */ + if (!db_config_pt->conn) { + ErrorExit(DB_MAINERROR, ARGV0); + } + + verbose("%s: Connected to database '%s' at '%s'.", + ARGV0, db_config_pt->db, db_config_pt->host); + } +} + +/* Set the error counter */ +static void osdb_seterror() +{ + db_config_pt->error_count++; + osdb_checkerror(); +} + +#endif + + +/* Create an internal pointer to the db configuration */ +void osdb_setconfig(DBConfig *db_config) +{ + db_config_pt = db_config; +} + +/** MySQL calls **/ +#ifdef MYSQL_DATABASE_ENABLED + +/* Create the database connection + * Returns NULL on error + */ +void *mysql_osdb_connect(const char *host, const char *user, const char *pass, const char *db, + unsigned int port, const char *sock) +{ + MYSQL *conn; + conn = mysql_init(NULL); + if (conn == NULL) { + merror(DBINIT_ERROR, ARGV0); + return (NULL); + } + + /* If host is 127.0.0.1 or localhost, use TCP socket */ + if ((strcmp(host, "127.0.0.1") == 0) || + (strcmp(host, "::1") == 0) || + (strcmp(host, "localhost") == 0)) { + if (sock != NULL) { + mysql_options(conn, MYSQL_OPT_NAMED_PIPE, NULL); + } else { + unsigned int p_type = MYSQL_PROTOCOL_TCP; + mysql_options(conn, MYSQL_OPT_PROTOCOL, (char *)&p_type); + } + } + if (mysql_real_connect(conn, host, user, pass, db, + port, sock, 0) == NULL) { + merror(DBCONN_ERROR, ARGV0, host, db, mysql_error(conn)); + mysql_close(conn); + return (NULL); + } + + return (conn); +} + +/* Close the database connection */ +void *mysql_osdb_close(void *db_conn) +{ + merror(DB_CLOSING, ARGV0); + mysql_close(db_conn); + return (NULL); +} + +/* Sends insert query to database */ +int mysql_osdb_query_insert(void *db_conn, const char *query) +{ + if (mysql_query(db_conn, query) != 0) { + /* failure; report error */ + merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn)); + osdb_seterror(); + return (0); + } + + return (1); +} + +/* Sends a select query to database. Returns the value of it. + * Returns 0 on error (not found). + */ +int mysql_osdb_query_select(void *db_conn, const char *query) +{ + int result_int = 0; + MYSQL_RES *result_data; + MYSQL_ROW result_row; + + /* Send the query. It can not fail. */ + if (mysql_query(db_conn, query) != 0) { + /* Failure: report error */ + merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn)); + osdb_seterror(); + return (0); + } + + /* Get result */ + result_data = mysql_use_result(db_conn); + if (result_data == NULL) { + /* Failure: report error */ + merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn)); + osdb_seterror(); + return (0); + } + + /* Get row. We only care about the first result. */ + result_row = mysql_fetch_row(result_data); + if (result_row && (result_row[0] != NULL)) { + result_int = atoi(result_row[0]); + } + + mysql_free_result(result_data); + + return (result_int); +} +#endif +/** End of MySQL calls **/ + +/** PostgreSQL Calls **/ +#ifdef PGSQL_DATABASE_ENABLED + +/* Create the PostgreSQL database connection + * Returns NULL on error + */ +void *postgresql_osdb_connect(const char *host, const char *user, const char *pass, const char *db, + unsigned int port, __attribute__((unused)) const char *sock) +{ + PGconn *conn; + char portAsString[6]; + + if (port > 0) { + snprintf(portAsString, 6, "%u", port); + } else { + snprintf(portAsString, 6, ""); + } + + conn = PQsetdbLogin(host, portAsString, NULL, NULL, db, user, pass); + + if (PQstatus(conn) == CONNECTION_BAD) { + merror(DBCONN_ERROR, ARGV0, host, db, PQerrorMessage(conn)); + PQfinish(conn); + return (NULL); + } + + return (conn); +} + +/* Terminates db connection */ +void *postgresql_osdb_close(void *db_conn) +{ + merror(DB_CLOSING, ARGV0); + PQfinish(db_conn); + return (NULL); +} + +/* Send insert query to database */ +int postgresql_osdb_query_insert(void *db_conn, const char *query) +{ + PGresult *result; + + result = PQexec(db_conn, query); + if (!result) { + merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn)); + osdb_seterror(); + return (0); + } + + if (PQresultStatus(result) != PGRES_COMMAND_OK) { + merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn)); + PQclear(result); + osdb_seterror(); + return (0); + } + + PQclear(result); + + return (1); +} + +/* Send a select query to database. Returns the value of it. + * Returns 0 on error (not found). + */ +int postgresql_osdb_query_select(void *db_conn, const char *query) +{ + int result_int = 0; + PGresult *result; + + result = PQexec(db_conn, query); + if (!result) { + merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn)); + osdb_seterror(); + return (0); + } + + if ((PQresultStatus(result) == PGRES_TUPLES_OK)) { + if (PQntuples(result) == 1) { + result_int = atoi(PQgetvalue(result, 0, 0)); + } + } else { + merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn)); + osdb_seterror(); + return (0); + } + + /* Clear result */ + PQclear(result); + + return (result_int); +} +/** End of PostgreSQL calls **/ +#endif + +/* Everything else when db is not defined */ +#if !defined(PGSQL_DATABASE_ENABLED) && !defined(MYSQL_DATABASE_ENABLED) + +void *none_osdb_connect(__attribute__((unused)) const char *host, __attribute__((unused)) const char *user, + __attribute__((unused)) const char *pass, __attribute__((unused)) const char *db, + __attribute__((unused)) unsigned int port, __attribute__((unused)) const char *sock) +{ + merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0); + return (NULL); +} +void *none_osdb_close(__attribute__((unused)) void *db_conn) +{ + merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0); + return (NULL); +} +int none_osdb_query_insert(__attribute__((unused)) void *db_conn, __attribute__((unused)) const char *query) +{ + merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0); + return (0); +} +int none_osdb_query_select(__attribute__((unused)) void *db_conn, __attribute__((unused)) const char *query) +{ + merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0); + return (0); +} + +#endif + diff --git a/src/os_dbd/db_op.h b/src/os_dbd/db_op.h new file mode 100644 index 000000000..e7456be5e --- /dev/null +++ b/src/os_dbd/db_op.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common API for dealing with databases */ + +#ifndef _OS_DBOP_H +#define _OS_DBOP_H + +/* Connect to the database */ +extern void *(*osdb_connect)(const char *host, const char *user, const char *pass, const char *db, unsigned int port, const char *sock); +void *mysql_osdb_connect(const char *host, const char *user, const char *pass, const char *db, unsigned int port, const char *sock); +void *postgresql_osdb_connect(const char *host, const char *user, const char *pass, const char *db, unsigned int port, const char *sock); +void *none_osdb_connect(const char *host, const char *user, const char *pass, const char *db, unsigned int port, const char *sock); + +/* Send insert query to the database */ +extern int (* osdb_query_insert)(void *db_conn, const char *query); +int mysql_osdb_query_insert(void *db_conn, const char *query); +int postgresql_osdb_query_insert(void *db_conn, const char *query); +int none_osdb_query_insert(void *db_conn, const char *query); + +/* Send select query to the database */ +extern int (* osdb_query_select)(void *db_conn, const char *query); +int mysql_osdb_query_select(void *db_conn, const char *query); +int postgresql_osdb_query_select(void *db_conn, const char *query); +int none_osdb_query_select(void *db_conn, const char *query); + +/* Close connection to the database */ +extern void *(*osdb_close)(void *db_conn); +void *mysql_osdb_close(void *db_conn); +void *postgresql_osdb_close(void *db_conn); +void *none_osdb_close(void *db_conn); + +/* Escape strings before inserting */ +void osdb_escapestr(char *str); + +/* Allowed characters */ +/* Insert charmap. + * Available chars: a-z, A-Z, 0-9, -, _, ., %, $, @, (, ), +, *, / + * Basically: 040-046 (oct) + * 050-176 (oct) + */ +extern const unsigned char insert_map[256]; + +#endif /* _OS_DBOP_H */ + diff --git a/src/os_dbd/dbd.c b/src/os_dbd/dbd.c new file mode 100644 index 000000000..d2d66f3af --- /dev/null +++ b/src/os_dbd/dbd.c @@ -0,0 +1,64 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "dbd.h" + +#ifndef ARGV0 +#define ARGV0 "openarmor-dbd" +#endif + + +/* Monitor the alerts and insert them into the database + * Only returns in case of error + */ +void OS_DBD(DBConfig *db_config) +{ + time_t tm; + struct tm *p; + file_queue *fileq; + alert_data *al_data; + + /* Get current time before starting */ + tm = time(NULL); + p = localtime(&tm); + + /* Initialize file queue to read the alerts */ + os_calloc(1, sizeof(file_queue), fileq); + Init_FileQueue(fileq, p, 0); + + /* Create location hash */ + db_config->location_hash = OSHash_Create(); + if (!db_config->location_hash) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Get maximum ID */ + db_config->alert_id = OS_SelectMaxID(db_config); + db_config->alert_id++; + + /* Infinite loop reading the alerts and inserting them */ + while (1) { + tm = time(NULL); + p = localtime(&tm); + + /* Get message if available (timeout of 5 seconds) */ + al_data = Read_FileMon(fileq, p, 5); + if (!al_data) { + continue; + } + + /* Insert into the db */ + OS_Alert_InsertDB(al_data, db_config); + + /* Clear the memory */ + FreeAlertData(al_data); + } +} + diff --git a/src/os_dbd/dbd.h b/src/os_dbd/dbd.h new file mode 100644 index 000000000..7521760c4 --- /dev/null +++ b/src/os_dbd/dbd.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _DBD_H +#define _DBD_H + +#include "shared.h" +#include "db_op.h" +#include "config/dbd-config.h" + +/** Prototypes **/ + +/* Read database config */ +int OS_ReadDBConf(int test_config, const char *cfgfile, DBConfig *db_config) __attribute__((nonnull)); + +/* Inserts server info to the db */ +int OS_Server_ReadInsertDB(const DBConfig *db_config) __attribute__((nonnull)); + +/* Insert rules in to the database */ +int OS_InsertRulesDB(DBConfig *db_config) __attribute__((nonnull)); + +/* Get maximum ID */ +int OS_SelectMaxID(const DBConfig *db_config) __attribute__((nonnull)); + +/* Insert alerts in to the database */ +int OS_Alert_InsertDB(const alert_data *al_data, DBConfig *db_config) __attribute__((nonnull)); + +/* Database inserting main function */ +void OS_DBD(DBConfig *db_config) __attribute__((nonnull)) __attribute__((noreturn)); + +/* Set config pointer for osbd_op */ +void osdb_setconfig(DBConfig *db_config); + +/* Version and db support info */ +void dbd_print_version(); + +#endif /* _DBD_H */ + diff --git a/src/os_dbd/dbd_help.c b/src/os_dbd/dbd_help.c new file mode 100644 index 000000000..e2fe3cb31 --- /dev/null +++ b/src/os_dbd/dbd_help.c @@ -0,0 +1,28 @@ +#include +#include + +#include "defs.h" + +void dbd_print_version() +{ + printf(" "); + printf("%s %s - %s", __openarmor_name, __openarmor_version, __author); + printf(" "); + printf("%s", __license); + + printf("\n"); + +#ifdef MYSQL_DATABASE_ENABLED + printf("** Compiled with MySQL support\n"); +#endif + +#ifdef PGSQL_DATABASE_ENABLED + printf("** Compiled with PostgreSQL support\n"); +#endif + +#if !defined(MYSQL_DATABASE_ENABLED) && !defined(PGSQL_DATABASE_ENABLED) + printf("** Compiled without any database support\n"); +#endif + + exit(1); +} diff --git a/src/os_dbd/dbmake.sh b/src/os_dbd/dbmake.sh new file mode 100644 index 000000000..351c0ef7c --- /dev/null +++ b/src/os_dbd/dbmake.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +MI="" +ML="" +PI="" +PL="" + +# Look for MySQL +ls "`which mysql 2>/dev/null`" > /dev/null 2>&1 +if [ $? = 0 ]; then + # Check if mysql_config is installed to use it + mysql_config --port > /dev/null 2>&1 + if [ $? = 0 ]; then + MI=`mysql_config --cflags` + ML=`mysql_config --libs` + fi + + # Check in a few dirs if mysql_config is perhaps there + for i in /usr /usr/local $1 + do + for j in $i/include/mysql/mysql.h $i/include/mysql.h + do + ls $j > /dev/null 2>&1 + if [ $? = 0 ]; then + if [ "X$MI" = "X" ]; then + MI="-I `dirname $j`"; + fi + break; + fi + done + + for j in $i/lib/mysql $i/lib64/mysql + do + ls $j > /dev/null 2>&1 + if [ $? = 0 ]; then + if [ "X$ML" = "X" ]; then + ML="-L $j -lmysqlclient"; + fi + break + fi + done + done +fi + +# Look for PostgreSQL +ls "`which psql 2>/dev/null`" > /dev/null 2>&1 +if [ $? = 0 ]; then + # Check if pg_config is installed to use it + pg_config --version > /dev/null 2>&1 + if [ $? = 0 ]; then + PGID=`pg_config --includedir` + PGPI=`pg_config --pkgincludedir` + PGLD=`pg_config --libdir` + PGLI=`pg_config --pkglibdir` + PI="${PGID} -I${PGPI}" + PL="-L${PGLD} -L${PGLI}" + fi + + for i in /usr /usr/local /usr/local/pgsql /usr/pgsql /usr/postgresql $1 + do + for j in $i/include/pgsql/libpq-fe.h $i/include/libpq-fe.h $i/include/postgresql/libpq-fe.h + do + ls $j > /dev/null 2>&1 + if [ $? = 0 ]; then + if [ "X$PI" = "X" ]; then + PI=`dirname $j`; + fi + break; + fi + done + + for j in $i/lib/pgsql $i/lib/postgresql $i/lib64/pgsql $i/lib64/postgresql + do + ls $j > /dev/null 2>&1 + if [ $? = 0 ]; then + if [ "X$PL" = "X" ]; then + PG_MAIN=`dirname $j`; + PL="-L$j -L${PG_MAIN}"; + fi + break + fi + done + done +fi + +# Print error if MySQL is not found +if [ "X$MI" = "X" -a "X$ML" = "X" ]; then + echo "" >&2 + echo "Error: MySQL client libraries not installed." >&2 + echo "" >&2 +fi + +# Print error if PostgreSQL is not found +if [ "X$PI" = "X" -a "X$PL" = "X" ]; then + echo "" >&2 + echo "Error: PostgreSQL client libraries not installed." >&2 + echo "" >&2 +fi + +# Final MySQL CFLAGS +if [ "X$MI" = "X" -o "X$ML" = "X" ]; then + MYSQL_FINAL="" +else + echo "Info: Compiled with MySQL support." >&2 + MYSQL_FINAL="$MI $ML -DDBD -DUMYSQL" +fi + +# Final PostgreSQL CFLAGS +if [ "X$PI" = "X" -o "X$PL" = "X" ]; then + POSTGRES_FINAL="" +else + echo "Info: Compiled with PostgreSQL support." >&2 + POSTGRES_FINAL="-I$PI $PL -lpq -DDBD -DUPOSTGRES" +fi + + +if [ "X${MYSQL_FINAL}" = "X" -a "X${POSTGRES_FINAL}" = "X" ]; then + echo "Error: DB libraries not installed." >&2 + exit 1; +fi + +echo "${MYSQL_FINAL} ${POSTGRES_FINAL}" + +exit 0; + diff --git a/src/os_dbd/main.c b/src/os_dbd/main.c new file mode 100644 index 000000000..ca24932dc --- /dev/null +++ b/src/os_dbd/main.c @@ -0,0 +1,251 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "dbd.h" + +#ifndef ARGV0 +#define ARGV0 "openarmor-dbd" +#endif + +/* Prototypes */ +static void print_db_info(void); +static void help_dbd(void) __attribute__((noreturn)); + + +/* Print information regarding enabled databases */ +static void print_db_info() +{ +#ifdef MYSQL_DATABASE_ENABLED + print_out(" Compiled with MySQL support"); +#endif + +#ifdef PGSQL_DATABASE_ENABLED + print_out(" Compiled with PostgreSQL support"); +#endif + +#if !defined(MYSQL_DATABASE_ENABLED) && !defined(PGSQL_DATABASE_ENABLED) + print_out(" Compiled without any database support"); +#endif +} + +/* Print help statement */ +static void help_dbd() +{ + print_header(); + print_out(" %s: -[Vhdtfv] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", MAILUSER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + print_out(" Database Support:"); + print_db_info(); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, test_config = 0, run_foreground = 0; + uid_t uid; + gid_t gid; + unsigned int d; + + /* Use MAILUSER (read only) */ + const char *dir = DEFAULTDIR; + const char *user = MAILUSER; + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + /* Database Structure */ + DBConfig db_config; + db_config.error_count = 0; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) { + switch (c) { + case 'V': + dbd_print_version(); + break; + case 'h': + help_dbd(); + break; + case 'd': + nowDebug(); + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_dbd(); + break; + } + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Read configuration */ + if ((c = OS_ReadDBConf(test_config, cfg, &db_config)) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + if (!run_foreground) { + /* Going on daemon mode */ + nowDaemon(); + goDaemon(); + } + + /* Not configured */ + if (c == 0) { + verbose("%s: Database not configured. Clean exit.", ARGV0); + exit(0); + } + + /* Maybe disable this debug? */ + debug1("%s: DEBUG: Connecting to '%s', using '%s', '%s', '%s', %d,'%s'.", + ARGV0, + db_config.host != NULL ? db_config.host : "NoHost", + db_config.user != NULL ? db_config.user : "NoUser", + db_config.pass != NULL ? db_config.pass : "NoPass", + db_config.db != NULL ? db_config.db : "NoDB", + db_config.port, + db_config.sock != NULL ? db_config.sock : "NoSock"); + + /* Set config pointer */ + osdb_setconfig(&db_config); + + /* Get maximum reconnect attempts */ + db_config.maxreconnect = (unsigned int) getDefine_Int("dbd", + "reconnect_attempts", 1, 9999); + + /* Connect to the database */ + d = 0; + while (d <= (db_config.maxreconnect * 10)) { + db_config.conn = osdb_connect(db_config.host, db_config.user, + db_config.pass, db_config.db, + db_config.port, db_config.sock); + + /* If we are able to reconnect, keep going */ + if (db_config.conn) { + break; + } + + d++; + sleep(d * 60); + + } + + /* If after the maxreconnect attempts, it still didn't work, exit here */ + if (!db_config.conn) { + merror(DB_CONFIGERR, ARGV0); + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* We must notify that we connected -- easy debugging */ + verbose("%s: Connected to database '%s' at '%s'.", + ARGV0, db_config.db, db_config.host); + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + + /* Now in chroot */ + nowChroot(); + + /* Insert server info into the db */ + db_config.server_id = OS_Server_ReadInsertDB(&db_config); + if (db_config.server_id <= 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Read rules and insert into the db */ + if (OS_InsertRulesDB(&db_config) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Change user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + /* Basic start up completed */ + debug1(CHROOT_MSG, ARGV0, dir); + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real daemon now */ + OS_DBD(&db_config); +} + diff --git a/src/os_dbd/mysql.schema b/src/os_dbd/mysql.schema new file mode 100644 index 000000000..35f67c25b --- /dev/null +++ b/src/os_dbd/mysql.schema @@ -0,0 +1,91 @@ +# Copyright (C) 2009 Trend Micro Inc. +# All rights reserved. +# +# This program is a free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public +# License (version 2) as published by the FSF - Free Software +# Foundation. + + +CREATE TABLE IF NOT EXISTS category + ( + cat_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + cat_name VARCHAR(32) NOT NULL UNIQUE, + PRIMARY KEY (cat_id) + ); + +CREATE TABLE IF NOT EXISTS signature + ( + id int UNSIGNED NOT NULL AUTO_INCREMENT, + rule_id MEDIUMINT UNSIGNED NOT NULL UNIQUE, + level TINYINT UNSIGNED, + description VARCHAR(255) NOT NULL, + PRIMARY KEY (id), + INDEX (level), + INDEX (rule_id) + ); + +CREATE TABLE IF NOT EXISTS signature_category_mapping + ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + rule_id MEDIUMINT UNSIGNED NOT NULL, + cat_id SMALLINT UNSIGNED NOT NULL, + PRIMARY KEY (id, rule_id, cat_id) + ); + +CREATE TABLE IF NOT EXISTS server + ( + id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, + last_contact INT UNSIGNED NOT NULL, + version VARCHAR(32) NOT NULL, + hostname VARCHAR(64) NOT NULL UNIQUE, + information TEXT NOT NULL, + PRIMARY KEY (id) + ); + +CREATE TABLE IF NOT EXISTS agent + ( + id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, + server_id SMALLINT UNSIGNED NOT NULL, + last_contact INT UNSIGNED NOT NULL, + ip_address VARCHAR(46) NOT NULL, + version VARCHAR(32) NOT NULL, + name VARCHAR(64) NOT NULL, + information VARCHAR(128) NOT NULL, + PRIMARY KEY (id, server_id) + ); + +CREATE TABLE IF NOT EXISTS location + ( + id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, + server_id SMALLINT UNSIGNED NOT NULL, + name VARCHAR(128) NOT NULL, + PRIMARY KEY (id, server_id) + ); + +CREATE TABLE IF NOT EXISTS alert + ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + server_id SMALLINT UNSIGNED NOT NULL, + rule_id MEDIUMINT UNSIGNED NOT NULL, + level TINYINT UNSIGNED, + timestamp INT UNSIGNED NOT NULL, + location_id SMALLINT UNSIGNED NOT NULL, + src_ip VARCHAR(46), + dst_ip VARCHAR(46), + src_port SMALLINT UNSIGNED, + dst_port SMALLINT UNSIGNED, + alertid VARCHAR(30) DEFAULT NULL, + user TEXT NOT NULL, + full_log TEXT NOT NULL, + is_hidden TINYINT NOT NULL DEFAULT '0', + tld VARCHAR(5) NOT NULL DEFAULT '', + PRIMARY KEY (id, server_id), + INDEX (alertid), + INDEX (level), + INDEX time (timestamp), + INDEX (rule_id), + INDEX (src_ip), + INDEX (tld) + ); + diff --git a/src/os_dbd/postgresql.schema b/src/os_dbd/postgresql.schema new file mode 100644 index 000000000..30c481cd7 --- /dev/null +++ b/src/os_dbd/postgresql.schema @@ -0,0 +1,103 @@ +-- Copyright (C) 2009 Trend Micro Inc. +-- All rights reserved. +-- +-- This program is a free software; you can redistribute it +-- and/or modify it under the terms of the GNU General Public +-- License (version 2) as published by the FSF - Free Software +-- Foundation. + +BEGIN; + +CREATE TABLE category + ( + cat_id SERIAL NOT NULL, + cat_name VARCHAR(32) NOT NULL UNIQUE, + PRIMARY KEY (cat_id) + ); +CREATE INDEX cat_name ON category (cat_name); + +CREATE TABLE signature + ( + id SERIAL NOT NULL, + rule_id INT8 NOT NULL UNIQUE, + level INT4, + description VARCHAR(255) NOT NULL, + PRIMARY KEY (id) + ); +CREATE INDEX signature_level ON signature (level); +CREATE INDEX signature_rule_id ON signature (rule_id); + +CREATE TABLE signature_category_mapping + ( + id SERIAL NOT NULL, + rule_id INT8 NOT NULL, + cat_id INT4 NOT NULL, + PRIMARY KEY (id, rule_id, cat_id) + ); + +CREATE TABLE server + ( + id SERIAL NOT NULL, + last_contact INT8 NOT NULL, + version VARCHAR(32) NOT NULL, + hostname VARCHAR(64) NOT NULL UNIQUE, + information TEXT NOT NULL, + PRIMARY KEY (id) + ); + +CREATE TABLE agent + ( + id SERIAL NOT NULL, + server_id INT8 NOT NULL, + last_contact INT8 NOT NULL, + ip_address VARCHAR(46) NOT NULL, + version VARCHAR(32) NOT NULL, + name VARCHAR(64) NOT NULL, + information VARCHAR(128) NOT NULL, + PRIMARY KEY (id, server_id) + ); + +CREATE TABLE location + ( + id SERIAL NOT NULL, + server_id INT8 NOT NULL, + name VARCHAR(128) NOT NULL, + PRIMARY KEY (id, server_id) + ); + +CREATE TABLE data + ( + id INT8 NOT NULL, + server_id INT4 NOT NULL, + "user" TEXT NOT NULL, + full_log TEXT NOT NULL, + PRIMARY KEY (id, server_id) + ); + +CREATE TABLE alert + ( + id bigserial NOT NULL, + server_id INT4 NOT NULL, + rule_id INT8 NOT NULL, + level INT2, + timestamp INT8 NOT NULL, + location_id INT4 NOT NULL, + src_ip VARCHAR(46), + dst_ip VARCHAR(46), + src_port INT4, + dst_port INT4, + alertid TEXT DEFAULT NULL, + "user" TEXT, + full_log TEXT NOT NULL, + is_hidden INT2 NOT NULL DEFAULT '0', + tld VARCHAR(32) NOT NULL DEFAULT '', + PRIMARY KEY (id, server_id) + ); +CREATE INDEX alertid on alert(alertid); +CREATE INDEX alert_level on alert(level); +CREATE INDEX timestamp on alert(timestamp); +CREATE INDEX alert_rule_id on alert(rule_id); +CREATE INDEX src_ip on alert(src_ip); +CREATE INDEX tld on alert(tld); + +COMMIT; diff --git a/src/os_dbd/rules.c b/src/os_dbd/rules.c new file mode 100644 index 000000000..90649a868 --- /dev/null +++ b/src/os_dbd/rules.c @@ -0,0 +1,242 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "dbd.h" +#include "config/config.h" +#include "rules_op.h" + +/* Prototypes */ +static int __Groups_SelectGroup(const char *group, const DBConfig *db_config) __attribute((nonnull)); +static int __Groups_InsertGroup(const char *group, const DBConfig *db_config) __attribute((nonnull)); +static int __Groups_SelectGroupMapping(int cat_id, int rule_id, const DBConfig *db_config) __attribute((nonnull)); +static int __Groups_InsertGroupMapping(int cat_id, int rule_id, const DBConfig *db_config) __attribute((nonnull)); +static void _Groups_ReadInsertDB(RuleInfo *rule, const DBConfig *db_config) __attribute((nonnull)); +static void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config) __attribute((nonnull)); + + +/* Select group (categories) from the db + * Returns 0 if not found + */ +static int __Groups_SelectGroup(const char *group, const DBConfig *db_config) +{ + int result = 0; + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "SELECT cat_id FROM " + "category WHERE cat_name = '%s'", + group); + + result = osdb_query_select(db_config->conn, sql_query); + + return (result); +} + +/* Insert group (categories) in to the db */ +static int __Groups_InsertGroup(const char *group, const DBConfig *db_config) +{ + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "INSERT INTO " + "category(cat_name) " + "VALUES ('%s')", + group); + + if (!osdb_query_insert(db_config->conn, sql_query)) { + merror(DB_GENERROR, ARGV0); + } + + return (0); +} + +static int __Groups_SelectGroupMapping(int cat_id, int rule_id, const DBConfig *db_config) +{ + int result = 0; + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "SELECT id FROM signature_category_mapping " + "WHERE cat_id = '%u' AND rule_id = '%u'", + cat_id, rule_id); + + result = osdb_query_select(db_config->conn, sql_query); + + return (result); +} + +static int __Groups_InsertGroupMapping(int cat_id, int rule_id, const DBConfig *db_config) +{ + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "INSERT INTO " + "signature_category_mapping(cat_id, rule_id) " + "VALUES ('%u', '%u')", + cat_id, rule_id); + + if (!osdb_query_insert(db_config->conn, sql_query)) { + merror(DB_GENERROR, ARGV0); + } + + return (0); +} + +static void _Groups_ReadInsertDB(RuleInfo *rule, const DBConfig *db_config) +{ + /* We must insert each group separately */ + int cat_id; + char *tmp_group; + char *tmp_str; + + debug1("%s: DEBUG: entering _Groups_ReadInsertDB", ARGV0); + + /* If group is null, just return */ + if (rule->group == NULL) { + return; + } + + tmp_str = strchr(rule->group, ','); + tmp_group = rule->group; + + /* Groups are separated by comma */ + while (tmp_group) { + if (tmp_str) { + *tmp_str = '\0'; + tmp_str++; + } + + /* Remove whitespace */ + while (*tmp_group == ' ') { + tmp_group++; + } + + /* Check for empty group */ + if (*tmp_group == '\0') { + tmp_group = tmp_str; + if (tmp_group) { + tmp_str = strchr(tmp_group, ','); + } + continue; + } + + cat_id = __Groups_SelectGroup(tmp_group, db_config); + + /* Check if we have this group in the db already. If not, add it. */ + if (cat_id == 0) { + __Groups_InsertGroup(tmp_group, db_config); + cat_id = __Groups_SelectGroup(tmp_group, db_config); + } + + /* If cat_id is valid (not zero), insert the mapping between + * the category and the rule + */ + if (cat_id != 0) { + /* First check if the mapping is not already there */ + if (!__Groups_SelectGroupMapping(cat_id, rule->sigid, db_config)) { + /* If not, we add it */ + __Groups_InsertGroupMapping(cat_id, rule->sigid, db_config); + } + } + + /* Get next category */ + tmp_group = tmp_str; + if (tmp_group) { + tmp_str = strchr(tmp_group, ','); + } + } + + return; +} + +/* Insert rules in to the db */ +static void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config) +{ + char sql_query[OS_SIZE_1024]; + memset(sql_query, '\0', OS_SIZE_1024); + + /* Escape strings */ + osdb_escapestr(rule->group); + osdb_escapestr(rule->comment); + + /* Check level limit */ + if (rule->level > 20) { + rule->level = 20; + } + if (rule->level < 0) { + rule->level = 0; + } + + debug1("%s: DEBUG: entering _Rules_ReadInsertDB()", ARGV0); + + /* Check rule limit */ + if (rule->sigid < 0 || rule->sigid > 9999999) { + merror("%s: Invalid rule id: %u", ARGV0, rule->sigid); + return (NULL); + } + + /* Insert group into the signature mapping */ + _Groups_ReadInsertDB(rule, (DBConfig *) db_config); + + debug2("%s: DEBUG: Inserting: %d", ARGV0, rule->sigid); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "REPLACE INTO " + "signature(rule_id, level, description) " + "VALUES ('%u','%u','%s')", + rule->sigid, rule->level, + rule->comment != NULL ? rule->comment : "NULL"); + + /* XXX We don't actually insert!? + if(!osdb_query_insert(dbc->conn, sql_query)) + { + merror(DB_GENERROR, ARGV0); + } + */ + + return (NULL); +} + +int OS_InsertRulesDB(DBConfig *db_config) +{ + char **rulesfiles; + + rulesfiles = db_config->includes; + while (rulesfiles && *rulesfiles) { + debug1("%s: Reading rules file: '%s'", ARGV0, *rulesfiles); + + if (OS_ReadXMLRules(*rulesfiles, _Rules_ReadInsertDB, db_config) < 0) { + merror(RULES_ERROR, ARGV0, *rulesfiles); + return (-1); + } + + free(*rulesfiles); + rulesfiles++; + } + + free(db_config->includes); + db_config->includes = NULL; + + + return (0); +} + diff --git a/src/os_dbd/server.c b/src/os_dbd/server.c new file mode 100644 index 000000000..53666cfb6 --- /dev/null +++ b/src/os_dbd/server.c @@ -0,0 +1,122 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "dbd.h" +#include "config/config.h" +#include "rules_op.h" + +/* Prototypes */ +static int __DBSelectServer(const char *server, const DBConfig *db_config) __attribute__((nonnull)); +static int __DBInsertServer(const char *server, const char *info, const DBConfig *db_config) __attribute__((nonnull)); + +/* System hostname */ +static char __shost[512]; + + +/* Select the server ID from the db + * Returns 0 if not found + */ +static int __DBSelectServer(const char *server, const DBConfig *db_config) +{ + int result = 0; + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Generate SQL */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "SELECT id FROM " + "server WHERE hostname = '%s'", + server); + + result = osdb_query_select(db_config->conn, sql_query); + + return (result); +} + +/* Inserts server in to the db */ +static int __DBInsertServer(const char *server, const char *info, const DBConfig *db_config) +{ + char sql_query[OS_SIZE_1024]; + + memset(sql_query, '\0', OS_SIZE_1024); + + /* Check if the server is present */ + snprintf(sql_query, OS_SIZE_1024 - 1, + "SELECT id from server where hostname = '%s'", + server); + + /* If not present, insert */ + if (osdb_query_select(db_config->conn, sql_query) == 0) { + snprintf(sql_query, OS_SIZE_1024 - 1, + "INSERT INTO " + "server(last_contact, version, hostname, information) " + "VALUES ('%u', '%s', '%s', '%s')", + (unsigned int)time(0), __openarmor_version, server, info); + + if (!osdb_query_insert(db_config->conn, sql_query)) { + merror(DB_GENERROR, ARGV0); + } + } + + /* If present, update it */ + else { + snprintf(sql_query, OS_SIZE_1024 - 1, + "UPDATE server SET " + "last_contact='%u',version='%s',information='%s' " + "WHERE hostname = '%s'", + (unsigned int)time(0), __openarmor_version, info, server); + + if (!osdb_query_insert(db_config->conn, sql_query)) { + merror(DB_GENERROR, ARGV0); + } + } + + return (0); +} + +/* Insert server info to the db + * Returns server ID or 0 on error + */ +int OS_Server_ReadInsertDB(const DBConfig *db_config) +{ + int server_id = 0; + char *info; + + debug1("%s: DEBUG: entering OS_Server_ReadInsertDB()", ARGV0); + + /* Get server hostname */ + memset(__shost, '\0', 512); + if (gethostname(__shost, 512 - 1) != 0) { + merror("%s: Error: gethostname() failed", ARGV0); + return (0); + } + + /* Get system uname */ + info = getuname(); + if (!info) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (0); + } + + /* Escape strings */ + osdb_escapestr(info); + osdb_escapestr(__shost); + + /* Insert server */ + __DBInsertServer(__shost, info, db_config); + + /* Get server id */ + server_id = __DBSelectServer(__shost, db_config); + + free(info); + + return (server_id); +} + diff --git a/src/os_execd/config.c b/src/os_execd/config.c new file mode 100644 index 000000000..8fbfc9d8f --- /dev/null +++ b/src/os_execd/config.c @@ -0,0 +1,95 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "execd.h" + + +/* Read the config file */ +int ExecdConfig(const char *cfgfile) +{ +#ifdef WIN32 + int is_disabled = 1; +#else + int is_disabled = 0; +#endif + const char *(xmlf[]) = {"openarmor_config", "active-response", "disabled", NULL}; + const char *(blocks[]) = {"openarmor_config", "active-response", "repeated_offenders", NULL}; + char *disable_entry; + char *repeated_t; + char **repeated_a; + + OS_XML xml; + + /* Read XML file */ + if (OS_ReadXML(cfgfile, &xml) < 0) { + ErrorExit(XML_ERROR, ARGV0, cfgfile, xml.err, xml.err_line); + } + + /* We do not validate the xml in here. It is done by other processes. */ + disable_entry = OS_GetOneContentforElement(&xml, xmlf); + if (disable_entry) { + if (strcmp(disable_entry, "yes") == 0) { + is_disabled = 1; + } else if (strcmp(disable_entry, "no") == 0) { + is_disabled = 0; + } else { + merror(XML_VALUEERR, ARGV0, + "disabled", + disable_entry); + return (-1); + } + } + + repeated_t = OS_GetOneContentforElement(&xml, blocks); + if (repeated_t) { + int i = 0; + int j = 0; + repeated_a = OS_StrBreak(',', repeated_t, 5); + if (!repeated_a) { + if (disable_entry != NULL && ARGV0 != NULL) { + merror(XML_VALUEERR, ARGV0, + "repeated_offenders", + disable_entry); + } + return (-1); + } + + while (repeated_a[i] != NULL) { + char *tmpt = repeated_a[i]; + while (*tmpt != '\0') { + if (*tmpt == ' ' || *tmpt == '\t') { + tmpt++; + } else { + break; + } + } + + if (*tmpt == '\0') { + i++; + continue; + } + + repeated_offenders_timeout[j] = atoi(tmpt); + verbose("%s: INFO: Adding offenders timeout: %d (for #%d)", + ARGV0, repeated_offenders_timeout[j], j + 1); + j++; + repeated_offenders_timeout[j] = 0; + if (j >= 6) { + break; + } + i++; + } + } + + OS_ClearXML(&xml); + + return (is_disabled); +} + diff --git a/src/os_execd/exec.c b/src/os_execd/exec.c new file mode 100644 index 000000000..1de89b986 --- /dev/null +++ b/src/os_execd/exec.c @@ -0,0 +1,211 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_regex/os_regex.h" +#include "execd.h" + +static char exec_names[MAX_AR + 1][OS_FLSIZE + 1]; +static char exec_cmd[MAX_AR + 1][OS_FLSIZE + 1]; +static int exec_timeout[MAX_AR + 1]; +static int exec_size = 0; +static int f_time_reading = 1; + + +/* Read the shared exec config + * Returns 1 on success or 0 on failure + * Format of the file is 'name - command - timeout' + */ +int ReadExecConfig() +{ + int i = 0, j = 0, dup_entry = 0; + FILE *fp; + FILE *process_file; + char buffer[OS_MAXSTR + 1]; + + /* Clean up */ + for (i = 0; i <= exec_size + 1; i++) { + memset(exec_names[i], '\0', OS_FLSIZE + 1); + memset(exec_cmd[i], '\0', OS_FLSIZE + 1); + exec_timeout[i] = 0; + } + exec_size = 0; + + /* Open file */ + fp = fopen(DEFAULTARPATH, "r"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH, errno, strerror(errno)); + return (0); + } + + /* Read config */ + while (fgets(buffer, OS_MAXSTR, fp) != NULL) { + char *str_pt; + char *tmp_str; + + str_pt = buffer; + + /* Clean up the buffer */ + tmp_str = strstr(buffer, " - "); + if (!tmp_str) { + merror(EXEC_INV_CONF, ARGV0, DEFAULTARPATH); + continue; + } + *tmp_str = '\0'; + tmp_str += 3; + + /* Set the name */ + strncpy(exec_names[exec_size], str_pt, OS_FLSIZE); + exec_names[exec_size][OS_FLSIZE] = '\0'; + + str_pt = tmp_str; + + /* Search for ' ' and - */ + tmp_str = strstr(tmp_str, " - "); + if (!tmp_str) { + merror(EXEC_INV_CONF, ARGV0, DEFAULTARPATH); + continue; + } + *tmp_str = '\0'; + tmp_str += 3; + + // Directory traversal test + + if (w_ref_parent_folder(str_pt)) { + merror("Active response command '%s' vulnerable to directory transversal attack. Ignoring.", str_pt); + exec_cmd[exec_size][0] = '\0'; + } else { + /* Write the full command path */ + snprintf(exec_cmd[exec_size], OS_FLSIZE, + "%s/%s", + AR_BINDIRPATH, + str_pt); + process_file = fopen(exec_cmd[exec_size], "r"); + if (!process_file) { + if (f_time_reading) { + verbose("%s: INFO: Active response command not present: '%s'. " + "Not using it on this system.", + ARGV0, exec_cmd[exec_size]); + } + + exec_cmd[exec_size][0] = '\0'; + } else { + fclose(process_file); + } + } + + str_pt = tmp_str; + tmp_str = strchr(tmp_str, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + /* Get the exec timeout */ + exec_timeout[exec_size] = atoi(str_pt); + + /* Check if name is duplicated */ + dup_entry = 0; + for (j = 0; j < exec_size; j++) { + if (strcmp(exec_names[j], exec_names[exec_size]) == 0) { + if (exec_cmd[j][0] == '\0') { + strncpy(exec_cmd[j], exec_cmd[exec_size], OS_FLSIZE); + exec_cmd[j][OS_FLSIZE] = '\0'; + dup_entry = 1; + break; + } else if (exec_cmd[exec_size][0] == '\0') { + dup_entry = 1; + } + } + } + + if (dup_entry) { + exec_cmd[exec_size][0] = '\0'; + exec_names[exec_size][0] = '\0'; + exec_timeout[exec_size] = 0; + } else { + exec_size++; + } + } + + fclose(fp); + f_time_reading = 0; + + return (1); +} + +/* Returns a pointer to the command name (full path) + * Returns NULL if name cannot be found + * If timeout is not NULL, write the timeout for that + * command to it + */ +char *GetCommandbyName(const char *name, int *timeout) +{ + int i = 0; + + for (; i < exec_size; i++) { + if (strcmp(name, exec_names[i]) == 0) { + *timeout = exec_timeout[i]; + return (exec_cmd[i]); + } + } + + return (NULL); +} + +#ifndef WIN32 + +/* Execute command given. Must be a argv** NULL terminated. + * Prints error to log message in case of problems + */ +void ExecCmd(char *const *cmd) +{ + pid_t pid; + + /* Fork and leave it running */ + pid = fork(); + if (pid == 0) { + if (execv(*cmd, cmd) < 0) { + merror(EXEC_CMDERROR, ARGV0, *cmd, strerror(errno)); + exit(1); + } + + exit(0); + } + + return; +} + +#else + +void ExecCmd_Win32(char *cmd) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + + if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, + &si, &pi)) { + merror("%s: ERROR: Unable to create active response process. ", ARGV0); + return; + } + + /* Wait until process exits */ + WaitForSingleObject(pi.hProcess, INFINITE ); + + /* Close process and thread */ + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + + return; +} +#endif + diff --git a/src/os_execd/execd.c b/src/os_execd/execd.c new file mode 100644 index 000000000..0aadaeca9 --- /dev/null +++ b/src/os_execd/execd.c @@ -0,0 +1,539 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "list_op.h" +#include "os_regex/os_regex.h" +#include "os_net/os_net.h" +#include "execd.h" + +int repeated_offenders_timeout[] = {0, 0, 0, 0, 0, 0, 0}; + +#ifndef WIN32 + +/* Prototypes */ +static void help_execd(void) __attribute__((noreturn)); +static void execd_shutdown(int sig) __attribute__((noreturn)); +static void ExecdStart(int q) __attribute__((noreturn)); + +/* Global variables */ +static OSList *timeout_list; +static OSListNode *timeout_node; +static OSHash *repeated_hash; + + +/* Print help statement */ +static void help_execd() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-g group] [-c config]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" "); + exit(1); +} + +/* Shut down execd properly */ +static void execd_shutdown(int sig) +{ + int status; + + /* Remove pending active responses */ + merror(EXEC_SHUTDOWN, ARGV0); + + timeout_node = OSList_GetFirstNode(timeout_list); + while (timeout_node) { + timeout_data *list_entry; + + list_entry = (timeout_data *)timeout_node->data; + + ExecCmd(list_entry->command); + wait(&status); + + /* Delete current node - already sets the pointer to next */ + OSList_DeleteCurrentlyNode(timeout_list); + timeout_node = OSList_GetCurrentlyNode(timeout_list); + } + + HandleSIG(sig); +} + +int main(int argc, char **argv) +{ + int c; + int test_config = 0, run_foreground = 0; + gid_t gid; + int m_queue = 0; + + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vtdhfg:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_execd(); + break; + case 'd': + nowDebug(); + break; + case 'f': + run_foreground = 1; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument.", ARGV0); + } + group = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument.", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_execd(); + break; + } + } + + /* Check if the group given is valid */ + gid = Privsep_GetGroup(group); + if (gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, "", group); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* Read config */ + if ((c = ExecdConfig(cfg)) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Exit if test_config */ + if (test_config) { + exit(0); + } + + /* Signal manipulation */ + StartSIG2(ARGV0, execd_shutdown); + + if (!run_foreground) { + /* Going daemon */ + nowDaemon(); + goDaemon(); + } + + /* Active response disabled */ + if (c == 1) { + verbose(EXEC_DISABLED, ARGV0); + exit(0); + } + + /* Create the PID file */ + if (CreatePID(ARGV0, getpid()) < 0) { + merror(PID_ERROR, ARGV0); + } + + /* Start exec queue */ + if ((m_queue = StartMQ(EXECQUEUEPATH, READ)) < 0) { + ErrorExit(QUEUE_ERROR, ARGV0, EXECQUEUEPATH, strerror(errno)); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real daemon Now */ + ExecdStart(m_queue); + + exit(0); +} + +#endif + +/* Free the timeout entry + * Must be called after popping it from the timeout list + */ +void FreeTimeoutEntry(timeout_data *timeout_entry) +{ + char **tmp_str; + + if (!timeout_entry) { + return; + } + + tmp_str = timeout_entry->command; + + /* Clear the command arguments */ + if (tmp_str) { + while (*tmp_str) { + os_free(*tmp_str); + *tmp_str = NULL; + tmp_str++; + } + os_free(timeout_entry->command); + timeout_entry->command = NULL; + } + + free(timeout_entry); +} + +#ifndef WIN32 + +/* Main function on the execd. Does all the data receiving, etc. */ +static void ExecdStart(int q) +{ + int i, childcount = 0; + time_t curr_time; + + char buffer[OS_MAXSTR + 1]; + char *tmp_msg = NULL; + char *name; + char *command; + char *cmd_args[MAX_ARGS + 2]; + + /* Select */ + fd_set fdset; + struct timeval socket_timeout; + + /* Clear the buffer */ + memset(buffer, '\0', OS_MAXSTR + 1); + + /* Initialize the cmd arguments */ + for (i = 0; i <= MAX_ARGS + 1; i++) { + cmd_args[i] = NULL; + } + + /* Create list for timeout */ + timeout_list = OSList_Create(); + if (!timeout_list) { + ErrorExit(LIST_ERROR, ARGV0); + } + + if (repeated_offenders_timeout[0] != 0) { + repeated_hash = OSHash_Create(); + } else { + repeated_hash = NULL; + } + + /* Main loop */ + while (1) { + int timeout_value; + int added_before = 0; + char **timeout_args; + timeout_data *timeout_entry; + + /* Clean up any children */ + while (childcount) { + int wp; + wp = waitpid((pid_t) - 1, NULL, WNOHANG); + if (wp < 0) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + break; + } + + /* if = 0, we still need to wait for the child process */ + else if (wp == 0) { + break; + } + /* Child completed if wp > 0 */ + else { + childcount--; + } + } + + /* Get current time */ + curr_time = time(0); + + /* Check if there is any timed out command to execute */ + timeout_node = OSList_GetFirstNode(timeout_list); + while (timeout_node) { + timeout_data *list_entry; + + list_entry = (timeout_data *)timeout_node->data; + + /* Timed out */ + if ((curr_time - list_entry->time_of_addition) > + list_entry->time_to_block) { + ExecCmd(list_entry->command); + + /* Delete current node - already sets the pointer to next */ + OSList_DeleteCurrentlyNode(timeout_list); + timeout_node = OSList_GetCurrentlyNode(timeout_list); + + /* Clear the memory */ + FreeTimeoutEntry(list_entry); + + childcount++; + } else { + timeout_node = OSList_GetNextNode(timeout_list); + } + } + + /* Set timeout to EXECD_TIMEOUT */ + socket_timeout.tv_sec = EXECD_TIMEOUT; + socket_timeout.tv_usec = 0; + + /* Set FD values */ + FD_ZERO(&fdset); + FD_SET(q, &fdset); + + /* Add timeout */ + if (select(q + 1, &fdset, NULL, NULL, &socket_timeout) == 0) { + /* Timeout */ + continue; + } + + /* Check for error */ + if (!FD_ISSET(q, &fdset)) { + merror(SELECT_ERROR, ARGV0, errno, strerror(errno)); + continue; + } + + /* Receive the message */ + if (OS_RecvUnix(q, OS_MAXSTR, buffer) == 0) { + merror(QUEUE_ERROR, ARGV0, EXECQUEUEPATH, strerror(errno)); + continue; + } + + /* Current time */ + curr_time = time(0); + + /* Get application name */ + name = buffer; + + /* Zero the name */ + tmp_msg = strchr(buffer, ' '); + if (!tmp_msg) { + merror(EXECD_INV_MSG, ARGV0, buffer); + continue; + } + *tmp_msg = '\0'; + tmp_msg++; + + /* Get the command to execute (valid name) */ + command = GetCommandbyName(name, &timeout_value); + if (!command) { + ReadExecConfig(); + command = GetCommandbyName(name, &timeout_value); + if (!command) { + merror(EXEC_INV_NAME, ARGV0, name); + continue; + } + } + + /* Command not present */ + if (command[0] == '\0') { + continue; + } + + /* Allocate memory for the timeout argument */ + os_calloc(MAX_ARGS + 2, sizeof(char *), timeout_args); + + /* Add initial variables to the cmd_arg and to the timeout cmd */ + cmd_args[0] = command; + cmd_args[1] = ADD_ENTRY; + os_strdup(command, timeout_args[0]); + os_strdup(DELETE_ENTRY, timeout_args[1]); + + cmd_args[2] = NULL; + timeout_args[2] = NULL; + + /* Get the arguments */ + i = 2; + while (i < (MAX_ARGS - 1)) { + cmd_args[i] = tmp_msg; + cmd_args[i + 1] = NULL; + + tmp_msg = strchr(tmp_msg, ' '); + if (!tmp_msg) { + timeout_args[i] = strdup(cmd_args[i]); + timeout_args[i + 1] = NULL; + break; + } + *tmp_msg = '\0'; + tmp_msg++; + + timeout_args[i] = strdup(cmd_args[i]); + timeout_args[i + 1] = NULL; + + i++; + } + + /* Check if this command was already executed */ + timeout_node = OSList_GetFirstNode(timeout_list); + added_before = 0; + + /* Check for the username and IP argument */ + if (!timeout_args[2] || !timeout_args[3]) { + added_before = 1; + merror("%s: Invalid number of arguments.", ARGV0); + } + + while (timeout_node) { + timeout_data *list_entry; + + list_entry = (timeout_data *)timeout_node->data; + if ((strcmp(list_entry->command[3], timeout_args[3]) == 0) && + (strcmp(list_entry->command[0], timeout_args[0]) == 0)) { + /* Means we executed this command before + * and we don't need to add it again + */ + added_before = 1; + + /* Update the timeout */ + list_entry->time_of_addition = curr_time; + + if (repeated_offenders_timeout[0] != 0 && + repeated_hash != NULL && + strncmp(timeout_args[3], "-", 1) != 0) { + char *ntimes = NULL; + char rkey[256]; + rkey[255] = '\0'; + snprintf(rkey, 255, "%s%s", list_entry->command[0], + timeout_args[3]); + + if ((ntimes = (char *) OSHash_Get(repeated_hash, rkey))) { + int ntimes_int = 0; + int i2 = 0; + int new_timeout = 0; + ntimes_int = atoi(ntimes); + while (repeated_offenders_timeout[i2] != 0) { + i2++; + } + if (ntimes_int >= i2) { + new_timeout = repeated_offenders_timeout[i2 - 1] * 60; + } else { + free(ntimes); /* In hash_op.c, data belongs to caller */ + os_calloc(10, sizeof(char), ntimes); + new_timeout = repeated_offenders_timeout[ntimes_int] * 60; + ntimes_int++; + snprintf(ntimes, 9, "%d", ntimes_int); + OSHash_Update(repeated_hash, rkey, ntimes); + } + list_entry->time_to_block = new_timeout; + } + } + break; + } + + /* Continue with the next entry in timeout list*/ + timeout_node = OSList_GetNextNode(timeout_list); + } + + /* If it wasn't added before, do it now */ + if (!added_before) { + /* Execute command */ + ExecCmd(cmd_args); + + /* We don't need to add to the list if the timeout_value == 0 */ + if (timeout_value) { + char *ntimes; + char rkey[256]; + rkey[255] = '\0'; + snprintf(rkey, 255, "%s%s", timeout_args[0], + timeout_args[3]); + + if (repeated_hash != NULL) { + if ((ntimes = (char *) OSHash_Get(repeated_hash, rkey))) { + int ntimes_int = 0; + int i2 = 0; + int new_timeout = 0; + + ntimes_int = atoi(ntimes); + while (repeated_offenders_timeout[i2] != 0) { + i2++; + } + if (ntimes_int >= i2) { + new_timeout = repeated_offenders_timeout[i2 - 1] * 60; + } else { + os_calloc(10, sizeof(char), ntimes); + new_timeout = repeated_offenders_timeout[ntimes_int] * 60; + ntimes_int++; + snprintf(ntimes, 9, "%d", ntimes_int); + OSHash_Update(repeated_hash, rkey, ntimes); + } + timeout_value = new_timeout; + } else { + /* Add to the repeat offenders list */ + OSHash_Add(repeated_hash, + rkey, strdup("0")); + } + } + + /* Create the timeout entry */ + os_calloc(1, sizeof(timeout_data), timeout_entry); + timeout_entry->command = timeout_args; + timeout_entry->time_of_addition = curr_time; + timeout_entry->time_to_block = timeout_value; + + /* Add command to the timeout list */ + if (!OSList_AddData(timeout_list, timeout_entry)) { + merror(LIST_ADD_ERROR, ARGV0); + FreeTimeoutEntry(timeout_entry); + } + } + + /* If no timeout, we still need to free it in here */ + else { + char **ss_ta = timeout_args; + while (*timeout_args) { + os_free(*timeout_args); + *timeout_args = NULL; + timeout_args++; + } + os_free(ss_ta); + } + + childcount++; + } + + /* We didn't add it to the timeout list */ + else { + char **ss_ta = timeout_args; + + /* Clear the timeout arguments */ + while (*timeout_args) { + os_free(*timeout_args); + *timeout_args = NULL; + timeout_args++; + } + + os_free(ss_ta); + } + + /* Some cleanup */ + while (i > 0) { + cmd_args[i] = NULL; + i--; + } + } +} + +#endif /* !WIN32 */ + diff --git a/src/os_execd/execd.h b/src/os_execd/execd.h new file mode 100644 index 000000000..84d4d6a7d --- /dev/null +++ b/src/os_execd/execd.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _EXECD_H +#define _EXECD_H + +#ifndef ARGV0 +#define ARGV0 "openarmor-execd" +#endif + +/* Add/delete arguments for the commands */ +#define ADD_ENTRY "add" +#define DELETE_ENTRY "delete" + +/* Maximum number of active responses active */ +#define MAX_AR 64 + +/* Maximum number of command arguments */ +#define MAX_ARGS 32 + +/* Execd select timeout -- in seconds */ +#define EXECD_TIMEOUT 90 + +extern int repeated_offenders_timeout[]; + +/** Function prototypes **/ + +void WinExecdRun(char *exec_msg); +int ReadExecConfig(void); +char *GetCommandbyName(const char *name, int *timeout) __attribute__((nonnull)); +void ExecCmd(char *const *cmd) __attribute__((nonnull)); +void ExecCmd_Win32(char *cmd); +int ExecdConfig(const char *cfgfile) __attribute__((nonnull)); +int WinExecd_Start(void); +void WinTimeoutRun(int timeout); + +/* Timeout data structure */ +typedef struct _timeout_data { + time_t time_of_addition; + int time_to_block; + char **command; +} timeout_data; + +void FreeTimeoutEntry(timeout_data *timeout_entry); + +#endif + diff --git a/src/os_execd/win_execd.c b/src/os_execd/win_execd.c new file mode 100644 index 000000000..bd740eefc --- /dev/null +++ b/src/os_execd/win_execd.c @@ -0,0 +1,256 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifdef WIN32 + +#include "shared.h" +#include "list_op.h" +#include "os_regex/os_regex.h" +#include "os_net/os_net.h" +#include "execd.h" + +#ifdef ARGV0 +#undef ARGV0 +#endif + +#define ARGV0 "openarmor-execd" + +/* Timeout list */ +OSList *timeout_list; +OSListNode *timeout_node; + + +int WinExecd_Start() +{ + int c; + int test_config = 0; + char *cfg = DEFAULTCPATH; + + /* Read config */ + if ((c = ExecdConfig(cfg)) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Exit if test_config */ + if (test_config) { + return (0); + } + + /* Active response disabled */ + if (c == 1) { + verbose(EXEC_DISABLED, ARGV0); + return (0); + } + + /* Create list for timeout */ + timeout_list = OSList_Create(); + if (!timeout_list) { + ErrorExit(LIST_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, getpid()); + + return (1); +} + +void WinTimeoutRun(int curr_time) +{ + /* Check if there is any timed out command to execute */ + timeout_node = OSList_GetFirstNode(timeout_list); + while (timeout_node) { + timeout_data *list_entry; + + list_entry = (timeout_data *)timeout_node->data; + + /* Timed out */ + if ((curr_time - list_entry->time_of_addition) > + list_entry->time_to_block) { + ExecCmd_Win32(list_entry->command[0]); + + /* Delete currently node - already sets the pointer to next */ + OSList_DeleteCurrentlyNode(timeout_list); + timeout_node = OSList_GetCurrentlyNode(timeout_list); + + /* Clear the memory */ + FreeTimeoutEntry(list_entry); + } + + else { + timeout_node = OSList_GetNextNode(timeout_list); + } + } +} + +void WinExecdRun(char *exec_msg) +{ + time_t curr_time; + + int i, j; + int timeout_value; + int added_before = 0; + + char **timeout_args; + + char *tmp_msg = NULL; + char *name; + char *command; + char *cmd_user; + char *cmd_ip; + char buffer[OS_MAXSTR + 1]; + + timeout_data *timeout_entry; + + /* Current time */ + curr_time = time(0); + + /* Get application name */ + name = exec_msg; + + /* Zero the name */ + tmp_msg = strchr(exec_msg, ' '); + if (!tmp_msg) { + merror(EXECD_INV_MSG, ARGV0, exec_msg); + return; + } + *tmp_msg = '\0'; + tmp_msg++; + + /* Get user */ + cmd_user = tmp_msg; + tmp_msg = strchr(tmp_msg, ' '); + if (!tmp_msg) { + merror(EXECD_INV_MSG, ARGV0, cmd_user); + return; + } + *tmp_msg = '\0'; + tmp_msg++; + + /* Get IP */ + cmd_ip = tmp_msg; + tmp_msg = strchr(tmp_msg, ' '); + if (!tmp_msg) { + merror(EXECD_INV_MSG, ARGV0, cmd_ip); + return; + } + *tmp_msg = '\0'; + tmp_msg++; + + /* Get the command to execute (valid name) */ + command = GetCommandbyName(name, &timeout_value); + if (!command) { + ReadExecConfig(); + command = GetCommandbyName(name, &timeout_value); + if (!command) { + merror(EXEC_INV_NAME, ARGV0, name); + return; + } + } + + /* Command not present */ + if (command[0] == '\0') { + return; + } + + /* Allocate memory for the timeout argument */ + os_calloc(MAX_ARGS + 2, sizeof(char *), timeout_args); + + /* Add initial variables to the timeout cmd */ + snprintf(buffer, OS_MAXSTR, "\"%s\" %s \"%s\" \"%s\" \"%s\"", + command, DELETE_ENTRY, cmd_user, cmd_ip, tmp_msg); + os_strdup(buffer, timeout_args[0]); + timeout_args[1] = NULL; + + /* Get size for the strncmp */ + i = 0, j = 0; + while (buffer[i] != '\0') { + if (buffer[i] == ' ') { + j++; + } + + i++; + if (j == 4) { + break; + } + } + + /* Check if this command was already executed */ + timeout_node = OSList_GetFirstNode(timeout_list); + added_before = 0; + + while (timeout_node) { + timeout_data *list_entry; + + list_entry = (timeout_data *)timeout_node->data; + if (strncmp(list_entry->command[0], timeout_args[0], i) == 0) { + /* Means we executed this command before + * and we don't need to add it again + */ + added_before = 1; + + /* Update the timeout */ + list_entry->time_of_addition = curr_time; + break; + } + + /* Continue with the next entry in timeout list */ + timeout_node = OSList_GetNextNode(timeout_list); + } + + /* If it wasn't added before, do it now */ + if (!added_before) { + snprintf(buffer, OS_MAXSTR, "\"%s\" %s \"%s\" \"%s\" \"%s\"", command, + ADD_ENTRY, cmd_user, cmd_ip, tmp_msg); + /* Execute command */ + ExecCmd_Win32(buffer); + + /* We don't need to add to the list if the timeout_value == 0 */ + if (timeout_value) { + /* Create the timeout entry */ + os_calloc(1, sizeof(timeout_data), timeout_entry); + timeout_entry->command = timeout_args; + timeout_entry->time_of_addition = curr_time; + timeout_entry->time_to_block = timeout_value; + + /* Add command to the timeout list */ + if (!OSList_AddData(timeout_list, timeout_entry)) { + merror(LIST_ADD_ERROR, ARGV0); + FreeTimeoutEntry(timeout_entry); + } + } + + /* If no timeout, we still need to free it in here */ + else { + char **ss_ta = timeout_args; + while (*timeout_args) { + os_free(*timeout_args); + *timeout_args = NULL; + timeout_args++; + } + os_free(ss_ta); + } + } + + /* We didn't add it to the timeout list */ + else { + char **ss_ta = timeout_args; + + /* Clear the timeout arguments */ + while (*timeout_args) { + os_free(*timeout_args); + *timeout_args = NULL; + timeout_args++; + } + + os_free(ss_ta); + } +} + +#endif /* WIN32 */ + diff --git a/src/os_maild/config.c b/src/os_maild/config.c new file mode 100644 index 000000000..13f2f2f6f --- /dev/null +++ b/src/os_maild/config.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "maild.h" +#include "config/config.h" + + +/* Read the Mail configuration */ +int MailConf(int test_config, const char *cfgfile, MailConfig *Mail) +{ + int modules = 0; + + modules |= CMAIL; + + Mail->to = NULL; + Mail->reply_to = NULL; + Mail->from = NULL; + Mail->idsname = NULL; + Mail->smtpserver = NULL; + Mail->heloserver = NULL; + Mail->mn = 0; + Mail->priority = 0; + Mail->maxperhour = 12; + Mail->gran_to = NULL; + Mail->gran_id = NULL; + Mail->gran_level = NULL; + Mail->gran_location = NULL; + Mail->gran_group = NULL; + Mail->gran_set = NULL; + Mail->gran_format = NULL; + Mail->groupping = 1; + Mail->strict_checking = 0; +#ifdef LIBGEOIP_ENABLED + Mail->geoip = 0; +#endif + + if (ReadConfig(modules, cfgfile, NULL, Mail) < 0) { + return (OS_INVALID); + } + + if (!Mail->mn) { + if (!test_config) { + verbose(MAIL_DIS, ARGV0); + } + exit(0); + } + + return (0); +} + diff --git a/src/os_maild/mail_list.c b/src/os_maild/mail_list.c new file mode 100644 index 000000000..7e782b2ef --- /dev/null +++ b/src/os_maild/mail_list.c @@ -0,0 +1,155 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "headers/debug_op.h" +#include "maild.h" +#include "mail_list.h" +#include "error_messages/error_messages.h" + +static MailNode *n_node; +static MailNode *lastnode; + +static int _memoryused = 0; +static int _memorymaxsize = 0; + + +/* Create the Mail List */ +void OS_CreateMailList(int maxsize) +{ + n_node = NULL; + + _memorymaxsize = maxsize; + _memoryused = 0; + + return; +} + +/* Check last mail */ +MailNode *OS_CheckLastMail() +{ + return (lastnode); +} + +/* Get the last Mail -- or first node */ +MailNode *OS_PopLastMail() +{ + MailNode *oldlast; + + oldlast = lastnode; + if (lastnode == NULL) { + n_node = NULL; + return (NULL); + } + + _memoryused--; + lastnode = lastnode->prev; + + /* Remove the last */ + return (oldlast); +} + +void FreeMailMsg(MailMsg *ml) +{ + if (ml == NULL) { + return; + } + + if (ml->subject) { + free(ml->subject); + } + + if (ml->body) { + free(ml->body); + } + + free(ml); +} + +/* Free mail node */ +void FreeMail(MailNode *ml) +{ + if (ml == NULL) { + return; + } + if (ml->mail->subject) { + free(ml->mail->subject); + } + + if (ml->mail->body) { + free(ml->mail->body); + } + + free(ml->mail); + free(ml); +} + + +/* Add an email to the list -- always to the beginning */ +void OS_AddMailtoList(MailMsg *ml) +{ + MailNode *tmp_node = n_node; + + if (tmp_node) { + MailNode *new_node; + new_node = (MailNode *)calloc(1, sizeof(MailNode)); + + if (new_node == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + /* Always add to the beginning of the list + * The new node will become the first node and + * new_node->next will be the previous first node + */ + new_node->next = tmp_node; + new_node->prev = NULL; + tmp_node->prev = new_node; + + n_node = new_node; + + /* Add the event to the node */ + new_node->mail = ml; + + _memoryused++; + + /* Need to remove the last node */ + if (_memoryused > _memorymaxsize) { + MailNode *oldlast; + + oldlast = lastnode; + lastnode = lastnode->prev; + + /* Free last node */ + FreeMail(oldlast); + + _memoryused--; + } + } + + else { + /* Add first node */ + n_node = (MailNode *)calloc(1, sizeof(MailNode)); + if (n_node == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + n_node->prev = NULL; + n_node->next = NULL; + n_node->mail = ml; + + lastnode = n_node; + } + + return; +} + diff --git a/src/os_maild/mail_list.h b/src/os_maild/mail_list.h new file mode 100644 index 000000000..613b8f22d --- /dev/null +++ b/src/os_maild/mail_list.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _MAILLIST__H +#define _MAILLIST__H + +/* Events List structure */ +typedef struct _MailNode { + MailMsg *mail; + struct _MailNode *next; + struct _MailNode *prev; +} MailNode; + +/* Add an email to the list */ +void OS_AddMailtoList(MailMsg *ml) __attribute__((nonnull)); + +/* Return the last event from the Event list + * removing it from there + */ +MailNode *OS_PopLastMail(void); + +/* Return a pointer to the last email, not removing it */ +MailNode *OS_CheckLastMail(void); + +/* Create the mail list. Maxsize must be specified */ +void OS_CreateMailList(int maxsize); + +/* Free an email node */ +void FreeMail(MailNode *ml); + +/* Free email msg */ +void FreeMailMsg(MailMsg *ml); + +#endif /* _MAILLIST__H */ + diff --git a/src/os_maild/maild.c b/src/os_maild/maild.c new file mode 100644 index 000000000..9a3bc7ddc --- /dev/null +++ b/src/os_maild/maild.c @@ -0,0 +1,403 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "maild.h" +#include "mail_list.h" + +#ifndef ARGV0 +#define ARGV0 "openarmor-maild" +#endif + +/* Global variables */ +unsigned int mail_timeout; +unsigned int _g_subject_level; +char _g_subject[SUBJECT_SIZE + 2]; + +/* Prototypes */ +static void OS_Run(MailConfig *mail) __attribute__((nonnull)) __attribute__((noreturn)); +static void help_maild(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_maild() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", MAILUSER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, test_config = 0, run_foreground = 0; + uid_t uid; + gid_t gid; + const char *dir = DEFAULTDIR; + const char *user = MAILUSER; + const char *group = GROUPGLOBAL; + const char *cfg = DEFAULTCPATH; + + /* Mail Structure */ + MailConfig mail; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_maild(); + break; + case 'd': + nowDebug(); + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_maild(); + break; + } + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Read configuration */ + if (MailConf(test_config, cfg, &mail) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Read internal options */ + mail.strict_checking = getDefine_Int("maild", + "strict_checking", + 0, 1); + + /* Get groupping */ + mail.groupping = getDefine_Int("maild", + "groupping", + 0, 1); + + /* Get subject type */ + mail.subject_full = getDefine_Int("maild", + "full_subject", + 0, 1); + +#ifdef LIBGEOIP_ENABLED + /* Get GeoIP */ + mail.geoip = getDefine_Int("maild", + "geoip", + 0, 1); +#endif + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + if (!run_foreground) { + nowDaemon(); + goDaemon(); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + if (mail.smtpserver[0] != '/') { + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + debug1(CHROOT_MSG, ARGV0, dir); + } + + /* Change user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real daemon now */ + OS_Run(&mail); +} + +/* Read the queue and send the appropriate alerts + * Not supposed to return + */ +static void OS_Run(MailConfig *mail) +{ + MailMsg *msg; + MailMsg *s_msg = NULL; + MailMsg *msg_sms = NULL; + + time_t tm; + struct tm *p; + + int i = 0; + int mailtosend = 0; + int childcount = 0; + int thishour = 0; + + int n_errs = 0; + + file_queue *fileq; + + /* Get current time before starting */ + tm = time(NULL); + p = localtime(&tm); + thishour = p->tm_hour; + + /* Initialize file queue */ + i = 0; + i |= CRALERT_MAIL_SET; + os_calloc(1, sizeof(file_queue), fileq); + Init_FileQueue(fileq, p, i); + + /* Create the list */ + OS_CreateMailList(MAIL_LIST_SIZE); + + /* Set default timeout */ + mail_timeout = DEFAULT_TIMEOUT; + + /* Clear global variables */ + _g_subject_level = 0; + memset(_g_subject, '\0', SUBJECT_SIZE + 2); + + while (1) { + tm = time(NULL); + p = localtime(&tm); + + + /* If mail_timeout == NEXTMAIL_TIMEOUT, we will try to get + * more messages, before sending anything + */ + if ((mail_timeout == NEXTMAIL_TIMEOUT) && (p->tm_hour == thishour)) { + /* Get more messages */ + } + + /* Hour changed: send all suppressed mails */ + else if (((mailtosend < mail->maxperhour) && (mailtosend != 0)) || + ((p->tm_hour != thishour) && (childcount < MAXCHILDPROCESS))) { + MailNode *mailmsg; + pid_t pid; + + /* Check if we have anything to send */ + mailmsg = OS_CheckLastMail(); + if (mailmsg == NULL) { + /* Don't fork in here */ + goto snd_check_hour; + } + + fflush(fileq->fp); + pid = fork(); + if (pid < 0) { + merror(FORK_ERROR, ARGV0, errno, strerror(errno)); + sleep(30); + continue; + } else if (pid == 0) { + if (OS_Sendmail(mail, p) < 0) { + merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver); + } + + exit(0); + } + + /* Clean the memory */ + mailmsg = OS_PopLastMail(); + do { + FreeMail(mailmsg); + mailmsg = OS_PopLastMail(); + } while (mailmsg); + + /* Increase child count */ + childcount++; + + /* Clear global variables */ + _g_subject[0] = '\0'; + _g_subject[SUBJECT_SIZE - 1] = '\0'; + _g_subject_level = 0; + + /* Clean up set values */ + if (mail->gran_to) { + i = 0; + while (mail->gran_to[i] != NULL) { + if (s_msg && mail->gran_set[i] == DONOTGROUP) { + mail->gran_set[i] = FULL_FORMAT; + } else { + mail->gran_set[i] = 0; + } + i++; + } + } + +snd_check_hour: + /* If we sent everything */ + if (p->tm_hour != thishour) { + thishour = p->tm_hour; + + mailtosend = 0; + } + } + + /* Saved message for the do_not_group option */ + if (s_msg) { + /* Set the remaining do no group to full format */ + if (mail->gran_to) { + i = 0; + while (mail->gran_to[i] != NULL) { + if (mail->gran_set[i] == DONOTGROUP) { + mail->gran_set[i] = FULL_FORMAT; + } + i++; + } + } + + OS_AddMailtoList(s_msg); + + s_msg = NULL; + mailtosend++; + continue; + } + + /* Receive message from queue */ + if ((msg = OS_RecvMailQ(fileq, p, mail, &msg_sms)) != NULL) { + /* If the e-mail priority is do_not_group, + * flush all previous entries and then send it. + * Use s_msg to hold the pointer to the message while we flush it. + */ + if (mail->priority == DONOTGROUP) { + s_msg = msg; + } else { + OS_AddMailtoList(msg); + } + + /* Change timeout to see if any new message is coming shortly */ + if (mail->groupping) { + /* If priority is set, send email now */ + if (mail->priority) { + mail_timeout = DEFAULT_TIMEOUT; + + /* If do_not_group is set, we do not increase the list count */ + if (mail->priority != DONOTGROUP) { + mailtosend++; + } + } else { + /* 5 seconds only */ + mail_timeout = NEXTMAIL_TIMEOUT; + } + } else { + /* Send message by itself */ + mailtosend++; + } + } else { + if (mail_timeout == NEXTMAIL_TIMEOUT) { + mailtosend++; + + /* Default timeout */ + mail_timeout = DEFAULT_TIMEOUT; + } + } + + /* Wait for the children */ + while (childcount) { + int wp; + int p_status; + wp = waitpid((pid_t) - 1, &p_status, WNOHANG); + if (wp < 0) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + n_errs++; + } + + /* if = 0, we still need to wait for the child process */ + else if (wp == 0) { + break; + } else { + if (p_status != 0) { + merror(CHLDWAIT_ERROR, ARGV0, p_status); + merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver); + n_errs++; + } + childcount--; + } + + /* Too many errors */ + if (n_errs > 6) { + merror(TOOMANY_WAIT_ERROR, ARGV0); + merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver); + exit(1); + } + } + + } +} + diff --git a/src/os_maild/maild.h b/src/os_maild/maild.h new file mode 100644 index 000000000..5ebb26df1 --- /dev/null +++ b/src/os_maild/maild.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef _MAILD_H +#define _MAILD_H + +#define MAIL_LIST_SIZE 96 /* Max number of emails to be saved */ +#define MAXCHILDPROCESS 6 /* Maximum simultaneous children */ + +/* Each timeout is x * 5 */ +#define NEXTMAIL_TIMEOUT 2 /* Time to check for next msg - 5 */ +#define DEFAULT_TIMEOUT 18 /* socket read timeout - 18 (*5)*/ +#define SUBJECT_SIZE 128 /* Maximum subject size */ + +/* Maximum body size */ +#define BODY_SIZE OS_MAXSTR + OS_SIZE_1024 + +#define SMS_SUBJECT "openarmor %d - %d - %s" +#define MAIL_SUBJECT "openarmor Notification - %s - Alert level %d" +#define MAIL_SUBJECT_FULL "openarmor Alert - %s - Level %d - %s" + +/* Full subject without openarmor in the name */ +#ifdef CLEANFULL +#define MAIL_SUBJECT_FULL2 "%d - %s - %s" +#endif + +#ifdef LIBGEOIP_ENABLED +#define MAIL_BODY "\r\nopenarmor HIDS Notification.\r\n" \ + "%s\r\n\r\n" \ + "Received From: %s\r\n" \ + "Rule: %d fired (level %d) -> \"%s\"\r\n" \ + "%s" \ + "%s" \ + "%s" \ + "Portion of the log(s):\r\n\r\n%s\r\n" \ + "\r\n\r\n --END OF NOTIFICATION\r\n\r\n\r\n" +#else +#define MAIL_BODY "\r\nopenarmor HIDS Notification.\r\n" \ + "%s\r\n\r\n" \ + "Received From: %s\r\n" \ + "Rule: %d fired (level %d) -> \"%s\"\r\n" \ + "%s" \ + "Portion of the log(s):\r\n\r\n%s\r\n" \ + "\r\n\r\n --END OF NOTIFICATION\r\n\r\n\r\n" +#endif + +/* Mail msg structure */ +typedef struct _MailMsg { + char *subject; + char *body; +} MailMsg; + +#include "shared.h" +#include "config/mail-config.h" + +/* Config function */ +int MailConf(int test_config, const char *cfgfile, MailConfig *Mail) __attribute__((nonnull)); + +/* Receive the e-mail message */ +MailMsg *OS_RecvMailQ(file_queue *fileq, struct tm *p, MailConfig *mail, + MailMsg **msg_sms) __attribute__((nonnull)); + +/* Send an email */ +int OS_Sendmail(MailConfig *mail, struct tm *p) __attribute__((nonnull)); +int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, char *idsname, char *fname, const struct tm *p); + +/* Mail timeout used by the file-queue */ +extern unsigned int mail_timeout; + +/* Global var for highest level on mail subjects */ +extern unsigned int _g_subject_level; +extern char _g_subject[SUBJECT_SIZE + 2]; + +#endif + diff --git a/src/os_maild/os_maild_client.c b/src/os_maild/os_maild_client.c new file mode 100644 index 000000000..a48c7b271 --- /dev/null +++ b/src/os_maild/os_maild_client.c @@ -0,0 +1,340 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "maild.h" +#ifdef LIBGEOIP_ENABLED +#include "config/config.h" +#endif + + +/* Receive a Message on the Mail queue */ +MailMsg *OS_RecvMailQ(file_queue *fileq, struct tm *p, + MailConfig *Mail, MailMsg **msg_sms) +{ + int i = 0, sms_set = 0, donotgroup = 0; + size_t body_size = OS_MAXSTR - 3, log_size; + char logs[OS_MAXSTR + 1]; + char extra_data[OS_MAXSTR + 1]; + char log_string[OS_MAXSTR / 4 + 1]; + char *subject_host; +#ifdef LIBGEOIP_ENABLED + char geoip_msg_src[OS_SIZE_1024 + 1]; + char geoip_msg_dst[OS_SIZE_1024 + 1]; +#endif + + MailMsg *mail; + alert_data *al_data; + + Mail->priority = 0; + + /* Get message if available */ + al_data = Read_FileMon(fileq, p, mail_timeout); + if (!al_data) { + return (NULL); + } + + /* If e-mail came correctly, generate the e-mail body/subject */ + os_calloc(1, sizeof(MailMsg), mail); + os_calloc(BODY_SIZE, sizeof(char), mail->body); + os_calloc(SUBJECT_SIZE, sizeof(char), mail->subject); + + /* Generate the logs */ + logs[0] = '\0'; + extra_data[0] = '\0'; + logs[OS_MAXSTR] = '\0'; + + while (al_data->log[i]) { + log_size = strlen(al_data->log[i]) + 4; + + /* If size left is small than the size of the log, stop it */ + if (body_size <= log_size) { + break; + } + + strncat(logs, al_data->log[i], body_size); + strncat(logs, "\r\n", body_size); + body_size -= log_size; + i++; + } + + if (al_data->old_md5) { + log_size = strlen(al_data->old_md5) + 16 + 4; + if (body_size > log_size) { + strncat(logs, "Old md5sum was: ", 16); + strncat(logs, al_data->old_md5, body_size); + strncat(logs, "\r\n", 4); + body_size -= log_size; + } + } + if (al_data->new_md5) { + log_size = strlen(al_data->new_md5) + 16 + 4; + if (body_size > log_size) { + strncat(logs, "New md5sum is : ", 16); + strncat(logs, al_data->new_md5, body_size); + strncat(logs, "\r\n", 4); + body_size -= log_size; + } + } + if (al_data->old_sha1) { + log_size = strlen(al_data->old_sha1) + 17 + 4; + if (body_size > log_size) { + strncat(logs, "Old sha1sum was: ", 17); + strncat(logs, al_data->old_sha1, body_size); + strncat(logs, "\r\n", 4); + body_size -= log_size; + } + } + if (al_data->new_sha1) { + log_size = strlen(al_data->new_sha1) + 17 + 4; + if (body_size > log_size) { + strncat(logs, "New sha1sum is : ", 17); + strncat(logs, al_data->new_sha1, body_size); + strncat(logs, "\r\n", 4); + body_size -= log_size; + } + } + if (al_data->perm_chg) { + log_size = strlen(al_data->perm_chg) + 17 + 4; + if (body_size > log_size) { + strncat(logs, "Permission change: ", 20); + strncat(logs, al_data->perm_chg, body_size); + strncat(logs, "\r\n", 4); + body_size -= log_size; + } + } + + + /* EXTRA DATA */ + if (al_data->srcip) { + log_size = snprintf(log_string, sizeof(log_string) - 1, "Src IP: %s\r\n", al_data->srcip ); + if (body_size > log_size) { + if ( strncat(extra_data, log_string, log_size) != NULL ) { + body_size -= log_size; + } + } + } + if (al_data->dstip) { + log_size = snprintf(log_string, sizeof(log_string) - 1, "Dst IP: %s\r\n", al_data->dstip ); + if (body_size > log_size) { + if ( strncat(extra_data, log_string, log_size) != NULL ) { + body_size -= log_size; + } + } + } + if (al_data->user) { + log_size = snprintf(log_string, sizeof(log_string) - 1, "User: %s\r\n", al_data->user ); + if (body_size > log_size) { + if ( strncat(extra_data, log_string, log_size) != NULL ) { + body_size -= log_size; + } + } + } + + /* Subject */ + subject_host = strchr(al_data->location, '>'); + if (subject_host) { + subject_host--; + *subject_host = '\0'; + } + + /* We have two subject options - full and normal */ + if (Mail->subject_full == 0) { + /* Option for a clean full subject (without openarmor in the name) */ +#ifdef CLEANFULL + snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL2, + al_data->level, + al_data->comment, + al_data->location); +#else + snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL, + al_data->location, + al_data->level, + al_data->comment); +#endif + } else { + snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT, + al_data->location, + al_data->level); + } + + + /* Fix subject back */ + if (subject_host) { + *subject_host = '-'; + } + +#ifdef LIBGEOIP_ENABLED + /* Get GeoIP information */ + if (Mail->geoip) { + if (al_data->srcgeoip) { + snprintf(geoip_msg_src, OS_SIZE_1024, "Src Location: %s\r\n", al_data->srcgeoip); + } else { + geoip_msg_src[0] = '\0'; + } + if (al_data->dstgeoip) { + snprintf(geoip_msg_dst, OS_SIZE_1024, "Dst Location: %s\r\n", al_data->dstgeoip); + } else { + geoip_msg_dst[0] = '\0'; + } + } else { + geoip_msg_src[0] = '\0'; + geoip_msg_dst[0] = '\0'; + } +#endif + + /* Body */ +#ifdef LIBGEOIP_ENABLED + snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY, + al_data->date, + al_data->location, + al_data->rule, + al_data->level, + al_data->comment, + geoip_msg_src, + geoip_msg_dst, + extra_data, + logs); +#else + snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY, + al_data->date, + al_data->location, + al_data->rule, + al_data->level, + al_data->comment, + extra_data, + logs); +#endif + debug2("OS_RecvMailQ: mail->body[%s]", mail->body); + + /* Check for granular email configs */ + if (Mail->gran_to) { + i = 0; + while (Mail->gran_to[i] != NULL) { + int gr_set = 0; + + /* Look if location is set */ + if (Mail->gran_location[i]) { + if (OSMatch_Execute(al_data->location, + strlen(al_data->location), + Mail->gran_location[i])) { + gr_set = 1; + } else { + i++; + continue; + } + } + + /* Look for the level */ + if (Mail->gran_level[i]) { + if (al_data->level >= Mail->gran_level[i]) { + gr_set = 1; + } else { + i++; + continue; + } + } + + /* Look for rule id */ + if (Mail->gran_id[i]) { + int id_i = 0; + while (Mail->gran_id[i][id_i] != 0) { + if (Mail->gran_id[i][id_i] == al_data->rule) { + break; + } + id_i++; + } + + /* If we found, id is going to be a valid rule */ + if (Mail->gran_id[i][id_i]) { + gr_set = 1; + } else { + i++; + continue; + } + } + + /* Look for the group */ + if (Mail->gran_group[i]) { + if (OSMatch_Execute(al_data->group, + strlen(al_data->group), + Mail->gran_group[i])) { + gr_set = 1; + } else { + i++; + continue; + } + } + + /* If we got here, everything matched. Set this e-mail to be used. */ + if (gr_set) { + if (Mail->gran_format[i] == SMS_FORMAT) { + Mail->gran_set[i] = SMS_FORMAT; + + /* Set the SMS flag */ + sms_set = 1; + } else { + /* Options */ + if (Mail->gran_format[i] == FORWARD_NOW) { + Mail->priority = 1; + Mail->gran_set[i] = FULL_FORMAT; + } else if (Mail->gran_format[i] == DONOTGROUP) { + Mail->priority = DONOTGROUP; + Mail->gran_set[i] = DONOTGROUP; + donotgroup = 1; + } else { + Mail->gran_set[i] = FULL_FORMAT; + } + } + } + i++; + } + } + + + /* If DONOTGROUP is set, we can't assign the new subject */ + if (!donotgroup) { + /* Get highest level for alert */ + if (_g_subject[0] != '\0') { + if (_g_subject_level < al_data->level) { + strncpy(_g_subject, mail->subject, SUBJECT_SIZE); + _g_subject_level = al_data->level; + } + } else { + strncpy(_g_subject, mail->subject, SUBJECT_SIZE); + _g_subject_level = al_data->level; + } + } + + /* If SMS is set, create the SMS output */ + if (sms_set) { + MailMsg *msg_sms_tmp; + + /* Allocate memory for SMS */ + os_calloc(1, sizeof(MailMsg), msg_sms_tmp); + os_calloc(BODY_SIZE, sizeof(char), msg_sms_tmp->body); + os_calloc(SUBJECT_SIZE, sizeof(char), msg_sms_tmp->subject); + + snprintf(msg_sms_tmp->subject, SUBJECT_SIZE - 1, SMS_SUBJECT, + al_data->level, + al_data->rule, + al_data->comment); + + + strncpy(msg_sms_tmp->body, logs, 128); + msg_sms_tmp->body[127] = '\0'; + *msg_sms = msg_sms_tmp; + } + + /* Clear the memory */ + FreeAlertData(al_data); + + return (mail); +} + diff --git a/src/os_maild/sendcustomemail.c b/src/os_maild/sendcustomemail.c new file mode 100644 index 000000000..3a8dd1294 --- /dev/null +++ b/src/os_maild/sendcustomemail.c @@ -0,0 +1,333 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Basic e-mailing operations */ + +#include "shared.h" +#include "os_net/os_net.h" + +/* Return codes (from SMTP server) */ +#define VALIDBANNER "220" +#define VALIDMAIL "250" +#define VALIDDATA "354" + +/* Default values used to connect */ +#define SMTP_DEFAULT_PORT "25" +#define HELOMSG "Helo notify.theopenarmor.org\r\n" +#define MAILFROM "Mail From: <%s>\r\n" +#define RCPTTO "Rcpt To: <%s>\r\n" +#define DATAMSG "DATA\r\n" +#define FROM "From: openarmor HIDS <%s>\r\n" +#define REPLYTO "Reply-To: openarmor HIDS <%s>\r\n" +#define TO "To: <%s>\r\n" +#define CC "Cc: <%s>\r\n" +#define SUBJECT "Subject: %s\r\n" +#define ENDHEADER "\r\n" +#define ENDDATA "\r\n.\r\n" +#define QUITMSG "QUIT\r\n" +#define XHEADER "X-IDS-openarmor: %s\r\n" + +/* Error messages - Can be translated */ +#define INTERNAL_ERROR "os_maild (1760): ERROR: Memory/configuration error" +#define BANNER_ERROR "os_sendmail(1762): WARN: Banner not received from server" +#define HELO_ERROR "os_sendmail(1763): WARN: Hello not accepted by server" +#define FROM_ERROR "os_sendmail(1764): WARN: Mail from not accepted by server" +#define TO_ERROR "os_sendmail(1765): WARN: RCPT TO not accepted by server - '%s'." +#define DATA_ERROR "os_sendmail(1766): WARN: DATA not accepted by server" +#define END_DATA_ERROR "os_sendmail(1767): WARN: End of DATA not accepted by server" + +#define MAIL_DEBUG_FLAG 0 +#define MAIL_DEBUG(x,y,z) if(MAIL_DEBUG_FLAG) merror(x,y,z) + + +int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, char *replyto, char *idsname, char *fname, const struct tm *p) +{ + FILE *sendmail = NULL; + int socket = -1, i = 0; + char *msg; + char snd_msg[128]; + char buffer[2049]; + + buffer[2048] = '\0'; + + if (smtpserver[0] == '/') { + sendmail = popen(smtpserver, "w"); + if (!sendmail) { + return (OS_INVALID); + } + } else { + /* Connect to the SMTP server */ + socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver); + if (socket < 0) { + return (socket); + } + + /* Receive the banner */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { + merror(BANNER_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); + free(msg); + + /* Send HELO message */ + OS_SendTCP(socket, HELOMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + if (msg) { + /* In some cases (with virus scans in the middle) + * we may get two banners. Check for that in here. + */ + if (OS_Match(VALIDBANNER, msg)) { + free(msg); + + /* Try again */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + } else { + merror("%s:%s", HELO_ERROR, msg); + free(msg); + close(socket); + return (OS_INVALID); + } + } else { + merror("%s:%s", HELO_ERROR, "null"); + close(socket); + return (OS_INVALID); + } + } + + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); + free(msg); + + /* Build "Mail from" msg */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, MAILFROM, from); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(FROM_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + /* Build "RCPT TO" msg */ + while (to[i]) { + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, to[i]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, to[i]); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + i++; + } + + /* Send the "DATA" msg */ + OS_SendTCP(socket, DATAMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { + merror(DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); + free(msg); + } + + /* Build "From" and "To" in the e-mail header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, to[0]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, FROM, from); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + if (replyto) { + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, REPLYTO, replyto); + if(sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + } + + /* Add CCs */ + if (to[1]) { + i = 1; + while (1) { + if (to[i] == NULL) { + break; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, to[i]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + i++; + } + } + + /* Send date */ + memset(snd_msg, '\0', 128); + + /* Solaris doesn't have the "%z", so we set the timezone to 0 */ +#ifdef SOLARIS + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n", p); +#else + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); +#endif + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + if (idsname) { + /* Send server name header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, XHEADER, idsname); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + } + + /* Send subject */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, SUBJECT, subject); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + fprintf(sendmail, ENDHEADER); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + } + + /* Send body */ + FILE *fp; + fp = fopen(fname, "r"); + if(!fp) { + merror("%s: ERROR: Cannot open %s: %s", __local_name, fname, strerror(errno)); + if(socket >= 0) { + close(socket); + } + if(sendmail) { + pclose(sendmail); + } + return(1); + } + + + struct stat sb; + int sr; + sr = stat(fname, &sb); + if(sr < 0) { + merror("Cannot stat %s: %s", fname, strerror(errno)); + } + if(sb.st_size == 0) { + merror("Report is empty"); + if(socket >= 0) { + close(socket); + } + if(sendmail) { + pclose(sendmail); + } + if(fp) { + fclose(fp); + } + return(0); + } + while (fgets(buffer, 2048, fp) != NULL) { + if (sendmail) { + fprintf(sendmail, "%s", buffer); + } else { + OS_SendTCP(socket, buffer); + } + } + fclose(fp); + + if (sendmail) { + if (pclose(sendmail) == -1) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + } + } else { + /* Send end of data \r\n.\r\n */ + OS_SendTCP(socket, ENDDATA); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + /* Check msg, since it may be null */ + if (msg) { + free(msg); + } + + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + if (msg) { + free(msg); + } + + close(socket); + } + + memset_secure(snd_msg, '\0', 128); + return (0); +} + diff --git a/src/os_maild/sendmail.c b/src/os_maild/sendmail.c new file mode 100644 index 000000000..28b71801a --- /dev/null +++ b/src/os_maild/sendmail.c @@ -0,0 +1,394 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Basic e-mailing operations */ + +#include "shared.h" +#include "os_net/os_net.h" +#include "maild.h" +#include "mail_list.h" + +/* Return codes (from SMTP server) */ +#define VALIDBANNER "220" +#define VALIDMAIL "250" +#define VALIDDATA "354" + +/* Default values used to connect */ +#define SMTP_DEFAULT_PORT "25" +#define MAILFROM "Mail From: <%s>\r\n" +#define RCPTTO "Rcpt To: <%s>\r\n" +#define DATAMSG "DATA\r\n" +#define FROM "From: openarmor HIDS <%s>\r\n" +#define TO "To: <%s>\r\n" +#define REPLYTO "Reply-To: openarmor HIDS <%s>\r\n" +/*#define CC "Cc: <%s>\r\n"*/ +#define SUBJECT "Subject: %s\r\n" +#define ENDHEADER "\r\n" +#define ENDDATA "\r\n.\r\n" +#define QUITMSG "QUIT\r\n" +#define XHEADER "X-IDS-openarmor: %s\r\n" + +/* Error messages - Can be translated */ +#define INTERNAL_ERROR "os_maild (1760): ERROR: Memory/configuration error" +#define BANNER_ERROR "os_sendmail(1762): WARN: Banner not received from server" +#define HELO_ERROR "os_sendmail(1763): WARN: Hello not accepted by server" +#define FROM_ERROR "os_sendmail(1764): WARN: Mail from not accepted by server" +#define TO_ERROR "os_sendmail(1765): WARN: RCPT TO not accepted by server - '%s'." +#define DATA_ERROR "os_sendmail(1766): WARN: DATA not accepted by server" +#define END_DATA_ERROR "os_sendmail(1767): WARN: End of DATA not accepted by server" + +#define MAIL_DEBUG_FLAG 0 +#define MAIL_DEBUG(x,y,z) if(MAIL_DEBUG_FLAG) merror(x,y,z) + + +int OS_Sendmail(MailConfig *mail, struct tm *p) +{ + FILE *sendmail = NULL; + int socket = -1; + unsigned int i = 0; + char *msg; + char snd_msg[128]; + + MailNode *mailmsg; + + /* If there is no sms message, attempt to get from the email list */ + mailmsg = OS_PopLastMail(); + + if (mailmsg == NULL) { + merror("%s: No email to be sent. Inconsistent state.", ARGV0); + return (OS_INVALID); + } + + if (mail->smtpserver[0] == '/') { + sendmail = popen(mail->smtpserver, "w"); + if (!sendmail) { + return (OS_INVALID); + } + } else { + /* Connect to the SMTP server */ + socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver); + if (socket < 0) { + return (socket); + } + + /* Receive the banner */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { + merror(BANNER_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); + free(msg); + + /* Send HELO message */ + memset(snd_msg, '\0', 128); + if (mail->heloserver) { + snprintf(snd_msg, 127, "Helo %s\r\n", mail->heloserver); + } else { + snprintf(snd_msg, 127, "Helo %s\r\n", "notify.theopenarmor.org"); + } + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + if (msg) { + /* In some cases (with virus scans in the middle) + * we may get two banners. Check for that in here. + */ + if (OS_Match(VALIDBANNER, msg)) { + free(msg); + + /* Try again */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + } else { + merror("%s:%s", HELO_ERROR, msg); + free(msg); + close(socket); + return (OS_INVALID); + } + } else { + merror("%s:%s", HELO_ERROR, "null"); + close(socket); + return (OS_INVALID); + } + } + + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + /* Build "Mail from" msg */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, MAILFROM, mail->from); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(FROM_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + /* Build "RCPT TO" msg */ + while (1) { + if (mail->to[i] == NULL) { + if (i == 0) { + merror(INTERNAL_ERROR); + close(socket); + return (OS_INVALID); + } + break; + } + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, mail->to[i++]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, mail->to[i - 1]); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + } + + /* Additional RCPT to */ + if (mail->gran_to) { + i = 0; + while (mail->gran_to[i] != NULL) { + if (mail->gran_set[i] != FULL_FORMAT) { + i++; + continue; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, mail->gran_to[i]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, mail->gran_to[i]); + if (msg) { + free(msg); + } + + i++; + continue; + } + + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + i++; + continue; + } + } + + /* Send the "DATA" msg */ + OS_SendTCP(socket, DATAMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { + merror(DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); + free(msg); + } + + /* Building "From" and "To" in the e-mail header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, mail->to[0]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, FROM, mail->from); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + /* Send reply-to if set */ + if (mail->reply_to){ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, REPLYTO, mail->reply_to); + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + } + + /* Add CCs */ + if (mail->to[1]) { + i = 1; + while (1) { + if (mail->to[i] == NULL) { + break; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, mail->to[i]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + i++; + } + } + + /* More CCs - from granular options */ + if (mail->gran_to) { + i = 0; + while (mail->gran_to[i] != NULL) { + if (mail->gran_set[i] != FULL_FORMAT) { + i++; + continue; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, mail->gran_to[i]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + i++; + continue; + } + } + + /* Send date */ + memset(snd_msg, '\0', 128); + + /* Solaris doesn't have the "%z", so we set the timezone to 0 */ +#ifdef SOLARIS + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n", p); +#else + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); +#endif + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + if (mail->idsname) { + /* Send server name header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, XHEADER, mail->idsname); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + } + + /* Send subject */ + memset(snd_msg, '\0', 128); + + /* Check if global subject is available */ + if ((_g_subject_level != 0) && (_g_subject[0] != '\0')) { + snprintf(snd_msg, 127, SUBJECT, _g_subject); + + /* Clear global values */ + _g_subject[0] = '\0'; + _g_subject_level = 0; + } else { + snprintf(snd_msg, 127, SUBJECT, mailmsg->mail->subject); + } + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + fprintf(sendmail, ENDHEADER); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + } + + /* Send body */ + + /* Send multiple emails together if we have to */ + do { + if (sendmail) { + fprintf(sendmail, "%s", mailmsg->mail->body); + } else { + OS_SendTCP(socket, mailmsg->mail->body); + } + mailmsg = OS_PopLastMail(); + } while (mailmsg); + + if (sendmail) { + if (pclose(sendmail) == -1) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + } + } else { + /* Send end of data \r\n.\r\n */ + OS_SendTCP(socket, ENDDATA); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if (mail->strict_checking && ((msg == NULL) || (!OS_Match(VALIDMAIL, msg)))) { + merror(END_DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + + /* Check msg, since it may be null */ + if (msg) { + free(msg); + } + + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + if (msg) { + free(msg); + } + + close(socket); + } + + memset_secure(snd_msg, '\0', 128); + return (0); +} diff --git a/src/os_net/COPYRIGHT b/src/os_net/COPYRIGHT new file mode 100644 index 000000000..090dd3828 --- /dev/null +++ b/src/os_net/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (C) 2009 Trend Micro Inc. + All rights reserved. + This program is a free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License (version 2) as published by the FSF - Free Software + Foundation + +openarmor, os_net library. +Available at http://www.theopenarmor.org/ diff --git a/src/os_net/VERSION b/src/os_net/VERSION new file mode 100644 index 000000000..be5863417 --- /dev/null +++ b/src/os_net/VERSION @@ -0,0 +1 @@ +0.3 diff --git a/src/os_net/os_net.c b/src/os_net/os_net.c new file mode 100644 index 000000000..a420836b5 --- /dev/null +++ b/src/os_net/os_net.c @@ -0,0 +1,861 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* OS_net Library + * APIs for many network operations + */ + +#include +#include "shared.h" +#include "os_net.h" +agent *os_net_agt; + +/* Prototypes */ +static OSNetInfo *OS_Bindport(char *_port, unsigned int _proto, const char *_ip); +static int OS_Connect(char *_port, unsigned int protocol, const char *_ip); +static int OS_DecodeAddrinfo (struct addrinfo *res); +static char *OS_DecodeSockaddr (struct sockaddr *sa); +static char *DecodeFamily (int val); +static char *DecodeSocktype (int val); +static char *DecodeProtocol (int val); + +/* Unix socket -- not for windows */ +#ifndef WIN32 +static struct sockaddr_un n_us; +static socklen_t us_l = sizeof(n_us); + +/* UNIX SOCKET */ +#ifndef SUN_LEN +#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + + strlen ((ptr)->sun_path)) +#endif /* Sun_LEN */ + +#else /* WIN32 */ +/*int ENOBUFS = 0;*/ +#ifndef ENOBUFS +#define ENOBUFS 0 +#endif + +#endif /* WIN32*/ + + +/* Bind all relevant ports */ +OSNetInfo *OS_Bindport(char *_port, unsigned int _proto, const char *_ip) +{ + int ossock = 0, s; + struct addrinfo hints, *result, *rp; + OSNetInfo *ni; /* return data */ + + /* Allocate the return data structure and initialize it. */ + ni = malloc (sizeof (OSNetInfo)); + memset(ni, 0, sizeof (OSNetInfo)); + FD_ZERO (&(ni->fdset)); + ni->fdmax = 0; + ni->fdcnt = 0; + ni->status = 0; + ni->retval = 0; + + /* init hints for getaddrinfo() */ + memset(&hints, 0, sizeof(struct addrinfo)); + + /* + * If you cannot bind both IPv4 and IPv6, the problem is likely due to the + * AF_INET6 family with the AI_V4MAPPED flag. Alter your Makefile to use the + * NOV4MAP define and it should work like a breeze. All of the *BSDs fall + * into this category even though AI_V4MAPPED exists in netdb.h (true for + * all modern OS's). This should work with all Linux versions too, but the + * original code for AF_INET6 was left for Linux because it works. + * + * d. stoddard - 4/19/2018 + */ + +#if defined(__linux__) && !defined(NOV4MAP) +#if defined (AI_V4MAPPED) + hints.ai_family = AF_INET6; /* Allow IPv4 and IPv6 */ + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG | AI_V4MAPPED; +#else + /* handle as normal IPv4 and IPv6 multi request */ + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; +#endif /* AI_V4MAPPED */ +#else + /* FreeBSD, OpenBSD, NetBSD, and others */ + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; +#endif + + hints.ai_protocol = _proto; + if (_proto == IPPROTO_UDP) { + hints.ai_socktype = SOCK_DGRAM; + } else if (_proto == IPPROTO_TCP) { + hints.ai_socktype = SOCK_STREAM; + } else { + ni->status = -1; + ni->retval = OS_INVALID; + return(ni); + } + + /* get linked list of adresses */ + s = getaddrinfo(_ip, _port, &hints, &result); + + /* Try to support legacy ipv4 only hosts */ + if((s == EAI_FAMILY) || (s == EAI_NONAME)) { + hints.ai_family = AF_INET; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + s = getaddrinfo(_ip, _port, &hints, &result); + } + + if (s != 0) { + verbose("getaddrinfo: %s", gai_strerror(s)); + ni->status = -1; + ni->retval = OS_INVALID; + return(ni); + } + + /* log the list of connections available */ + OS_DecodeAddrinfo (result); + + /* + * getaddrinfo() returns a list of address structures. We try each + * address and attempt to connect to it. If a socket(2) or bind(2) fails, + * we close the socket and try the next address. We repeat this for every + * address getaddrinfo() returns in the addrinfo linked list. + */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + ossock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (ossock == -1) { + verbose ("socket error: family %s type %s protocol %s: %s", + DecodeFamily (rp->ai_family), + DecodeSocktype (rp->ai_socktype), + DecodeProtocol (rp->ai_protocol), + strerror(errno)); + continue; + } + + if (_proto == IPPROTO_TCP) { + int flag = 1; + if (setsockopt(ossock, SOL_SOCKET, SO_REUSEADDR, + (char *)&flag, sizeof(flag)) < 0) { + verbose ("setsockopt error: SO_REUSEADDR %d: %s", + errno, strerror(errno)); + if(ossock > 0) { + OS_CloseSocket(ossock); + } + continue; + } + } + + if (bind(ossock, rp->ai_addr, rp->ai_addrlen) == -1) { + /* + * Don't issue an error message if the address and port is already + * bound. This can happen when 0.0.0.0 or :: are bound in a + * previous iteration of this loop. + */ + if (errno == EADDRINUSE) { + close (ossock); + continue; + } + + /* tell them why this address failed */ + verbose ("Bind failed on socket for %s: %s", + OS_DecodeSockaddr (rp->ai_addr), strerror (errno)); + close (ossock); + continue; + } + + if (_proto == IPPROTO_TCP) { + if (listen(ossock, 32) < 0) { + verbose ("Request to listen() failed on socket for %s: %s", + OS_DecodeSockaddr (rp->ai_addr), strerror (errno)); + close (ossock); + continue; + } + verbose ("Request for TCP listen() succeeded."); + } + + /* success - accumulate data for select call */ + verbose ("Socket bound for %s", OS_DecodeSockaddr (rp->ai_addr)); + + /* save bound socket info for select() */ + ni->fds[ni->fdcnt++] = ossock; /* increment after use! */ + FD_SET (ossock, &(ni->fdset)); + if (ossock > ni->fdmax) { + ni->fdmax = ossock; + } + } + + /* check to see if at least one address succeeded */ + if (ni->fdcnt == 0) { + verbose ("Request to allocate and bind sockets failed."); + ni->status = -1; + ni->retval = OS_SOCKTERR; + if(result) { + freeaddrinfo(result); + } + return(ni); + } + + freeaddrinfo(result); /* No longer needed */ + ni->fdmax += 1; /* prep for use with select() */ + return (ni); +} + + +/* Bind a TCP port, using the OS_Bindport */ +OSNetInfo *OS_Bindporttcp(char *_port, const char *_ip) +{ + return (OS_Bindport(_port, IPPROTO_TCP, _ip)); +} + +/* Bind a UDP port, using the OS_Bindport */ +OSNetInfo *OS_Bindportudp(char *_port, const char *_ip) +{ + return (OS_Bindport(_port, IPPROTO_UDP, _ip)); +} + +#ifndef WIN32 +/* Bind to a Unix domain, using DGRAM sockets */ +int OS_BindUnixDomain(const char *path, mode_t mode, int max_msg_size) +{ + int len; + int ossock = 0; + socklen_t optlen = sizeof(len); + + /* Make sure the path isn't there */ + int urc = -1; + if (( urc = unlink(path)) < 0) { + /* XXX I think we're blindly unlinking path, so if it doesn't exist, don't log an error */ + if (urc != ENOENT) { + merror("ERROR: Cannot unlink file %s: %s", path, strerror(errno)); + } + } + + memset(&n_us, 0, sizeof(n_us)); + n_us.sun_family = AF_UNIX; + strncpy(n_us.sun_path, path, sizeof(n_us.sun_path) - 1); + + if ((ossock = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { + return (OS_SOCKTERR); + } + + if (bind(ossock, (struct sockaddr *)&n_us, SUN_LEN(&n_us)) < 0) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + + /* Change permissions */ + if (chmod(path, mode) < 0) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + + /* Get current maximum size */ + if (getsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + + /* Set socket opt */ + if (len < max_msg_size) { + len = max_msg_size; + if (setsockopt(ossock, SOL_SOCKET, SO_RCVBUF, &len, optlen) < 0) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + } + + return (ossock); +} + +/* Open a client Unix domain socket + * ("/tmp/lala-socket",0666)); + */ +int OS_ConnectUnixDomain(const char *path, int max_msg_size) +{ + int len; + int ossock = 0; + socklen_t optlen = sizeof(len); + + memset(&n_us, 0, sizeof(n_us)); + + n_us.sun_family = AF_UNIX; + + /* Set up path */ + strncpy(n_us.sun_path, path, sizeof(n_us.sun_path) - 1); + + if ((ossock = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { + return (OS_SOCKTERR); + } + + /* Connect to the UNIX domain */ + if (connect(ossock, (struct sockaddr *)&n_us, SUN_LEN(&n_us)) < 0) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + + /* Get current maximum size */ + if (getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + + /* Set maximum message size */ + if (len < max_msg_size) { + len = max_msg_size; + if (setsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, optlen) < 0) { + OS_CloseSocket(ossock); + return (OS_SOCKTERR); + } + } + + return (ossock); +} + +int OS_getsocketsize(int ossock) +{ + int len = 0; + socklen_t optlen = sizeof(len); + + /* Get current maximum size */ + if (getsockopt(ossock, SOL_SOCKET, SO_SNDBUF, &len, &optlen) == -1) { + OS_CloseSocket(ossock); + return(OS_SOCKTERR); + } + + return (len); +} + +#endif + +/* Open a TCP/UDP client socket */ +int OS_Connect(char *_port, unsigned int protocol, const char *_ip) +{ + int ossock = 0, s; + struct addrinfo hints, *result, *rp, *local_ai = NULL; + char tempaddr[INET6_ADDRSTRLEN]; + + if ((_ip == NULL)||(_ip[0] == '\0')) { + OS_CloseSocket(ossock); + return(OS_INVALID); + } + + if (os_net_agt) { + if (os_net_agt->lip) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST; + s = getaddrinfo(os_net_agt->lip, NULL, &hints, &result); + if (s != 0) { + verbose("getaddrinfo: %s", gai_strerror(s)); + } + else { + local_ai = result; + } + } + } + + memset(&hints, 0, sizeof(struct addrinfo)); + /* Allow IPv4 or IPv6 if local_ip isn't specified */ + hints.ai_family = AF_UNSPEC; + if (os_net_agt) { + if (os_net_agt->lip) { + hints.ai_family = local_ai->ai_family; + } + } + hints.ai_protocol = protocol; + if (protocol == IPPROTO_TCP) { + hints.ai_socktype = SOCK_STREAM; + } else if (protocol == IPPROTO_UDP) { + hints.ai_socktype = SOCK_DGRAM; + } else { + return(OS_INVALID); + } + hints.ai_flags = 0; + + s = getaddrinfo(_ip, _port, &hints, &result); + if (s != 0) { + verbose("getaddrinfo: %s", gai_strerror(s)); + if(result) { + freeaddrinfo(result); + } + return(OS_INVALID); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully connect(2). + If socket(2) (or connect(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + ossock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (ossock == -1) { + continue; + } + + if (os_net_agt) { + if (os_net_agt->lip) { + if (bind(ossock, local_ai->ai_addr, local_ai->ai_addrlen)) { + verbose("Unable to bind to local address %s. Ignoring. (%s)", + os_net_agt->lip, strerror(errno)); + } + else verbose("Connecting from local address %s", os_net_agt->lip); + } + } + + if (connect(ossock, rp->ai_addr, rp->ai_addrlen) != -1) { + break; /* Success */ + } + } + if (rp == NULL) { /* No address succeeded */ + if (ossock > 0) { + OS_CloseSocket(ossock); + } + if(result) { + freeaddrinfo(result); + } + return(OS_SOCKTERR); + } + satop(rp->ai_addr, tempaddr, sizeof tempaddr); + verbose("INFO: Connected to %s at address %s, port %s", _ip, + tempaddr, _port); + + freeaddrinfo(result); /* No longer needed */ + + #ifdef HPUX + { + int flags; + flags = fcntl(ossock,F_GETFL,0); + fcntl(ossock, F_SETFL, flags | O_NONBLOCK); + } + #endif + + return(ossock); +} + + +/* Open a TCP socket */ +int OS_ConnectTCP(char *_port, const char *_ip) +{ + return (OS_Connect(_port, IPPROTO_TCP, _ip)); +} + +/* Open a UDP socket */ +int OS_ConnectUDP(char *_port, const char *_ip) +{ + return (OS_Connect(_port, IPPROTO_UDP, _ip)); +} + +/* Send a TCP packet (through an open socket) */ +int OS_SendTCP(int socket, const char *msg) +{ + if ((send(socket, msg, strlen(msg), 0)) <= 0) { + return (OS_SOCKTERR); + } + + return (0); +} + +/* Send a TCP packet of a specific size (through a open socket) */ +int OS_SendTCPbySize(int socket, int size, const char *msg) +{ + if ((send(socket, msg, size, 0)) < size) { + return (OS_SOCKTERR); + } + + return (0); +} + +/* Send a UDP packet of a specific size (through an open socket) */ +int OS_SendUDPbySize(int socket, int size, const char *msg) +{ + unsigned int i = 0; + + /* Maximum attempts is 5 */ + while ((send(socket, msg, size, 0)) < 0) { + if ((errno != ENOBUFS) || (i >= 5)) { + return (OS_SOCKTERR); + } + + i++; + merror("%s: INFO: Remote socket busy, waiting %d s.", __local_name, i); + sleep(i); + } + + return (0); +} + +/* Accept a TCP connection */ +int OS_AcceptTCP(int socket, char *srcip, size_t addrsize) +{ + int clientsocket; + struct sockaddr_storage _nc; + socklen_t _ncl; + + memset(&_nc, 0, sizeof(_nc)); + _ncl = sizeof(_nc); + + if ((clientsocket = accept(socket, (struct sockaddr *) &_nc, + &_ncl)) < 0) { + return (-1); + } + + satop((struct sockaddr *) &_nc, srcip, addrsize -1); + srcip[addrsize -1] = '\0'; + + return (clientsocket); +} + +/* Receive a TCP packet (from an open socket) */ +char *OS_RecvTCP(int socket, int sizet) +{ + char *ret; + + ret = (char *) calloc((sizet), sizeof(char)); + if (ret == NULL) { + return (NULL); + } + + if (recv(socket, ret, sizet - 1, 0) <= 0) { + free(ret); + return (NULL); + } + + return (ret); +} + +/* Receive a TCP packet (from an open socket) */ +int OS_RecvTCPBuffer(int socket, char *buffer, int sizet) +{ + int retsize; + + if ((retsize = recv(socket, buffer, sizet - 1, 0)) > 0) { + buffer[retsize] = '\0'; + return (retsize); + } + return (-1); +} + +/* Receive a UDP packet */ +char *OS_RecvUDP(int socket, int sizet) +{ + char *ret; + + ret = (char *) calloc((sizet), sizeof(char)); + if (ret == NULL) { + return (NULL); + } + + if ((recv(socket, ret, sizet - 1, 0)) < 0) { + free(ret); + return (NULL); + } + + return (ret); +} + +/* Receives a message from a connected UDP socket */ +int OS_RecvConnUDP(int socket, char *buffer, int buffer_size) +{ + int recv_b; + + recv_b = recv(socket, buffer, buffer_size, 0); + if (recv_b < 0) { + return (0); + } + + buffer[recv_b] = '\0'; + + return (recv_b); +} + +#ifndef WIN32 +/* Receive a message from a Unix socket */ +int OS_RecvUnix(int socket, int sizet, char *ret) +{ + ssize_t recvd; + if ((recvd = recvfrom(socket, ret, sizet - 1, 0, + (struct sockaddr *)&n_us, &us_l)) < 0) { + return (0); + } + + ret[recvd] = '\0'; + return ((int)recvd); +} + +/* Send a message using a Unix socket + * Returns the OS_SOCKETERR if it fails + */ +int OS_SendUnix(int socket, const char *msg, int size) +{ + if (size == 0) { + size = strlen(msg) + 1; + } + + if (send(socket, msg, size, 0) < size) { + if (errno == ENOBUFS) { + return (OS_SOCKBUSY); + } + + return (OS_SOCKTERR); + } + + return (OS_SUCCESS); +} +#endif + +/* Calls getaddrinfo (tries x attempts) */ +char *OS_GetHost(const char *host, unsigned int attempts) +{ + unsigned int i = 0; + int error; + + char *ip; + struct addrinfo *hai, *result; + + if (host == NULL) { + return (NULL); + } + + while (i <= attempts) { + if ((error = getaddrinfo(host, NULL, NULL, &result)) != 0) { + sleep(i++); + continue; + } + + if ((ip = (char *) calloc(IPSIZE, sizeof(char))) == NULL) { + if (result) { + freeaddrinfo(result); + } + return (NULL); + } + + hai = result; + satop(hai->ai_addr, ip, IPSIZE); + + freeaddrinfo(result); + return (ip); + } + + return (NULL); +} + +/* satop(struct sockaddr *sa, char *dst, socklen_t size) + * Convert a sockaddr to a printable address. + */ +int satop(struct sockaddr *sa, char *dst, socklen_t size) +{ + sa_family_t af; + struct sockaddr_in *sa4; + struct sockaddr_in6 *sa6; +#ifdef WIN32 + int newlength; +#endif + + af = sa->sa_family; + + switch (af) + { + case AF_INET: + sa4 = (struct sockaddr_in *) sa; +#ifdef WIN32 + newlength = size; + WSAAddressToString((LPSOCKADDR) sa4, sizeof(struct sockaddr_in), + NULL, dst, (LPDWORD) &newlength); +#else + inet_ntop(af, (const void *) &(sa4->sin_addr), dst, size); +#endif + return(0); + case AF_INET6: + sa6 = (struct sockaddr_in6 *) sa; +#ifdef WIN32 + newlength = size; + WSAAddressToString((LPSOCKADDR) sa6, sizeof(struct sockaddr_in6), + NULL, dst, (LPDWORD) &newlength); +#else + inet_ntop(af, (const void *) &(sa6->sin6_addr), dst, size); +#endif + if (IN6_IS_ADDR_V4MAPPED(&(sa6->sin6_addr))) + { /* extract the embedded IPv4 address */ + memmove(dst, dst+7, size-7); + } + return(0); + default: + *dst = '\0'; + return(-1); + } +} + +int OS_CloseSocket(int socket) +{ +#ifdef WIN32 + return (closesocket(socket)); +#else + return (close(socket)); +#endif /* WIN32 */ +} + + +/* + * OS_DecodeAddrinfo() will decode the contents of an addrinfo structure and + * log the IP version, address, and port number for each item in the + * linked list of addrinfo structs. + */ + +int OS_DecodeAddrinfo (struct addrinfo *res) { + struct addrinfo *p; /* pointer to addrinfo structs */ + + for (p = res; p != NULL; p = p->ai_next) + verbose ("%s",OS_DecodeSockaddr (p->ai_addr)); + return 0; +} + + +/* + * OS_DecodeSockaddr() will decode a socket address and return a string with + * the IP version, address, and port number. + */ + +char *OS_DecodeSockaddr (struct sockaddr *sa) { + int rc; /* return code */ + char ipaddr[INET6_ADDRSTRLEN]; /* printed address */ + char ipport[NI_MAXSERV]; /* printed port */ + static char buf[256]; /* message buffer */ + +#if defined(__linux__) || defined (WIN32) || defined (SOLARIS) + /* most Linux systems do not have sa_len in the sockaddr struct */ + socklen_t slen = 0; + switch(sa->sa_family) { + case AF_INET: + slen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + slen = sizeof(struct sockaddr_in6); + break; + default: + // XXX WTF + break; + } + rc = getnameinfo ((struct sockaddr *) sa, slen, ipaddr, + sizeof (ipaddr), ipport, sizeof (ipport), + NI_NUMERICHOST | NI_NUMERICSERV); +#else + /* BSD systems require the value in sa->sa_len or error 4 occurs */ + rc = getnameinfo ((struct sockaddr *) sa, sa->sa_len, ipaddr, + sizeof (ipaddr), ipport, sizeof (ipport), + NI_NUMERICHOST | NI_NUMERICSERV); +#endif + + if (rc) { + sprintf (buf, "Error %d on getnameinfo: %s", rc, gai_strerror (rc)); + return (buf); + } + + sprintf (buf, "%s: %s on port %s", + DecodeFamily (sa->sa_family), ipaddr, ipport); + return buf; +} + + +/* + * DecodeFamily() is used to convert the IP family into a string for info + * and debugging purposes. + */ + +char *DecodeFamily (int val) { + static char buf[32]; /* response */ + + switch (val) { + case AF_INET: + strcpy (buf,"IPv4"); + break; + case AF_INET6: + strcpy (buf,"IPv6"); + break; + default: + sprintf (buf, "Unknown Family %d", val); + break; + } + + return (buf); +} + + +/* + * DecodeSocktype() is used to convert the IP socket type into a string for + * info and debugging purposes. + */ + +char *DecodeSocktype (int val) { + static char buf[32]; /* response */ + + switch (val) { + case SOCK_STREAM: + strcpy (buf,"STREAM"); + break; + case SOCK_DGRAM: + strcpy (buf,"DGRAM"); + break; + case SOCK_RAW: + strcpy (buf,"RAW"); + break; + default: + sprintf (buf, "Unknown Sock Type %d", val); + break; + } + + return (buf); +} + + +/* + * DecodeProtocol() is used to convert the IP protocol into a string for info + * and debugging purposes. + */ + +char *DecodeProtocol (int val) { + static char buf[32]; /* response */ + + switch (val) { + case IPPROTO_IP: + strcpy (buf,"IP"); + break; + case IPPROTO_ICMP: + strcpy (buf,"ICMP"); + break; + case IPPROTO_TCP: + strcpy (buf,"TCP"); + break; + case IPPROTO_UDP: + strcpy (buf,"UDP"); + break; + default: + sprintf (buf, "Unknown Protocol %d", val); + break; + } + + return (buf); +} + +#ifndef WIN32 +/* Set a socket to be non-blocking */ +int setnonblock(int fd) { + int flags; + + flags = fcntl(fd, F_GETFL); + if (flags < 0) + return flags; + flags |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, flags) < 0) { + return -1; + } + + return 0; +} +#endif //WIN32 + diff --git a/src/os_net/os_net.h b/src/os_net/os_net.h new file mode 100644 index 000000000..3aaf00429 --- /dev/null +++ b/src/os_net/os_net.h @@ -0,0 +1,129 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* OS_net Library + * APIs for many network operations + */ + +#include "headers/shared.h" +#include "config/client-config.h" +extern agent *os_net_agt; +#ifdef WIN32 +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0x0400 +#endif +#ifndef AI_V4MAPPED +#define AI_V4MAPPED 0x0800 +#endif +typedef unsigned short int sa_family_t; +#endif /* WIN32 */ + + +#ifndef __OS_NET_H +#define __OS_NET_H +#ifdef _WIN32 +#include +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +#endif + +#ifndef WIN32 +#include +#endif //WIN32 + +/* + * OSNetInfo is used to exchange a set of bound sockets for use with the + * select() function for monitoring incoming packets on multiple interfaces. + * This allows you to support IPv4 and IPv6 simultaneously. + */ + +typedef struct _OSNetInfo { + fd_set fdset; /* set of sockets used by select ()*/ + int fdmax; /* fd max socket for select() */ + int fds[FD_SETSIZE]; /* array of bound sockets for send() */ + int fdcnt; /* number of sockets in array */ + int status; /* return status (-1 is error) */ + int retval; /* return value (additional info) */ +} OSNetInfo; + +/* + * OS_Bindport* + * Bind a specific port (protocol and a ip). + * If the IP is not set, it is going to use ADDR_ANY + * Return a pointer to the OSNetInfo struct. + */ + +OSNetInfo *OS_Bindporttcp(char *_port, const char *_ip); +OSNetInfo *OS_Bindportudp(char *_port, const char *_ip); + +/* OS_BindUnixDomain + * Bind to a specific file, using the "mode" permissions in + * a Unix Domain socket. + */ +int OS_BindUnixDomain(const char *path, mode_t mode, int max_msg_size) __attribute__((nonnull)); +int OS_ConnectUnixDomain(const char *path, int max_msg_size) __attribute__((nonnull)); +int OS_getsocketsize(int ossock); + +/* OS_Connect + * Connect to a TCP/UDP socket + */ +int OS_ConnectTCP(char *_port, const char *_ip); +int OS_ConnectUDP(char *_port, const char *_ip); + +/* OS_RecvUDP + * Receive a UDP packet. Return NULL if failed + */ +char *OS_RecvUDP(int socket, int sizet); +int OS_RecvConnUDP(int socket, char *buffer, int buffer_size) __attribute__((nonnull)); + +/* OS_RecvUnix + * Receive a message via a Unix socket + */ +int OS_RecvUnix(int socket, int sizet, char *ret) __attribute__((nonnull)); + +/* OS_RecvTCP + * Receive a TCP packet + */ +int OS_AcceptTCP(int socket, char *srcip, size_t addrsize) __attribute__((nonnull)); +char *OS_RecvTCP(int socket, int sizet); +int OS_RecvTCPBuffer(int socket, char *buffer, int sizet) __attribute__((nonnull)); + +/* OS_SendTCP + * Send a TCP/UDP/UnixSocket packet (in a open socket) + */ +int OS_SendTCP(int socket, const char *msg) __attribute__((nonnull)); +int OS_SendTCPbySize(int socket, int size, const char *msg) __attribute__((nonnull)); + +int OS_SendUnix(int socket, const char *msg, int size) __attribute__((nonnull)); + +int OS_SendUDPbySize(int socket, int size, const char *msg) __attribute__((nonnull)); + +/* OS_GetHost + * Calls getaddrinfo + */ +char *OS_GetHost(const char *host, unsigned int attempts); + + +/* satop + * Convert a sockaddr to a printable address. + */ +int satop(struct sockaddr *sa, char *dst, socklen_t size); + + +/* Close a network socket + * Returns 0 on success, else -1 or SOCKET_ERROR + */ +int OS_CloseSocket(int socket); + +/* Set a socket to be non-blocking */ +int setnonblock(int fd); + +#endif /* __OS_NET_H */ + diff --git a/src/os_regex/COPYRIGHT b/src/os_regex/COPYRIGHT new file mode 100644 index 000000000..37cbf39b8 --- /dev/null +++ b/src/os_regex/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (C) 2009 Trend Micro Inc. + All right reserved. + This program is a free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License (version 2) as published by the FSF - Free Software + Foundation + +openarmor, os_regex library. +Available at http://www.theopenarmor.org/ diff --git a/src/os_regex/README b/src/os_regex/README new file mode 100644 index 000000000..1f5cd8c89 --- /dev/null +++ b/src/os_regex/README @@ -0,0 +1,27 @@ += openarmor, os_regex Library. = + +Fast and simple library for regular expressions in C. + +This library is designed to be simple, but support +the most common regular expressions. It was design +with intrusion detection systems in mind, where having +all options is not crucial, but speed is. + +The following expressions are supported: + \w -> A-Z, a-z, 0-9 characters + \d -> 0-9 characters + \s -> For spaces " " + \p -> ()*+,-.:;<=>?[]!"'#$%&|{} (punctuation characters) + \W -> For anything not \w + \D -> For anything not \d + \S -> For anything not \s + \. -> For anything + +Each regular expression can be followed by: + + + -> To match one or more times (eg \w+ or \d+) + * -> To match zero or more times (eg \w* or \p*) + +We also support the "^" to match at the beginning of the text, +'$" to match at the end of the text and "|" to have multiple +expressions. diff --git a/src/os_regex/VERSION b/src/os_regex/VERSION new file mode 100644 index 000000000..be5863417 --- /dev/null +++ b/src/os_regex/VERSION @@ -0,0 +1 @@ +0.3 diff --git a/src/os_regex/examples/Makefile b/src/os_regex/examples/Makefile new file mode 100644 index 000000000..00a7cc376 --- /dev/null +++ b/src/os_regex/examples/Makefile @@ -0,0 +1,9 @@ +# Makefile for os_regex tests + +maketest: + $(CC) -o regex regex.c ../os_regex.a -I../ -Wall + $(CC) -o match match.c ../os_regex.a -I../ -Wall + $(CC) -o regex_str regex_str.c ../os_regex.a -I../ -Wall + +clean: + rm -f regex match regex_str *.core diff --git a/src/os_regex/examples/match.c b/src/os_regex/examples/match.c new file mode 100644 index 000000000..69afa9e5a --- /dev/null +++ b/src/os_regex/examples/match.c @@ -0,0 +1,29 @@ +/* Copyright by Daniel B. Cid (2005) + * Under the public domain. It is just an example. + * Some examples of the usage for the os_regex library. + */ + +#include +#include +#include + +#include "os_regex.h" + + +int main(int argc, char **argv) +{ + if (argc != 3) { + printf("%s regex word\n", argv[0]); + exit(1); + } + + printf("for MATCH: "); + if (OS_Match2(argv[1], argv[2])) { + printf("TRUE\n"); + } else { + printf("FALSE\n"); + } + + return (0); +} + diff --git a/src/os_regex/examples/regex.c b/src/os_regex/examples/regex.c new file mode 100644 index 000000000..e399a8329 --- /dev/null +++ b/src/os_regex/examples/regex.c @@ -0,0 +1,29 @@ +/* Copyright by Daniel B. Cid (2005) + * Under the public domain. It is just an example. + * Some examples of the usage for the os_regex library. + */ + +#include +#include +#include + +#include "os_regex.h" + + +int main(int argc, char **argv) +{ + if (argc != 3) { + printf("%s regex word\n", argv[0]); + exit(1); + } + + printf("for REGEX: "); + if (OS_Regex(argv[1], argv[2])) { + printf("TRUE\n"); + } else { + printf("FALSE\n"); + } + + return (0); +} + diff --git a/src/os_regex/examples/regex_str.c b/src/os_regex/examples/regex_str.c new file mode 100644 index 000000000..8def8acfe --- /dev/null +++ b/src/os_regex/examples/regex_str.c @@ -0,0 +1,68 @@ +/* Copyright by Daniel B. Cid (2005, 2006) + * Under the public domain. It is just an example. + * Some examples of usage for the os_regex library. + */ + +#include +#include +#include + +#include "os_regex.h" + + +int main(int argc, char **argv) +{ + int r_code = 0; + + /* OSRegex structure */ + OSRegex reg; + + /* Check for arguments */ + if (argc != 3) { + printf("%s regex string\n", argv[0]); + exit(1); + } + + /* If the compilation failed, we don't need to free anything. + * We are passing the OS_RETURN_SUBSTRING because we want the + * substrings back. + */ + if (OSRegex_Compile(argv[1], ®, OS_RETURN_SUBSTRING)) { + const char *retv; + /* If the execution succeeds, the substrings will be + * at reg.sub_strings + */ + if ((retv = OSRegex_Execute(argv[2], ®))) { + int sub_size = 0; + char **ret; + r_code = 1; + + /* Next pt */ + printf("next pt: '%s'\n", retv); + /* Assign reg.sub_strings to ret */ + ret = reg.sub_strings; + + printf("substrings:\n"); + while (*ret) { + printf(" %d: !%s!\n", sub_size, *ret); + sub_size++; + ret++; + } + + /* We must free the substrings */ + OSRegex_FreeSubStrings(®); + } else { + printf("Error: Didn't match.\n"); + } + + OSRegex_FreePattern(®); + } + + /* Compilation error */ + else { + printf("Error: Regex Compile Error: %d\n", reg.error); + } + + return (r_code); +} + diff --git a/src/os_regex/examples/run.sh b/src/os_regex/examples/run.sh new file mode 100644 index 000000000..aae2e3ff1 --- /dev/null +++ b/src/os_regex/examples/run.sh @@ -0,0 +1,10 @@ +make +perl ./validate.pl "./match" tests/true.tests FALSE +perl ./validate.pl "./match" tests/false.tests TRUE +perl ./validate.pl "./newmatch" tests/true.tests FALSE +perl ./validate.pl "./newmatch" tests/false.tests TRUE +perl ./validate.pl "./regex" tests/true.tests FALSE +perl ./validate.pl "./regex" tests/false.tests TRUE +perl ./validate.pl "./regex" tests/true.regex FALSE +perl ./validate.pl "./regex" tests/false.regex TRUE +perl ./validate.pl "./regex_str" tests/str.regex FALSE diff --git a/src/os_regex/examples/tests/false.regex b/src/os_regex/examples/tests/false.regex new file mode 100644 index 000000000..a96363261 --- /dev/null +++ b/src/os_regex/examples/tests/false.regex @@ -0,0 +1,8 @@ +"\w+\s+\w+\d+\s\$" "a aa11 " +"^\s+\s l" " lala" +"test123test\d+" "test123test" +"test123test\d+\$" "test123test" +"(lalala" "lalala" +"test123(\d)" "test123a" +"\(test)" "test" +"(\w+)(\d+)" "1 1" diff --git a/src/os_regex/examples/tests/false.tests b/src/os_regex/examples/tests/false.tests new file mode 100644 index 000000000..0d9d64c65 --- /dev/null +++ b/src/os_regex/examples/tests/false.tests @@ -0,0 +1,13 @@ +"abc" "abb" +"^ab" " ab" +"test" "tes" +"abcd" "abc" +"abbb" "abb" +"abbbbbbbb" "abbbbbbb" +"a|b|c| " "def" +"lala$" "lalalalalal" +"^ab$" "abc" +"zzzz$" "zzzzzzzzzzzz " +"^bin$|^shell$" "bina" +"^bin$|^shell$" "shella" +"^bin$|^shell$" "ashell" diff --git a/src/os_regex/examples/tests/str.regex b/src/os_regex/examples/tests/str.regex new file mode 100644 index 000000000..40157a939 --- /dev/null +++ b/src/os_regex/examples/tests/str.regex @@ -0,0 +1,6 @@ +"123(\w+\s+)abc" "123sdf abc" +"123(\w+\s+)abc" "abc123sdf abc" +"123 (\d+.\d.\d.\d\d*\d*)" "123 45.6.5.567" +"from (\S*\d+.\d+.\d+.\d\d*\d*)" "sshd[21576]: Illegal user web14 from ::ffff:212.227.60.55" +"^sshd[\d+]: Accepted \S+ for (\S+) from (\S+) port " "sshd[21405]: Accepted password for root from 192.1.1.1 port 6023" +": \((\S+)@(\S+)\) [" "pure-ftpd: (?@enigma.lab.theopenarmor.org) [INFO] New connection from enigma.lab.theopenarmor.org" diff --git a/src/os_regex/examples/tests/true.regex b/src/os_regex/examples/tests/true.regex new file mode 100644 index 000000000..49815826f --- /dev/null +++ b/src/os_regex/examples/tests/true.regex @@ -0,0 +1,27 @@ +"\s+123" " 123" +"\s*123" "123" +"\s123" " 123" +"\w+\s+\w+" "a 1" +"\w+\d+\w+\s+" "ab12fb12fd12 " +"^\s*\w\s*\w+" "a l a a" +"\w+\s+\w+\d+\s\$" "a aa11 " +"^su\S*: BAD su" "su: BAD SU dcid to root on /dev/ttyp0" +"^su\s*: BAD su" "su: BAD SU dcid to root on /dev/ttyp0" +"^abc\sabc" "abc abcd" +"^abc\s\s*abc" "abc abcd" +"^\s+\sl" " lala" +"^\s*\sl" " lala" +"^\s\s+l" " lala" +"^\s+\s l" " lala" +"^\s*\s lal\w\$" " lala" +"test123test\d+\$" "test123test123" +"^kernel: \S+ \.+ SRC=\S+ DST=\S+ \.+ PROTO=\w+ SPT=\d+ DPT=\d+ " "kernel: IPTABLE IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:03:93:db:2e:b4:08:00 SRC=10.4.11.40 DST=255.255.255.255 LEN=180 TOS=0x00 PREC=0x00 TTL=64 ID=4753 PROTO=UDP SPT=49320 DPT=2222 LEN=160" +"test (\w+)la" "test abclala" +"(\w+) (\w+)" "wofl wofl" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:469:3] ICMP PING NMAP [Classification: Attempted Information Leak] [Priority: 2]: {ICMP} 10.4.12.26 -> 10.4.10.231" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:408:5] ICMP Echo Reply [Classification: Misc Activity] [Priority: 3]: {ICMP} 10.4.10.231 -> 10.4.12.26" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:162" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37021 -> 10.4.10.231:162" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:669 -> 10.4.3.20:111" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:670 -> 10.4.3.20:111" +"^\S+ [(\d+:\d+:\d+)] \.+ (\d+.\d+.\d+.\d+)\p*\d* -> (\d+.\d+.\d+.\d+)\p*" "snort: [1:1421:11] SNMP AgentX/tcp request [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:705" diff --git a/src/os_regex/examples/tests/true.tests b/src/os_regex/examples/tests/true.tests new file mode 100644 index 000000000..0bb68d33f --- /dev/null +++ b/src/os_regex/examples/tests/true.tests @@ -0,0 +1,28 @@ +"abc" "abcd" +"abcd" "abcd" +"a" "a" +"a" "aa" +"^a" "ab" +"test" "testa" +"test" "testest" +"lalaila" "lalalalaila" +"abc|cde" "cde" +"^aa|ee|ii|oo|uu" "dfgdsii" +"Abc" "abc" +"ZBE" "zbe" +"ABC" "ABc" +"^A" "a" +"a|E" "abcdef" +"daniel" "daniel" +"DANIeL" "daNIel" +"^abc " "abc " +"ddd|eee|fff|ggg|ggg|hhh|iii" "iii" +"kwo|fe|fw|wfW|edW|dwDF|WdW|dw|d|^la" "la" +"^a" "a" +"^ab$" "ab" +"c$" "c" +"c$" "lalalalac" +"^bin$|^shell$" "bin" +"^bin$|^shell$" "shell" +"^bin$|^shell$|^ftp$" "shell" +"^bin$|^shell$|^ftp$" "ftp" diff --git a/src/os_regex/examples/validate.pl b/src/os_regex/examples/validate.pl new file mode 100644 index 000000000..4bd67916d --- /dev/null +++ b/src/os_regex/examples/validate.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +if (@ARGV < 2) { + die "$0 file error_msg\n"; +} + +my ($prog, $file,$msg) = (@ARGV); + +open(FILE,$file) || die "Error opening file: $file\n"; + +if (! -f $prog) { + die "File $prog not present\n"; +} + +while() { + my $line = $_; + print "running: $prog $line\n"; + my $result = `$prog $line`; + if ($result =~ /$msg/) { + print $result; + print "\t ** $line **\n"; + ; + } else { + print $result; + } +} + diff --git a/src/os_regex/os_converter.c b/src/os_regex/os_converter.c new file mode 100644 index 000000000..4fe9c610f --- /dev/null +++ b/src/os_regex/os_converter.c @@ -0,0 +1,273 @@ +#include +#include +#include +#include + +#include "debug_op.h" +#include "os_regex.h" + +#define OSREGEX_TO_PCRE2_FIX \ + ("(??\\[\\]!\"'#%&$|{}-]"), + REPLACEMENT_ENTRY("\\s", "[ ]"), + REPLACEMENT_ENTRY("\\W", "[^A-Za-z0-9@_-]"), + REPLACEMENT_ENTRY("\\w", "[A-Za-z0-9@_-]"), + REPLACEMENT_ENTRY("\\d", "[0-9]"), + REPLACEMENT_ENTRY("\\D", "[^0-9]"), + REPLACEMENT_ENTRY("\\S", "[^ ]"), + REPLACEMENT_ENTRY("\\.", "(?s:.)"), + REPLACEMENT_ENTRY("$", "(?!\\n)$"), + REPLACEMENT_ENTRY(".", "\\."), + REPLACEMENT_ENTRY("[", "\\["), + REPLACEMENT_ENTRY("]", "\\]"), + REPLACEMENT_ENTRY("{", "\\{"), + REPLACEMENT_ENTRY("}", "\\}"), + REPLACEMENT_ENTRY("+", "\\+"), + REPLACEMENT_ENTRY("?", "\\?"), + REPLACEMENT_ENTRY("*", "\\*")}; + +/* replacement map for match expressions */ +const replacement_pattern _replacement_map_match[] = { + REPLACEMENT_ENTRY(".", "\\."), REPLACEMENT_ENTRY("[", "\\["), REPLACEMENT_ENTRY("]", "\\]"), + REPLACEMENT_ENTRY("{", "\\{"), REPLACEMENT_ENTRY("}", "\\}"), REPLACEMENT_ENTRY("+", "\\+"), + REPLACEMENT_ENTRY("?", "\\?"), REPLACEMENT_ENTRY("*", "\\*"), REPLACEMENT_ENTRY("(", "\\("), + REPLACEMENT_ENTRY(")", "\\)"), REPLACEMENT_ENTRY("\\", "\\\\")}; + +int OSRegex_ConvertRegex(const char *pattern, char **converted_pattern_ptr); +int OSRegex_ConvertMatch(const char *pattern, char **converted_pattern_ptr); + +int OSRegex_Convert(const char *pattern, char **converted_pattern_ptr, uint32_t map) +{ + *converted_pattern_ptr = NULL; + switch (map) { + case OS_CONVERT_REGEX: + return OSRegex_ConvertRegex(pattern, converted_pattern_ptr); + case OS_CONVERT_MATCH: + return OSRegex_ConvertMatch(pattern, converted_pattern_ptr); + break; + default: + return (0); + } +} + +int OSRegex_ConvertRegex(const char *pattern, char **converted_pattern_ptr) +{ + char *converted_pattern = NULL; + size_t converted_pattern_size = 0UL; + size_t converted_pattern_offset = 0UL; + size_t pattern_offset = 0UL; + size_t pattern_size = strlen(pattern); + const char *replacement = NULL; + size_t replacement_size = 0UL; + const size_t map_size = ARRAY_LENGTH(_replacement_map_regex); + const replacement_pattern *map = _replacement_map_regex; + size_t i; + const char *p = NULL; + const char *star_ungreedy = "*?"; + const char *plus_ungreedy = "+?"; + pcre2_code *preg = NULL; + int error = 0; + PCRE2_SIZE erroroffset = 0; + PCRE2_UCHAR *final_converted_pattern = NULL; + PCRE2_SIZE final_converted_pattern_len = 0; + + for (pattern_offset = 0UL; pattern_offset < pattern_size; pattern_offset++) { + p = &pattern[pattern_offset]; + replacement = NULL; + replacement_size = 0UL; + + if (pattern_offset >= 2 && pattern[pattern_offset - 2] == '\\') { + switch (p[0]) { + case '*': + replacement = star_ungreedy; + replacement_size = 2UL; + break; + case '+': + replacement = plus_ungreedy; + replacement_size = 2UL; + break; + default: + break; + } + } + + if (!replacement) { + for (i = 0; i < map_size; i++) { + if (map[i].old_sz + pattern_offset <= pattern_size && + strncmp(map[i].old, p, map[i].old_sz) == 0) { + replacement = map[i].new; + replacement_size = map[i].new_sz; + pattern_offset += map[i].old_sz - 1; + break; + } + } + } + + if (!replacement) { + /* If it is a special class for openarmor */ + if (p[0] == '\\' && pattern_offset + 1 < pattern_size) { + switch (p[1]) { + case 't': + case '$': + case '(': + case ')': + case '{': + case '}': + case '[': + case ']': + case '\\': + case '|': + case '<': + /* case '>': Only the '<' can be escaped, possibly to not interfer + * with XML parsing if nothing to backslash we copy the two current + * input pattern characters and move the cursor to the next next char + */ + replacement = p; + pattern_offset++; + replacement_size = 2UL; + break; + default: + goto conversion_error; + } + } else { + replacement = p; + replacement_size = 1UL; + } + } + + if (converted_pattern_offset + replacement_size >= converted_pattern_size) { + converted_pattern_size += OS_PATTERN_MAXSIZE; + char *tmp_converted_pattern = NULL; + tmp_converted_pattern = (char *)realloc(converted_pattern, converted_pattern_size); + if (tmp_converted_pattern == NULL) { + free(converted_pattern); + return(0); + } else { + converted_pattern = tmp_converted_pattern; + } + /* + if (!converted_pattern) { + return (0); + } + */ + } + + converted_pattern_offset += sprintf(&converted_pattern[converted_pattern_offset], "%.*s", + (int)replacement_size, replacement); + } + + /* + * We should remove the '?' for non-greediness when it is the last one => m/([+*])\?(\)*[|]?)$/ + * Because openarmor is only greedy with the last occurencies modifier + */ + preg = pcre2_compile((PCRE2_SPTR)OSREGEX_TO_PCRE2_FIX, PCRE2_ZERO_TERMINATED, PCRE2_EXTENDED, + &error, &erroroffset, NULL); + if (preg == NULL) { + goto conversion_error; + } + final_converted_pattern_len = converted_pattern_size; + final_converted_pattern = malloc(final_converted_pattern_len); + if (pcre2_substitute(preg, (PCRE2_SPTR)converted_pattern, converted_pattern_offset, 0, + PCRE2_SUBSTITUTE_GLOBAL, NULL, NULL, (PCRE2_SPTR) "$1$2", 4, + final_converted_pattern, &final_converted_pattern_len) > 0) { + free(converted_pattern); + *converted_pattern_ptr = (char *)final_converted_pattern; + } else { + free(final_converted_pattern); + *converted_pattern_ptr = converted_pattern; + } + pcre2_code_free(preg); + + return (1); + +conversion_error: + if (converted_pattern) { + free(converted_pattern); + } + + if (preg) { + pcre2_code_free(preg); + } + + return (0); +} + +int OSRegex_ConvertMatch(const char *pattern, char **converted_pattern_ptr) +{ + char *converted_pattern = NULL; + size_t converted_pattern_size = 0UL; + size_t converted_pattern_offset = 0UL; + size_t pattern_offset = 0UL; + size_t pattern_size = strlen(pattern); + const char *replacement = NULL; + size_t replacement_size = 0UL; + const size_t map_size = ARRAY_LENGTH(_replacement_map_match); + const replacement_pattern *map = _replacement_map_match; + size_t i; + const char *p = NULL; + + for (pattern_offset = 0UL; pattern_offset < pattern_size; pattern_offset++) { + p = &pattern[pattern_offset]; + replacement = NULL; + replacement_size = 0UL; + for (i = 0; i < map_size; i++) { + if (map[i].old_sz + pattern_offset <= pattern_size && + strncmp(map[i].old, p, map[i].old_sz) == 0) { + replacement = map[i].new; + replacement_size = map[i].new_sz; + pattern_offset += map[i].old_sz - 1; + break; + } + } + if (!replacement) { + replacement = p; + replacement_size = 1UL; + } + + if (converted_pattern_offset + replacement_size >= converted_pattern_size) { + converted_pattern_size += OS_PATTERN_MAXSIZE; + char *tmp_converted_pattern = NULL; + tmp_converted_pattern = (char *)realloc(converted_pattern, converted_pattern_size); + if (tmp_converted_pattern == NULL) { + free(converted_pattern); + return(0); + } else { + converted_pattern = tmp_converted_pattern; + } + if (!converted_pattern) { + return (0); + } + } + + converted_pattern_offset += sprintf(&converted_pattern[converted_pattern_offset], "%.*s", + (int)replacement_size, replacement); + } + + *converted_pattern_ptr = converted_pattern; + + return (1); +} diff --git a/src/os_regex/os_match.c b/src/os_regex/os_match.c new file mode 100644 index 000000000..35ca37030 --- /dev/null +++ b/src/os_regex/os_match.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + + +/* This function is a wrapper around the compile/execute + * functions. It should only be used when the pattern is + * only going to be used once. + * Returns 1 on success or 0 on failure. + */ +int OS_Match2(const char *pattern, const char *str) +{ + int r_code = 0; + OSMatch reg; + + /* If the compilation failed, we don't need to free anything */ + if (OSMatch_Compile(pattern, ®, 0)) { + if (OSMatch_Execute(str, strlen(str), ®)) { + r_code = 1; + } + + OSMatch_FreePattern(®); + } + + return (r_code); +} + diff --git a/src/os_regex/os_match_compile.c b/src/os_regex/os_match_compile.c new file mode 100644 index 000000000..4a1755d1b --- /dev/null +++ b/src/os_regex/os_match_compile.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +int OSMatch_Execute_pcre2_match(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_true(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_strncmp(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_strrcmp(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_strcmp(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_strncasecmp(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_strrcasecmp(const char *subject, size_t len, OSMatch *match); +int OSMatch_Execute_strcasecmp(const char *subject, size_t len, OSMatch *match); +int OSMatch_CouldBeOptimized(const char *pattern2check); + +/* Compile a pattern to be used later + * Allowed flags are: + * - OS_CASE_SENSITIVE + * Returns 1 on success or 0 on error + * The error code is set on reg->error + */ +int OSMatch_Compile(const char *pattern, OSMatch *reg, int flags) +{ + char *pattern_pcre2 = NULL; + int flags_compile = 0; + int error = 0; + PCRE2_SIZE erroroffset = 0; + size_t pattern_len = 0UL; + char first_char, last_char; + + /* Check for references not initialized */ + if (reg == NULL) { + return (0); + } + + /* Initialize OSMatch structure */ + reg->error = 0; + reg->regex = NULL; + reg->match_data = NULL; + reg->pattern_len = 0UL; + reg->pattern = NULL; + reg->exec_function = NULL; + + /* The pattern can't be null */ + if (pattern == NULL) { + reg->error = OS_REGEX_PATTERN_NULL; + goto compile_error; + } + + /* Maximum size of the pattern */ + pattern_len = strlen(pattern); + if (pattern_len > OS_PATTERN_MAXSIZE) { + reg->error = OS_REGEX_MAXSIZE; + goto compile_error; + } + + if (pattern_len == 0) { + reg->exec_function = OSMatch_Execute_true; + return (1); + } else if (OSMatch_CouldBeOptimized(pattern)) { + first_char = pattern[0]; + last_char = pattern[pattern_len - 1]; + + if (first_char == '^') { + if (last_char == '$') { + reg->pattern = strdup(&pattern[1]); + reg->pattern_len = pattern_len - 2; + reg->pattern[reg->pattern_len] = '\0'; + if (flags & OS_CASE_SENSITIVE) { + reg->exec_function = OSMatch_Execute_strcmp; + } else { + reg->exec_function = OSMatch_Execute_strcasecmp; + } + return (1); + } else { + reg->pattern = strdup(&pattern[1]); + reg->pattern_len = pattern_len - 1; + if (flags & OS_CASE_SENSITIVE) { + reg->exec_function = OSMatch_Execute_strncmp; + } else { + reg->exec_function = OSMatch_Execute_strncasecmp; + } + return (1); + } + } else { + if (last_char == '$') { + reg->pattern = strdup(pattern); + reg->pattern_len = pattern_len - 1; + reg->pattern[reg->pattern_len] = '\0'; + if (flags & OS_CASE_SENSITIVE) { + reg->exec_function = OSMatch_Execute_strrcmp; + } else { + reg->exec_function = OSMatch_Execute_strrcasecmp; + } + return (1); + } + } + } + + reg->exec_function = OSMatch_Execute_pcre2_match; + + /* openarmor pattern conversion */ + if (OSRegex_Convert(pattern, &pattern_pcre2, OS_CONVERT_MATCH) == 0) { + reg->error = OS_REGEX_BADREGEX; + goto compile_error; + } + + flags_compile |= PCRE2_UTF; + flags_compile |= PCRE2_NO_UTF_CHECK; + flags_compile |= (flags & OS_CASE_SENSITIVE) ? 0 : PCRE2_CASELESS; + reg->regex = pcre2_compile((PCRE2_SPTR)pattern_pcre2, PCRE2_ZERO_TERMINATED, flags_compile, + &error, &erroroffset, NULL); + if (reg->regex == NULL) { + reg->error = OS_REGEX_BADREGEX; + goto compile_error; + } + + reg->match_data = pcre2_match_data_create_from_pattern(reg->regex, NULL); + if (reg->match_data == NULL) { + reg->error = OS_REGEX_OUTOFMEMORY; + goto compile_error; + } + +#ifdef USE_PCRE2_JIT + /* Just In Time compilation for faster execution */ + if (pcre2_jit_compile(reg->regex, PCRE2_JIT_COMPLETE) != 0) { + reg->error = OS_REGEX_NO_JIT; + goto compile_error; + } +#endif + + free(pattern_pcre2); + + return (1); + +compile_error: + /* Error handling */ + + if (pattern_pcre2) { + free(pattern_pcre2); + } + + OSMatch_FreePattern(reg); + + return (0); +} + +int OSMatch_CouldBeOptimized(const char *pattern2check) +{ + return OS_Pcre2("^\\^?[^$|^]+\\$?$", pattern2check); +} + diff --git a/src/os_regex/os_match_execute.c b/src/os_regex/os_match_execute.c new file mode 100644 index 000000000..77b5ed6a4 --- /dev/null +++ b/src/os_regex/os_match_execute.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +/* Compare an already compiled pattern with a not NULL string. + * Returns 1 on success or 0 on error. + * The error code is set on reg->error. + */ +int OSMatch_Execute(const char *str, size_t str_len, OSMatch *reg) +{ + return reg->exec_function(str, str_len, reg); +} + +int OSMatch_Execute_true(const char *subject, size_t len, OSMatch *match) +{ + (void)subject; + (void)len; + (void)match; + return (1); +} + +int OSMatch_Execute_pcre2_match(const char *str, size_t str_len, OSMatch * reg) +{ + int rc = 0; + +#ifdef USE_PCRE2_JIT + rc = pcre2_jit_match(reg->regex, (PCRE2_SPTR)str, str_len, 0, 0, reg->match_data, NULL); +#else + rc = pcre2_match(reg->regex, (PCRE2_SPTR)str, str_len, 0, 0, reg->match_data, NULL); +#endif + + return (rc >= 0); +} + +int OSMatch_Execute_strcmp(const char *subject, size_t len, OSMatch *match) +{ + //^literal$ + (void)len; + return !strcmp(match->pattern, subject); +} + +int OSMatch_Execute_strncmp(const char *subject, size_t len, OSMatch *match) +{ + //^literal + (void)len; + return !strncmp(match->pattern, subject, match->pattern_len); +} + +int OSMatch_Execute_strrcmp(const char *subject, size_t len, OSMatch *match) +{ + // literal$ + if (len >= match->pattern_len) { + return !strcmp(match->pattern, &subject[len - match->pattern_len]); + } + return (0); +} + +int OSMatch_Execute_strcasecmp(const char *subject, size_t len, OSMatch *match) +{ + return (len == match->pattern_len && !strcasecmp(match->pattern, subject)); +} + +int OSMatch_Execute_strncasecmp(const char *subject, size_t len, OSMatch *match) +{ + (void)len; + return !strncasecmp(match->pattern, subject, match->pattern_len); +} + +int OSMatch_Execute_strrcasecmp(const char *subject, size_t len, OSMatch *match) { + if (len >= match->pattern_len) { + return !strcasecmp(match->pattern, &subject[len - match->pattern_len]); + } + return (0); +} + diff --git a/src/os_regex/os_match_free_pattern.c b/src/os_regex/os_match_free_pattern.c new file mode 100644 index 000000000..2a2ceadc8 --- /dev/null +++ b/src/os_regex/os_match_free_pattern.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" +#include "os_regex_internal.h" + + +/* Release all the memory created by the compilation/execution phases */ +void OSMatch_FreePattern(OSMatch *reg) +{ + /* Free the match data */ + if (reg->match_data) { + pcre2_match_data_free(reg->match_data); + reg->match_data = NULL; + } + + /* Free the regex */ + if (reg->regex) { + pcre2_code_free(reg->regex); + reg->regex = NULL; + } + + /* Free the patter, */ + if (reg->pattern) { + free(reg->pattern); + reg->pattern = NULL; + } + + return; +} + diff --git a/src/os_regex/os_pcre2.c b/src/os_regex/os_pcre2.c new file mode 100644 index 000000000..7ea665df1 --- /dev/null +++ b/src/os_regex/os_pcre2.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +int OS_Pcre2(const char *pattern, const char *str) +{ + int r_code = 0; + OSPcre2 reg; + + if (OSPcre2_Compile(pattern, ®, PCRE2_UTF | PCRE2_NO_UTF_CHECK | PCRE2_CASELESS)) { + if(OSPcre2_Execute(str, ®)) { + r_code = 1; + } + + OSPcre2_FreePattern(®); + } + + return (r_code); +} + diff --git a/src/os_regex/os_pcre2_compile.c b/src/os_regex/os_pcre2_compile.c new file mode 100644 index 000000000..496c352fb --- /dev/null +++ b/src/os_regex/os_pcre2_compile.c @@ -0,0 +1,173 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include + +#include "os_regex.h" + +const char *OSPcre2_Execute_pcre2_match(const char *str, OSPcre2 *reg); +const char *OSPcre2_Execute_strncmp(const char *subject, OSPcre2 *reg); +const char *OSPcre2_Execute_strrcmp(const char *subject, OSPcre2 *reg); +const char *OSPcre2_Execute_strcasecmp(const char *subject, OSPcre2 *reg); +const char *OSPcre2_Execute_strncasecmp(const char *subject, OSPcre2 *reg); +const char *OSPcre2_Execute_strrcasecmp(const char *subject, OSPcre2 *reg); +const char *OSPcre2_Execute_strcmp(const char *subject, OSPcre2 *reg); +int OSPcre2_CouldBeOptimized(const char *pattern); + +int OSPcre2_Compile(const char *pattern, OSPcre2 *reg, int flags) +{ + int error = 0; + PCRE2_SIZE erroroffset; + size_t pattern_len = 0UL; + char first_char, last_char; + uint32_t count, i; + + /* Check for references not initialized */ + if (reg == NULL) { + return (0); + } + + /* Initialize OSRegex structure */ + reg->error = 0; + reg->sub_strings = NULL; + reg->regex = NULL; + reg->match_data = NULL; + reg->pattern_len = 0UL; + reg->pattern = NULL; + reg->exec_function = NULL; + + /* The pattern can't be null */ + if (pattern == NULL) { + reg->error = OS_REGEX_PATTERN_NULL; + goto compile_error; + } + + /* Maximum size of the pattern */ + pattern_len = strlen(pattern); +#if 0 + if (pattern_len > OS_PATTERN_MAXSIZE) { + reg->error = OS_REGEX_MAXSIZE; + goto compile_error; + } +#endif + + /* The pattern can't be empty */ + if (pattern_len == 0) { + reg->error = OS_REGEX_PATTERN_EMPTY; + goto compile_error; + } + + if (OSPcre2_CouldBeOptimized(pattern)) { + first_char = pattern[0]; + last_char = pattern[pattern_len - 1]; + + if (first_char == '^') { + if (last_char == '$') { + reg->pattern = strdup(&pattern[1]); + reg->pattern_len = pattern_len - 2; + reg->pattern[reg->pattern_len] = '\0'; + if (flags & PCRE2_CASELESS) { + reg->exec_function = OSPcre2_Execute_strcasecmp; + } else { + reg->exec_function = OSPcre2_Execute_strcmp; + } + return (1); + } else { + reg->pattern = strdup(&pattern[1]); + reg->pattern_len = pattern_len - 1; + if (flags & PCRE2_CASELESS) { + reg->exec_function = OSPcre2_Execute_strncasecmp; + } else { + reg->exec_function = OSPcre2_Execute_strncmp; + } + return (1); + } + } else { + if (last_char == '$') { + reg->pattern = strdup(pattern); + reg->pattern_len = pattern_len - 1; + reg->pattern[reg->pattern_len] = '\0'; + if (flags & PCRE2_CASELESS) { + reg->exec_function = OSPcre2_Execute_strrcasecmp; + } else { + reg->exec_function = OSPcre2_Execute_strrcmp; + } + return (1); + } + } + } + + reg->exec_function = OSPcre2_Execute_pcre2_match; + + reg->regex = pcre2_compile((PCRE2_SPTR)pattern, pattern_len, flags, &error, &erroroffset, NULL); + if (reg->regex == NULL) { + reg->error = OS_REGEX_BADREGEX; + goto compile_error; + } + + reg->match_data = pcre2_match_data_create_from_pattern(reg->regex, NULL); + if (reg->match_data == NULL) { + reg->error = OS_REGEX_OUTOFMEMORY; + goto compile_error; + } + + pcre2_pattern_info(reg->regex, PCRE2_INFO_CAPTURECOUNT, (void *)&count); + count++; // to store NULL pointer at the end + reg->sub_strings = calloc(count, sizeof(char *)); + if (reg->sub_strings == NULL) { + reg->error = OS_REGEX_OUTOFMEMORY; + goto compile_error; + } + for (i = 0; i < count; i++) { + reg->sub_strings[i] = NULL; + } + +#ifdef USE_PCRE2_JIT + /* Just In Time compilation for faster execution */ + if (pcre2_jit_compile(reg->regex, PCRE2_JIT_COMPLETE) != 0) { + reg->error = OS_REGEX_NO_JIT; + goto compile_error; + } +#endif + + return (1); + +compile_error: + /* Error handling */ + + OSPcre2_FreePattern(reg); + + return (0); +} + +int OSPcre2_CouldBeOptimized(const char *pattern) +{ + pcre2_code *preg = NULL; + pcre2_match_data *md = NULL; + PCRE2_SPTR re = (PCRE2_SPTR) "^\\^?[a-zA-Z0-9 !\"#%&',/:;<=>@_`~-]*\\$?$"; + int error = 0; + PCRE2_SIZE erroroffset = 0; + int should_be_optimized = 0; + + preg = pcre2_compile(re, PCRE2_ZERO_TERMINATED, PCRE2_UTF | PCRE2_NO_UTF_CHECK, &error, + &erroroffset, NULL); + md = pcre2_match_data_create_from_pattern(preg, NULL); + + if (pcre2_match(preg, (PCRE2_SPTR)pattern, strlen(pattern), 0, 0, md, NULL) >= 0) { + should_be_optimized = 1; + } + + pcre2_match_data_free(md); + pcre2_code_free(preg); + + return should_be_optimized; +} diff --git a/src/os_regex/os_pcre2_execute.c b/src/os_regex/os_pcre2_execute.c new file mode 100644 index 000000000..21066a2dd --- /dev/null +++ b/src/os_regex/os_pcre2_execute.c @@ -0,0 +1,112 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "defs.h" +#include "os_regex.h" +#include +#include +#include + +const char *OSPcre2_Execute(const char *str, OSPcre2 *reg) +{ + /* Check for references not initialized */ + if (str == NULL) { + reg->error = OS_REGEX_STR_NULL; + return (NULL); + } + + return reg->exec_function(str, reg); +} + +const char *OSPcre2_Execute_pcre2_match(const char *str, OSPcre2 *reg) +{ + int rc = 0, nbs = 0, i = 0; + PCRE2_SIZE *ov = NULL; + + /* Execute the reg */ +#ifdef USE_PCRE2_JIT + rc = pcre2_jit_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL); +#else + rc = pcre2_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL); +#endif + + /* Check execution result */ + if (rc <= 0) { + return NULL; + } + + /* get the offsets informations for the match */ + ov = pcre2_get_ovector_pointer(reg->match_data); + + /* get the substrings if required */ + for (i = 1; i < rc; i++) { + PCRE2_SIZE sub_string_start = ov[2 * i]; + PCRE2_SIZE sub_string_end = ov[2 * i + 1]; + PCRE2_SIZE sub_string_len = sub_string_end - sub_string_start; + if (sub_string_start != -1) { + reg->sub_strings[nbs] = (char *)calloc(sub_string_len + 1, sizeof(char)); + strncpy(reg->sub_strings[nbs], &str[sub_string_start], sub_string_len); + nbs++; + } + } + reg->sub_strings[nbs] = NULL; + + return &str[ov[1]]; +} + +const char *OSPcre2_Execute_strcmp(const char *subject, OSPcre2 *reg) +{ + if (!strcmp(reg->pattern, subject)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSPcre2_Execute_strncmp(const char *subject, OSPcre2 *reg) +{ + if (!strncmp(reg->pattern, subject, reg->pattern_len)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSPcre2_Execute_strrcmp(const char *subject, OSPcre2 *reg) +{ + size_t len = strlen(subject); + if (len >= reg->pattern_len && !strcmp(reg->pattern, &subject[len - reg->pattern_len])) { + return &subject[len]; + } + return NULL; +} + +const char *OSPcre2_Execute_strcasecmp(const char *subject, OSPcre2 *reg) +{ + if (!strcasecmp(reg->pattern, subject)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSPcre2_Execute_strncasecmp(const char *subject, OSPcre2 *reg) +{ + if (!strncasecmp(reg->pattern, subject, reg->pattern_len)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSPcre2_Execute_strrcasecmp(const char *subject, OSPcre2 *reg) +{ + size_t len = strlen(subject); + if (len >= reg->pattern_len && + !strcasecmp(reg->pattern, &subject[len - reg->pattern_len])) { + return &subject[len]; + } + return NULL; +} diff --git a/src/os_regex/os_pcre2_free_pattern.c b/src/os_regex/os_pcre2_free_pattern.c new file mode 100644 index 000000000..1cf1c79cc --- /dev/null +++ b/src/os_regex/os_pcre2_free_pattern.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +/* Release all the memory created by the compilation/execution phases */ +void OSPcre2_FreePattern(OSPcre2 *reg) +{ + /* Free the match data */ + if (reg->match_data) { + pcre2_match_data_free(reg->match_data); + reg->match_data = NULL; + } + + /* Free the regex */ + if (reg->regex) { + pcre2_code_free(reg->regex); + reg->regex = NULL; + } + + /* Free the patter, */ + if (reg->pattern) { + free(reg->pattern); + reg->pattern = NULL; + } + + /* Free the sub strings */ + if (reg->sub_strings) { + OSPcre2_FreeSubStrings(reg); + free(reg->sub_strings); + reg->sub_strings = NULL; + } + + return; +} + diff --git a/src/os_regex/os_pcre2_free_substrings.c b/src/os_regex/os_pcre2_free_substrings.c new file mode 100644 index 000000000..4e2eeacb8 --- /dev/null +++ b/src/os_regex/os_pcre2_free_substrings.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +/* Release all the memory created to store the sub strings */ +void OSPcre2_FreeSubStrings(OSPcre2 *reg) { + int i = 0; + + /* Free the sub strings */ + if (reg->sub_strings) { + while (reg->sub_strings[i]) { + free(reg->sub_strings[i]); + reg->sub_strings[i] = NULL; + i++; + } + } + return; +} + diff --git a/src/os_regex/os_regex.c b/src/os_regex/os_regex.c new file mode 100644 index 000000000..4902fe593 --- /dev/null +++ b/src/os_regex/os_regex.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + + +/* This function is a wrapper around the compile/execute + * functions. It should only be used when the pattern is + * only going to be used once. + * Returns 1 on success or 0 on failure. + */ +int OS_Regex(const char *pattern, const char *str) +{ + int r_code = 0; + OSRegex reg; + + /* If the compilation failed, we don't need to free anything */ + if (OSRegex_Compile(pattern, ®, 0)) { + if (OSRegex_Execute(str, ®)) { + r_code = 1; + } + + OSRegex_FreePattern(®); + } + + return (r_code); +} + diff --git a/src/os_regex/os_regex.h b/src/os_regex/os_regex.h new file mode 100644 index 000000000..2dd800595 --- /dev/null +++ b/src/os_regex/os_regex.h @@ -0,0 +1,192 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* See README for details */ + +#ifndef __OS_REGEX_H +#define __OS_REGEX_H + +/* size_t */ +#include + +#define PCRE2_CODE_UNIT_WIDTH 8 +#include + +/* OSRegex_Compile flags */ +#define OS_RETURN_SUBSTRING 0000200 +#define OS_CASE_SENSITIVE 0000400 + +/* Pattern maximum size */ +#define OS_PATTERN_MAXSIZE 2048 + +/* Error codes */ +#define OS_REGEX_REG_NULL 1 +#define OS_REGEX_PATTERN_NULL 2 +#define OS_REGEX_MAXSIZE 3 +#define OS_REGEX_OUTOFMEMORY 4 +#define OS_REGEX_STR_NULL 5 +#define OS_REGEX_BADREGEX 6 +#define OS_REGEX_BADPARENTHESIS 7 +#define OS_REGEX_NO_MATCH 8 +#define OS_REGEX_NO_JIT 9 +#define OS_REGEX_PATTERN_EMPTY 10 + +#define OS_CONVERT_REGEX 1 +#define OS_CONVERT_MATCH 2 + +/* OSRegex structure */ +typedef struct _OSRegex { + int error; + char **sub_strings; + pcre2_code *regex; + pcre2_match_data *match_data; + size_t pattern_len; + char *pattern; + const char *(*exec_function)(const char *, struct _OSRegex *); +} OSRegex; + +/* OSmatch structure */ +typedef struct _OSMatch { + int error; + pcre2_code *regex; + pcre2_match_data *match_data; + size_t pattern_len; + char *pattern; + int (*exec_function)(const char *, size_t, struct _OSMatch *); +} OSMatch; + +/* OSPcre2 structure */ +typedef struct _OSPcre2 { + int error; + char **sub_strings; + pcre2_code *regex; + pcre2_match_data *match_data; + size_t pattern_len; + char *pattern; + const char *(*exec_function)(const char *, struct _OSPcre2 *); +} OSPcre2; + +/*** Prototypes ***/ + +/* Convert an openarmor pattern, match or regex, + * to a PCRE2 pattern + * Allowed map are: + * - OS_CONVERT_REGEX + * - OS_CONVERT_MATCH + * Returns 1 on success or 0 on error. + */ +int OSRegex_Convert(const char *pattern, char **converted_pattern, uint32_t map); + +/* Compile a regular expression to be used later + * Allowed flags are: + * - OS_CASE_SENSITIVE + * - OS_RETURN_SUBSTRING + * Returns 1 on success or 0 on error. + * The error code is set on reg->error. + */ +int OSRegex_Compile(const char *pattern, OSRegex *reg, int flags); + +/* Compare an already compiled regular expression with + * a not NULL string. + * Returns end of str on success or NULL on error. + * The error code is set on reg->error. + */ +const char *OSRegex_Execute(const char *str, OSRegex *reg) __attribute__((nonnull(2))); + +/* Release all the memory created by the compilation/execution phases */ +void OSRegex_FreePattern(OSRegex *reg) __attribute__((nonnull)); + + +/* Release all the memory created to store the sub strings */ +void OSRegex_FreeSubStrings(OSRegex *reg) __attribute__((nonnull)); + +/* This function is a wrapper around the compile/execute + * functions. It should only be used when the pattern is + * only going to be used once. + * Returns 1 on success or 0 on failure. + */ +int OS_Regex(const char *pattern, const char *str); + +/* Compile a pattern to be used later. + * Allowed flags are: + * - OS_CASE_SENSITIVE + * Returns 1 on success or 0 on error. + * The error code is set on reg->error. + */ +int OSMatch_Compile(const char *pattern, OSMatch *reg, int flags); + +/* Compare an already compiled pattern with a not NULL string. + * Returns 1 on success or 0 on error. + * The error code is set on reg->error. + */ +int OSMatch_Execute(const char *str, size_t str_len, OSMatch *reg) __attribute__((nonnull(3))); + +/* Release all the memory created by the compilation/execution phases */ +void OSMatch_FreePattern(OSMatch *reg) __attribute__((nonnull)); + +int OS_Match2(const char *pattern, const char *str) __attribute__((nonnull(2))); + +/* Searches for pattern in the string */ +int OS_WordMatch(const char *pattern, const char *str) __attribute__((nonnull)); +#define OS_Match OS_WordMatch + +/* Compile a PCRE2 expression to be used later + * Allowed flags are the same as option in pcre2_compile + * Returns 1 on success or 0 on error. + * The error code is set on reg->error. + */ +int OSPcre2_Compile(const char *pattern, OSPcre2 *reg, int flags); + +/* Compare an already compiled PCRE2 expression with + * a not NULL string. + * Returns end of str on success or NULL on error. + * The error code is set on reg->error. + */ +const char *OSPcre2_Execute(const char *str, OSPcre2 *reg); + +/* Release all the memory created by the compilation/execution phases */ +void OSPcre2_FreePattern(OSPcre2 *reg); + +/* Release all the memory created to store the sub strings */ +void OSPcre2_FreeSubStrings(OSPcre2 *reg); + +/* This function is a wrapper around the compile/execute + * functions. It should only be used when the pattern is + * only going to be used once. + * Returns 1 on success or 0 on failure. + */ +int OS_Pcre2(const char *pattern, const char *str); + +/* Split a string into multiples pieces, divided by a char "match". + * Returns a NULL terminated array on success or NULL on error. + */ +char **OS_StrBreak(char match, const char *str, size_t size); + +/* Returns the number of characters that both strings + * have in similar (start at the beginning of them). + */ +size_t OS_StrHowClosedMatch(const char *str1, const char *str2); + +/** Inline prototypes **/ + +/* Verifies if a string starts with the provided pattern. + * Returns 1 on success or 0 on failure. + */ +int OS_StrStartsWith(const char *str, const char *pattern) __attribute__((nonnull)); + +/* Checks if a specific string is numeric (like "129544") */ +int OS_StrIsNum(const char *str); + +/* Checks if a specified char is in the following range: + * a-z, A-Z, 0-9, _-. + */ +extern const unsigned char hostname_map[256]; +#define isValidChar(x) (hostname_map[(unsigned char)x]) + +#endif /* __OS_REGEX_H */ diff --git a/src/os_regex/os_regex_compile.c b/src/os_regex/os_regex_compile.c new file mode 100644 index 000000000..2c47119b6 --- /dev/null +++ b/src/os_regex/os_regex_compile.c @@ -0,0 +1,172 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +const char *OSRegex_Execute_pcre2_match(const char *str, OSRegex *reg); +const char *OSRegex_Execute_strncmp(const char *subject, OSRegex *reg); +const char *OSRegex_Execute_strrcmp(const char *subject, OSRegex *reg); +const char *OSRegex_Execute_strcasecmp(const char *subject, OSRegex *reg); +const char *OSRegex_Execute_strncasecmp(const char *subject, OSRegex *reg); +const char *OSRegex_Execute_strrcasecmp(const char *subject, OSRegex *reg); +const char *OSRegex_Execute_strcmp(const char *subject, OSRegex *reg); +int OSRegex_CouldBeOptimized(const char *pattern2check); + +/* Compile a regular expression to be used later + * Allowed flags are: + * - OS_CASE_SENSITIVE + * - OS_RETURN_SUBSTRING + * Returns 1 on success or 0 on error + * The error code is set on reg->error + */ +int OSRegex_Compile(const char *pattern, OSRegex *reg, int flags) +{ + char *pattern_pcre2 = NULL; + int flags_compile = 0; + int error = 0; + PCRE2_SIZE erroroffset = 0; + size_t pattern_len = 0UL; + char first_char, last_char; + uint32_t count, i; + + /* Check for references not initialized */ + if (reg == NULL) { + return (0); + } + + /* Initialize OSRegex structure */ + reg->error = 0; + reg->sub_strings = NULL; + reg->regex = NULL; + reg->match_data = NULL; + reg->pattern_len = 0UL; + reg->pattern = NULL; + reg->exec_function = NULL; + + /* The pattern can't be null */ + if (pattern == NULL) { + reg->error = OS_REGEX_PATTERN_NULL; + goto compile_error; + } + + /* Maximum size of the pattern */ + pattern_len = strlen(pattern); + if (pattern_len > OS_PATTERN_MAXSIZE) { + reg->error = OS_REGEX_MAXSIZE; + goto compile_error; + } + + if (OSRegex_CouldBeOptimized(pattern)) { + first_char = pattern[0]; + last_char = pattern[pattern_len - 1]; + + if (first_char == '^') { + if (last_char == '$') { + reg->pattern = strdup(&pattern[1]); + reg->pattern_len = pattern_len - 2; + reg->pattern[reg->pattern_len] = '\0'; + if (flags & OS_CASE_SENSITIVE) { + reg->exec_function = OSRegex_Execute_strcmp; + } else { + reg->exec_function = OSRegex_Execute_strcasecmp; + } + return (1); + } else { + reg->pattern = strdup(&pattern[1]); + reg->pattern_len = pattern_len - 1; + if (flags & OS_CASE_SENSITIVE) { + reg->exec_function = OSRegex_Execute_strncmp; + } else { + reg->exec_function = OSRegex_Execute_strncasecmp; + } + return (1); + } + } else { + if (last_char == '$') { + reg->pattern = strdup(pattern); + reg->pattern_len = pattern_len - 1; + reg->pattern[reg->pattern_len] = '\0'; + if (flags & OS_CASE_SENSITIVE) { + reg->exec_function = OSRegex_Execute_strrcmp; + } else { + reg->exec_function = OSRegex_Execute_strrcasecmp; + } + return (1); + } + } + } + + reg->exec_function = OSRegex_Execute_pcre2_match; + + /* openarmor pattern conversion */ + if (OSRegex_Convert(pattern, &pattern_pcre2, OS_CONVERT_REGEX) == 0) { + reg->error = OS_REGEX_BADREGEX; + goto compile_error; + } + + flags_compile |= PCRE2_UTF; + flags_compile |= PCRE2_NO_UTF_CHECK; + flags_compile |= (flags & OS_CASE_SENSITIVE) ? 0 : PCRE2_CASELESS; + reg->regex = pcre2_compile((PCRE2_SPTR)pattern_pcre2, PCRE2_ZERO_TERMINATED, flags_compile, + &error, &erroroffset, NULL); + if (reg->regex == NULL) { + reg->error = OS_REGEX_BADREGEX; + goto compile_error; + } + + reg->match_data = pcre2_match_data_create_from_pattern(reg->regex, NULL); + if (reg->match_data == NULL) { + reg->error = OS_REGEX_OUTOFMEMORY; + goto compile_error; + } + +#ifdef USE_PCRE2_JIT + /* Just In Time compilation for faster execution */ + if (pcre2_jit_compile(reg->regex, PCRE2_JIT_COMPLETE) != 0) { + reg->error = OS_REGEX_NO_JIT; + goto compile_error; + } +#endif + + if (flags & OS_RETURN_SUBSTRING) { + pcre2_pattern_info(reg->regex, PCRE2_INFO_CAPTURECOUNT, (void *)&count); + count++; // to store NULL pointer at the end + reg->sub_strings = calloc(count, sizeof(char *)); + if (reg->sub_strings == NULL) { + reg->error = OS_REGEX_OUTOFMEMORY; + goto compile_error; + } + for (i = 0; i < count; i++) { + reg->sub_strings[i] = NULL; + } + } + + free(pattern_pcre2); + + return (1); + +compile_error: + /* Error handling */ + + if (pattern_pcre2) { + free(pattern_pcre2); + } + + OSRegex_FreePattern(reg); + + return (0); +} + +int OSRegex_CouldBeOptimized(const char *pattern2check) { + return OS_Pcre2("^\\^?[A-Za-z0-9 !\"#%&',/:;<=>@_`~-]*\\$?$", pattern2check); +} diff --git a/src/os_regex/os_regex_execute.c b/src/os_regex/os_regex_execute.c new file mode 100644 index 000000000..5dc90863a --- /dev/null +++ b/src/os_regex/os_regex_execute.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" + +/* Compare an already compiled regular expression with + * a not NULL string. + * Returns the end of the string on success or NULL on error. + * The error code is set on reg->error. + */ +const char *OSRegex_Execute(const char *str, OSRegex *reg) +{ + /* The string can't be NULL */ + if (str == NULL) { + reg->error = OS_REGEX_STR_NULL; + return (NULL); + } + return reg->exec_function(str, reg); +} + +const char *OSRegex_Execute_pcre2_match(const char *str, OSRegex *reg) +{ + int rc = 0, nbs = 0, i = 0; + PCRE2_SIZE *ov = NULL; + + /* Execute the reg */ +#ifdef USE_PCRE2_JIT + rc = pcre2_jit_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL); +#else + rc = pcre2_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL); +#endif + + /* Check execution result */ + if (rc <= 0) { + return NULL; + } + + /* get the offsets informations for the match */ + ov = pcre2_get_ovector_pointer(reg->match_data); + + if (reg->sub_strings) { + /* get the substrings if required */ + for (i = 1; i < rc; i++) { + PCRE2_SIZE sub_string_start = ov[2 * i]; + PCRE2_SIZE sub_string_end = ov[2 * i + 1]; + PCRE2_SIZE sub_string_len = sub_string_end - sub_string_start; + if (sub_string_start != -1) { + reg->sub_strings[nbs] = (char *)calloc(sub_string_len + 1, sizeof(char)); + strncpy(reg->sub_strings[nbs], &str[sub_string_start], sub_string_len); + nbs++; + } + } + reg->sub_strings[nbs] = NULL; + } + + return &str[ov[1]]; +} + +const char *OSRegex_Execute_strcmp(const char *subject, OSRegex *reg) +{ + if (!strcmp(reg->pattern, subject)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSRegex_Execute_strncmp(const char *subject, OSRegex *reg) +{ + if (!strncmp(reg->pattern, subject, reg->pattern_len)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSRegex_Execute_strrcmp(const char *subject, OSRegex *reg) +{ + size_t len = strlen(subject); + if (len >= reg->pattern_len && !strcmp(reg->pattern, &subject[len - reg->pattern_len])) { + return &subject[len]; + } + return NULL; +} + +const char *OSRegex_Execute_strcasecmp(const char *subject, OSRegex *reg) +{ + if (!strcasecmp(reg->pattern, subject)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSRegex_Execute_strncasecmp(const char *subject, OSRegex *reg) +{ + if (!strncasecmp(reg->pattern, subject, reg->pattern_len)) { + return &subject[reg->pattern_len]; + } + return NULL; +} + +const char *OSRegex_Execute_strrcasecmp(const char *subject, OSRegex *reg) +{ + size_t len = strlen(subject); + if (len >= reg->pattern_len && !strcasecmp(reg->pattern, &subject[len - reg->pattern_len])) { + return &subject[len]; + } + return NULL; +} diff --git a/src/os_regex/os_regex_free_pattern.c b/src/os_regex/os_regex_free_pattern.c new file mode 100644 index 000000000..fbc477001 --- /dev/null +++ b/src/os_regex/os_regex_free_pattern.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" +#include "os_regex_internal.h" + + +/* Release all the memory created by the compilation/execution phases */ +void OSRegex_FreePattern(OSRegex *reg) +{ + /* Free the match data */ + if (reg->match_data) { + pcre2_match_data_free(reg->match_data); + reg->match_data = NULL; + } + + /* Free the regex */ + if (reg->regex) { + pcre2_code_free(reg->regex); + reg->regex = NULL; + } + + /* Free the patter, */ + if (reg->pattern) { + free(reg->pattern); + reg->pattern = NULL; + } + + /* Free the sub strings */ + if (reg->sub_strings) { + OSRegex_FreeSubStrings(reg); + free(reg->sub_strings); + reg->sub_strings = NULL; + } + + return; +} + diff --git a/src/os_regex/os_regex_free_substrings.c b/src/os_regex/os_regex_free_substrings.c new file mode 100644 index 000000000..0c66bfcc3 --- /dev/null +++ b/src/os_regex/os_regex_free_substrings.c @@ -0,0 +1,32 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" +#include "os_regex_internal.h" + + +/* Release all the memory created to store the sub strings */ +void OSRegex_FreeSubStrings(OSRegex *reg) +{ + /* Free the sub strings */ + if (reg->sub_strings) { + int i = 0; + while (reg->sub_strings[i]) { + free(reg->sub_strings[i]); + reg->sub_strings[i] = NULL; + i++; + } + } + return; +} + diff --git a/src/os_regex/os_regex_internal.h b/src/os_regex/os_regex_internal.h new file mode 100644 index 000000000..856efde86 --- /dev/null +++ b/src/os_regex/os_regex_internal.h @@ -0,0 +1,112 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef __OS_INTERNAL_H +#define __OS_INTERNAL_H + +/* Prototype for the _OsMatch */ +int _OS_Match(const char *pattern, const char *str, size_t str_len, size_t size) __attribute__((nonnull)); +int _os_strncmp(const char *pattern, const char *str, size_t str_len, size_t size) __attribute__((nonnull)); +int _os_strcmp_last(const char *pattern, const char *str, size_t str_len, size_t size) __attribute__((nonnull)); +int _os_strcmp(const char *pattern, const char *str, size_t str_len, size_t size) __attribute__((nonnull)); +int _os_strmatch(const char *pattern, const char *str, size_t str_len, size_t size) __attribute__((nonnull)); + +#define BACKSLASH '\\' +#define ENDSTR '\0' +#define ENDLINE '\n' +#define BEGINREGEX '^' +#define ENDREGEX '$' +#define OR '|' +#define AND '&' + +#define TRUE 1 +#define FALSE 0 + +/* Pattern flags */ +#define BEGIN_SET 0000200 +#define END_SET 0000400 + +/* uchar */ +typedef unsigned char uchar; + +/* _IsD Returns 1 if it is a number */ +#define _IsD(x) ((x >= 48) && (x <= 57)) + +/* Is it a character? + * a-z or A-Z or 0-9 + * Returns 1 if true + */ +#define _IsW(x) ((x >= 48 && x <= 57 )|| \ + (x >= 65 && x <= 90 )|| \ + (x >= 97 && x <= 122)) + +/* Is it a ' ' (blank) + * Ascii 32 + * Returns 1 if true + */ +#define _IsS(x) (x == 32) + +/* Check for parenthesis */ +#define prts(x) (x == '(') + +/* Is it '+' or '*' + * Returns 1 on success + */ +#define isPlus(x) ((x == '+') || (x == '*')) + +/* True char */ +#define TRUECHAR 1 + +/* Is "y" a valid "x"?. + * Returns 1 on success + */ +#define Regex(x,y) (regexmap[x][y] == TRUECHAR) +#define Regex2(x,y) (x == 'd' && y >= 48 && y <= 57)|| \ + (x == 's' && y == 32)|| \ + ((x == 'p') && \ + ((y >= 40 && y <= 46)|| \ + (y >= 58 && y <= 63)))|| \ + ((x == 'w') && \ + ((y == '_')|| \ + (y >= 48 && y <= 57)|| \ + (y >= 65 && y <= 90)|| \ + (y >= 97 && y <= 122)))|| \ + (x == '.')|| \ + ((x == '\\') && (y == '\\'))|| \ + ((x == 'n') && (y == '\n'))|| \ + (x == 'S' && y != 32)|| \ + (x == 'D' && (y < 48 || y > 57))|| \ + (x == 'W' && (y < 48 || y > 122 || \ + (y > 57 && y <65)||(y > 90 && y< 97))) + +/* Charmap for case insensitive search */ +extern const uchar charmap[256]; + +/* Regex mapping + * 0 = none + * 1 = \d + * 2 = \w + * 3 = \s + * 4 = \p + * 5 = \( + * 6 = \) + * 7 = \\ + * 8 = \D + * 9 = \W + * 10 = \S + * 11 = \. + * 12 = \t + * 13 = \$ + * 14 = | + * 15 = < + */ +extern const uchar regexmap[][256]; + +#endif /* __OS_INTERNAL_H */ + diff --git a/src/os_regex/os_regex_maps.c b/src/os_regex/os_regex_maps.c new file mode 100644 index 000000000..c535b41cf --- /dev/null +++ b/src/os_regex/os_regex_maps.c @@ -0,0 +1,634 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "os_regex.h" +#include "os_regex_internal.h" + +/* Hostname charmap + * Available chars: a-z, A-Z, 0-9, -, _, ., @ / + */ +const unsigned char hostname_map[256] = { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 1, 1, 42, 43, 44, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 59, 60, 61, 62, 63, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 91, 92, 93, 94, 1, + 96, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 240, 241, 242, 243, 244, 245, 246, 247, +}; + +const unsigned char charmap[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, +}; + +const unsigned char regexmap[][256] = { + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 1, 46, 47, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 59, 60, 61, 62, 63, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 91, 92, 93, 94, 1, + 96, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 240, 241, 242, 243, 244, 245, 246, 247, + }, + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 1, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 1, 1, 1, 1, 1, 1, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 1, 0, 1, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 1, 1, 1, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }, + { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }, + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 1, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 10, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 1, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 10, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 1, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, + + + { + 0, 0, 2, 3, 4, 5, 6, 7, + 8, 10, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 1, 61, 62, 63, + 64, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + }, +}; + diff --git a/src/os_regex/os_regex_match.c b/src/os_regex/os_regex_match.c new file mode 100644 index 000000000..5097b31df --- /dev/null +++ b/src/os_regex/os_regex_match.c @@ -0,0 +1,121 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include + +#include "os_regex.h" +#include "os_regex_internal.h" + +/* Algorithm: + * Go as fast as you can :) + * + * Supports: + * '|' to separate multiple OR patterns + * '^' to match the beginning of a string + */ + +/* Prototypes */ +static int _InternalMatch(const char *pattern, const char *str, size_t count) __attribute__((nonnull)); + + +/* Search for pattern in the string */ +int OS_WordMatch(const char *pattern, const char *str) +{ + size_t count = 0; + + if (*pattern == '\0') { + return (FALSE); + } + + do { + if (pattern[count] == '|') { + /* If we match '|' , search with + * we have so far. + */ + if (_InternalMatch(pattern, str, count)) { + return (TRUE); + } else { + pattern += count + 1; + count = 0; + continue; + } + } + + count++; + + } while (pattern[count] != '\0'); + + /* Last check until end of string */ + return (_InternalMatch(pattern, str, count)); +} + +static int _InternalMatch(const char *pattern, const char *str, size_t pattern_size) +{ + const uchar *pt = (const uchar *)pattern; + const uchar *st = (const uchar *)str; + const uchar last_char = (const uchar) pattern[pattern_size]; + + if (*pattern == '\0') { + return (TRUE); + } + + /* If '^' specified, just do a strncasecmp */ + else if (*pattern == '^') { + pattern++; + pattern_size --; + + /* Compare two strings */ + if (strncasecmp(pattern, str, pattern_size) == 0) { + return (TRUE); + } + return (FALSE); + } + + /* Null line */ + else if (*st == '\0') { + return (FALSE); + } + + /* Look to match the first pattern */ + do { + /* Match */ + if (charmap[*st] == charmap[*pt]) { + str = (const char *)st++; + pt++; + + while (*pt != last_char) { + if (*st == '\0') { + return (FALSE); + } + + else if (charmap[*pt] != charmap[*st]) { + goto error; + } + + st++; + pt++; + } + + /* Return here if pt == last_char */ + return (TRUE); + +error: + st = (const uchar *)str; + pt = (const uchar *)pattern; + } + + st++; + } while (*st != '\0'); + + return (FALSE); +} + diff --git a/src/os_regex/os_regex_startswith.c b/src/os_regex/os_regex_startswith.c new file mode 100644 index 000000000..b825403cd --- /dev/null +++ b/src/os_regex/os_regex_startswith.c @@ -0,0 +1,23 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "os_regex.h" +#include "os_regex_internal.h" + + +int OS_StrStartsWith(const char *str, const char *pattern) +{ + while (*pattern) { + if (*pattern++ != *str++) { + return FALSE; + } + } + + return TRUE; +} diff --git a/src/os_regex/os_regex_str.c b/src/os_regex/os_regex_str.c new file mode 100644 index 000000000..dbf73e57b --- /dev/null +++ b/src/os_regex/os_regex_str.c @@ -0,0 +1,55 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" +#include "os_regex_internal.h" + + +/* Check if a specific string is numeric (like "129544") */ +int OS_StrIsNum(const char *str) +{ + if (str == NULL) { + return (FALSE); + } + + while (*str != '\0') { + if (!_IsD(*str)) { + return (FALSE); + } + str++; + } + + return (TRUE); +} + +/* Return the number of characters that both strings have in common */ +size_t OS_StrHowClosedMatch(const char *str1, const char *str2) +{ + size_t count = 0; + + /* They don't match if any of them is null */ + if (!str1 || !str2) { + return (0); + } + + do { + if (str1[count] != str2[count]) { + break; + } + + count++; + } while ((str1[count] != '\0') && (str2[count] != '\0')); + + return (count); +} + diff --git a/src/os_regex/os_regex_strbreak.c b/src/os_regex/os_regex_strbreak.c new file mode 100644 index 000000000..dde2d233d --- /dev/null +++ b/src/os_regex/os_regex_strbreak.c @@ -0,0 +1,106 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_regex.h" +#include "os_regex_internal.h" + + +/* Split a string into multiples pieces, divided by a char "match". + * Returns a NULL terminated array on success or NULL on error. + */ +char **OS_StrBreak(char match, const char *str, size_t size) +{ + size_t count = 0; + size_t i = 0; + const char *tmp_str = str; + char **ret; + + /* We can't do anything if str is null */ + if (str == NULL) { + return (NULL); + } + + ret = (char **)calloc(size + 1, sizeof(char *)); + + if (ret == NULL) { + /* Memory error. Should provide a better way to detect it */ + return (NULL); + } + + /* Allocate memory to null */ + while (i <= size) { + ret[i] = NULL; + i++; + } + i = 0; + + while (*str != '\0') { + i++; + if ((count < size - 1) && (*str == match)) { + ret[count] = (char *)calloc(i, sizeof(char)); + + if (ret[count] == NULL) { + goto error; + } + + /* Copy the string */ + ret[count][i - 1] = '\0'; + strncpy(ret[count], tmp_str, i - 1); + + tmp_str = ++str; + count++; + i = 0; + + continue; + } + str++; + } /* leave from here when *str == \0 */ + + + /* Just do it if count < size */ + if (count < size) { + ret[count] = (char *)calloc(i + 1, sizeof(char)); + + if (ret[count] == NULL) { + goto error; + } + + /* Copy the string */ + ret[count][i] = '\0'; + strncpy(ret[count], tmp_str, i); + + count++; + + /* Make sure it is null terminated */ + ret[count] = NULL; + + return (ret); + } + + /* We shouldn't get to this point + * Just let "error" handle that + */ + +error: + i = 0; + + while (i < count) { + free(ret[i]); + i++; + } + + free(ret); + return (NULL); + +} + diff --git a/src/os_xml/COPYRIGHT b/src/os_xml/COPYRIGHT new file mode 100644 index 000000000..99043b77f --- /dev/null +++ b/src/os_xml/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (C) 2009 Trend Micro Inc. + All rights reserved. + This program is a free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License (version 2) as published by the FSF - Free Software + Foundation + +openarmor, os_xml library. +Available at http://www.theopenarmor.org diff --git a/src/os_xml/README b/src/os_xml/README new file mode 100644 index 000000000..6a499a5ac --- /dev/null +++ b/src/os_xml/README @@ -0,0 +1,21 @@ +== openarmor, os_xml "library" == +Copyright (C) 2009 Trend Micro Inc. + +This "library" is a set of very simple functions to read +a XML configuration file. + +It can only read XML, not write. I did not test it on very +complex XML files, so I don't know if it will work. + +Any question, comment or suggestion, please contact me +at dcid@theopenarmor.org or daniel@underlinux.com.br. + +The latest version of this library is available at +http://www.theopenarmor.org/ + +== Examples == + +The file examples/main.c shows some examples (reading example.xml) on +how to use the "os_xml" to read an XML file. Basically, you only need to +start your XML" by calling the ReadXML function (the file as argument) +and use the other supplied functions to read the structure it creates. diff --git a/src/os_xml/VERSION b/src/os_xml/VERSION new file mode 100644 index 000000000..be5863417 --- /dev/null +++ b/src/os_xml/VERSION @@ -0,0 +1 @@ +0.3 diff --git a/src/os_xml/examples/mem_test.c b/src/os_xml/examples/mem_test.c new file mode 100644 index 000000000..fc3f3fc16 --- /dev/null +++ b/src/os_xml/examples/mem_test.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +#include "os_xml.h" + + +int main(int argc, char **argv) +{ + if (argc < 2) { + printf("usage: %s file\n", argv[0]); + return (-1); + } + + while (1) { + OS_XML xml; + xml_node **node; + int i = 0; + + usleep(10); + printf("."); + fflush(stdout); + + if (OS_ReadXML(argv[1], &xml) < 0) { + printf("Error reading XML(%u): %s\n", xml.err_line, xml.err); + return (1); + } + + node = OS_GetElementsbyNode(&xml, NULL); + if (node == NULL) { + printf("error reading xml\n"); + return (1); + } + + while (node[i]) { + xml_node **cnode = NULL; + int j = 0; + cnode = OS_GetElementsbyNode(&xml, node[i]); + if (cnode == NULL) { + i++; + continue; + } + while (cnode[j]) { + /* */ + j++; + } + + OS_ClearNode(cnode); + i++; + } + + OS_ClearNode(node); + + node = NULL; + + OS_ClearXML(&xml); + } + return (0); +} + diff --git a/src/os_xml/examples/test.c b/src/os_xml/examples/test.c new file mode 100644 index 000000000..2fa85ae5a --- /dev/null +++ b/src/os_xml/examples/test.c @@ -0,0 +1,79 @@ +#include +#include +#include + +#include "os_xml.h" + + +int main(int argc, char **argv) +{ + int i = 0; + OS_XML xml; + XML_NODE node = NULL; + + /* File name must be given */ + if (argc < 2) { + printf("Usage: %s file\n", argv[0]); + return (-1); + } + + /* Read the XML. Print error and line number */ + if (OS_ReadXML(argv[1], &xml) < 0) { + printf("OS_ReadXML error: %s, line :%d\n", xml.err, xml.err_line); + return (1); + } + + if (OS_ApplyVariables(&xml) != 0) { + printf("OS_ReadXML error: Applying variables: %s\n", xml.err); + return (1); + } + + /* Get all nodes */ + node = OS_GetElementsbyNode(&xml, NULL); + if (node == NULL) { + printf("OS_GetElementsbyNode error: %s, line: %d\n", xml.err, xml.err_line); + return (1); + } + + i = 0; + + while (node[i]) { + int j = 0; + XML_NODE cnode; + + cnode = OS_GetElementsbyNode(&xml, node[i]); + if (cnode == NULL) { + i++; + continue; + } + + while (cnode[j]) { + printf("Element: %s -> %s\n", + cnode[j]->element, + cnode[j]->content); + if (cnode[j]->attributes && cnode[j]->values) { + int k = 0; + while (cnode[j]->attributes[k]) { + printf("attr %s:%s\n", + cnode[j]->attributes[k], + cnode[j]->values[k]); + k++; + } + } + j++; + } + + OS_ClearNode(cnode); + i++; + } + + /* Clear the nodes */ + OS_ClearNode(node); + + node = NULL; + + OS_ClearXML(&xml); + + return (0); +} + diff --git a/src/os_xml/examples/test.xml b/src/os_xml/examples/test.xml new file mode 100644 index 000000000..5bad9cde3 --- /dev/null +++ b/src/os_xml/examples/test.xml @@ -0,0 +1,46 @@ +xx +my name is daniel +xx2 +Davi Alves Cid +Liliane Cid + + + + + $lala + + lele + + + + $lala + $lala2 + $lala + PARA $lala2,$lala ola $davi|$lili$lala.$lala OIIIIII + lala-abc + + + + + yes please \< lala + + + + + content1 + content2 + + + + content3lala \< lala\< + content4 + content5 + content51 + content52 + + content6 + + diff --git a/src/os_xml/os_xml.c b/src/os_xml/os_xml.c new file mode 100644 index 000000000..175d88739 --- /dev/null +++ b/src/os_xml/os_xml.c @@ -0,0 +1,536 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* os_xml Library */ + +#include +#include +#include +#include +#include + +#include "os_xml.h" +#include "os_xml_internal.h" + +/* Prototypes */ +static int _oscomment(FILE *fp) __attribute__((nonnull)); +static int _writecontent(const char *str, size_t size, unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static int _writememory(const char *str, XML_TYPE type, size_t size, + unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static int _xml_fgetc(FILE *fp) __attribute__((nonnull)); +static int _ReadElem(FILE *fp, unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static int _getattributes(FILE *fp, unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static void xml_error(OS_XML *_lxml, const char *msg, ...) __attribute__((format(printf, 2, 3), nonnull)); + +/* Current line */ +static unsigned int _line; + + +/* Local fgetc */ +static int _xml_fgetc(FILE *fp) +{ + int c; + c = fgetc(fp); + + if (c == '\n') { /* add newline */ + _line++; + } + + return (c); +} + +static void xml_error(OS_XML *_lxml, const char *msg, ...) +{ + va_list args; + va_start(args, msg); + + memset(_lxml->err, '\0', XML_ERR_LENGTH); + vsnprintf(_lxml->err, XML_ERR_LENGTH - 1, msg, args); + va_end(args); + _lxml->err_line = _line; +} + +/* Clear memory */ +void OS_ClearXML(OS_XML *_lxml) +{ + unsigned int i; + for (i = 0; i < _lxml->cur; i++) { + free(_lxml->el[i]); + free(_lxml->ct[i]); + } + _lxml->cur = 0; + _lxml->fol = 0; + _lxml->err_line = 0; + + free(_lxml->el); + _lxml->el = NULL; + + free(_lxml->ct); + _lxml->ct = NULL; + + free(_lxml->rl); + _lxml->rl = NULL; + + free(_lxml->tp); + _lxml->tp = NULL; + + free(_lxml->ck); + _lxml->ck = NULL; + + free(_lxml->ln); + _lxml->ln = NULL; + + memset(_lxml->err, '\0', XML_ERR_LENGTH); +} + +/* Read an XML file and generate the necessary structs */ +int OS_ReadXML(const char *file, OS_XML *_lxml) +{ + int r; + unsigned int i; + FILE *fp; + + /* Initialize xml structure */ + _lxml->cur = 0; + _lxml->fol = 0; + _lxml->el = NULL; + _lxml->ct = NULL; + _lxml->tp = NULL; + _lxml->rl = NULL; + _lxml->ck = NULL; + _lxml->ln = NULL; + + _lxml->err_line = 0; + memset(_lxml->err, '\0', XML_ERR_LENGTH); + + fp = fopen(file, "r"); + if (!fp) { + xml_error(_lxml, "XMLERR: File '%s' not found.", file); + return (-2); + } + + /* Zero the line */ + _line = 1; + + if ((r = _ReadElem(fp, 0, _lxml)) < 0) { /* First position */ + if (r != LEOF) { + fclose(fp); + return (-1); + } + } + + for (i = 0; i < _lxml->cur; i++) { + if (_lxml->ck[i] == 0) { + xml_error(_lxml, "XMLERR: Element '%s' not closed.", _lxml->el[i]); + fclose(fp); + return (-1); + } + } + + fclose(fp); + return (0); +} + +static int _oscomment(FILE *fp) +{ + int c; + if ((c = fgetc(fp)) == _R_COM) { + while ((c = _xml_fgetc(fp)) != EOF) { + if (c == _R_COM) { + if ((c = fgetc(fp)) == _R_CONFE) { + return (1); + } + ungetc(c, fp); + } else if (c == '-') { /* W3C way of finishing comments */ + if ((c = _xml_fgetc(fp)) == '-') { + if ((c = fgetc(fp)) == _R_CONFE) { + return (1); + } + ungetc(c, fp); + } + ungetc(c, fp); + } else { + continue; + } + } + return (-1); + } else { + ungetc(c, fp); + } + return (0); +} + +static int _ReadElem(FILE *fp, unsigned int parent, OS_XML *_lxml) +{ + int c; + unsigned int count = 0; + unsigned int _currentlycont = 0; + short int location = -1; + + int prevv = 0; + char elem[XML_MAXSIZE + 1]; + char cont[XML_MAXSIZE + 1]; + char closedelim[XML_MAXSIZE + 1]; + + memset(elem, '\0', XML_MAXSIZE + 1); + memset(cont, '\0', XML_MAXSIZE + 1); + memset(closedelim, '\0', XML_MAXSIZE + 1); + + while ((c = _xml_fgetc(fp)) != EOF) { + if (c == '\\') { + prevv = c; + } else if (prevv == '\\') { + if (c != _R_CONFS) { + prevv = 0; + } + } + + /* Max size */ + if (count >= XML_MAXSIZE) { + xml_error(_lxml, "XMLERR: String overflow."); + return (-1); + } + + /* Check for comments */ + if (c == _R_CONFS) { + int r = 0; + if ((r = _oscomment(fp)) < 0) { + xml_error(_lxml, "XMLERR: Comment not closed."); + return (-1); + } else if (r == 1) { + continue; + } + } + + /* Real checking */ + if ((location == -1) && (prevv == 0)) { + if (c == _R_CONFS) { + if ((c = fgetc(fp)) == '/') { + xml_error(_lxml, "XMLERR: Element not opened."); + return (-1); + } else { + ungetc(c, fp); + } + location = 0; + } else { + continue; + } + } + + else if ((location == 0) && ((c == _R_CONFE) || isspace(c))) { + int _ge = 0; + int _ga = 0; + elem[count] = '\0'; + + /* Remove the / at the end of the element name */ + if (count > 0 && elem[count - 1] == '/') { + _ge = '/'; + elem[count - 1] = '\0'; + } + + if (_writememory(elem, XML_ELEM, count + 1, parent, _lxml) < 0) { + return (-1); + } + _currentlycont = _lxml->cur - 1; + if (isspace(c)) { + if ((_ga = _getattributes(fp, parent, _lxml)) < 0) { + return (-1); + } + } + + /* If the element is closed already (finished in />) */ + if ((_ge == '/') || (_ga == '/')) { + if (_writecontent("\0", 2, _currentlycont, _lxml) < 0) { + return (-1); + } + _lxml->ck[_currentlycont] = 1; + _currentlycont = 0; + count = 0; + location = -1; + + memset(elem, '\0', XML_MAXSIZE); + memset(closedelim, '\0', XML_MAXSIZE); + memset(cont, '\0', XML_MAXSIZE); + + if (parent > 0) { + return (0); + } + } else { + count = 0; + location = 1; + } + } + + else if ((location == 2) && (c == _R_CONFE)) { + closedelim[count] = '\0'; + if (strcmp(closedelim, elem) != 0) { + xml_error(_lxml, "XMLERR: Element '%s' not closed.", elem); + return (-1); + } + if (_writecontent(cont, strlen(cont) + 1, _currentlycont, _lxml) < 0) { + return (-1); + } + _lxml->ck[_currentlycont] = 1; + memset(elem, '\0', XML_MAXSIZE); + memset(closedelim, '\0', XML_MAXSIZE); + memset(cont, '\0', XML_MAXSIZE); + _currentlycont = 0; + count = 0; + location = -1; + if (parent > 0) { + return (0); + } + } else if ((location == 1) && (c == _R_CONFS) && (prevv == 0)) { + if ((c = fgetc(fp)) == '/') { + cont[count] = '\0'; + count = 0; + location = 2; + } else { + ungetc(c, fp); + ungetc(_R_CONFS, fp); + + if (_ReadElem(fp, parent + 1, _lxml) < 0) { + return (-1); + } + count = 0; + } + } else { + if (location == 0) { + elem[count++] = (char) c; + } else if (location == 1) { + cont[count++] = (char) c; + } else if (location == 2) { + closedelim[count++] = (char) c; + } + + if ((_R_CONFS == c) && (prevv != 0)) { + prevv = 0; + } + } + } + if (location == -1) { + return (LEOF); + } + + xml_error(_lxml, "XMLERR: End of file and some elements were not closed."); + return (-1); +} + +static int _writememory(const char *str, XML_TYPE type, size_t size, + unsigned int parent, OS_XML *_lxml) +{ + char **tmp; + int *tmp2; + unsigned int *tmp3; + XML_TYPE *tmp4; + + /* Allocate for the element */ + tmp = (char **)realloc(_lxml->el, (_lxml->cur + 1) * sizeof(char *)); + if (tmp == NULL) { + goto fail; + } + _lxml->el = tmp; + _lxml->el[_lxml->cur] = (char *)calloc(size, sizeof(char)); + if (_lxml->el[_lxml->cur] == NULL) { + goto fail; + } + strncpy(_lxml->el[_lxml->cur], str, size - 1); + + /* Allocate for the content */ + tmp = (char **)realloc(_lxml->ct, (_lxml->cur + 1) * sizeof(char *)); + if (tmp == NULL) { + goto fail; + } + _lxml->ct = tmp; + _lxml->ct[_lxml->cur] = NULL; + + /* Allocate for the type */ + tmp4 = (XML_TYPE *) realloc(_lxml->tp, (_lxml->cur + 1) * sizeof(XML_TYPE)); + if (tmp4 == NULL) { + goto fail; + } + _lxml->tp = tmp4; + _lxml->tp[_lxml->cur] = type; + + /* Allocate for the relation */ + tmp3 = (unsigned int *) realloc(_lxml->rl, (_lxml->cur + 1) * sizeof(unsigned int)); + if (tmp3 == NULL) { + goto fail; + } + _lxml->rl = tmp3; + _lxml->rl[_lxml->cur] = parent; + + /* Allocate for the "check" */ + tmp2 = (int *) realloc(_lxml->ck, (_lxml->cur + 1) * sizeof(int)); + if (tmp2 == NULL) { + goto fail; + } + _lxml->ck = tmp2; + _lxml->ck[_lxml->cur] = 0; + + /* Allocate for the line */ + tmp3 = (unsigned int *) realloc(_lxml->ln, (_lxml->cur + 1) * sizeof(unsigned int)); + if (tmp3 == NULL) { + goto fail; + } + _lxml->ln = tmp3; + _lxml->ln[_lxml->cur] = _line; + + /* Attributes does not need to be closed */ + if (type == XML_ATTR) { + _lxml->ck[_lxml->cur] = 1; + } + + /* Check if it is a variable */ + if (strcasecmp(XML_VAR, str) == 0) { + _lxml->tp[_lxml->cur] = XML_VARIABLE_BEGIN; + } + + _lxml->cur++; + return (0); + +fail: + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + return (-1); +} + +static int _writecontent(const char *str, size_t size, unsigned int parent, OS_XML *_lxml) +{ + _lxml->ct[parent] = (char *)calloc(size, sizeof(char)); + if ( _lxml->ct[parent] == NULL) { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + return (-1); + } + strncpy(_lxml->ct[parent], str, size - 1); + + return (0); +} + +/* Read the attributes of an element */ +static int _getattributes(FILE *fp, unsigned int parent, OS_XML *_lxml) +{ + int location = 0; + unsigned int count = 0; + int c; + int c_to_match = 0; + + char attr[XML_MAXSIZE + 1]; + char value[XML_MAXSIZE + 1]; + + memset(attr, '\0', XML_MAXSIZE + 1); + memset(value, '\0', XML_MAXSIZE + 1); + + while ((c = _xml_fgetc(fp)) != EOF) { + if (count >= XML_MAXSIZE) { + attr[count - 1] = '\0'; + xml_error(_lxml, + "XMLERR: Overflow attempt at attribute '%.20s'.", attr); + return (-1); + } + + else if ((c == _R_CONFE) || ((location == 0) && (c == '/'))) { + if (location == 1) { + xml_error(_lxml, "XMLERR: Attribute '%s' not closed.", + attr); + return (-1); + } else if ((location == 0) && (count > 0)) { + xml_error(_lxml, "XMLERR: Attribute '%s' has no value.", + attr); + return (-1); + } else if (c == '/') { + return (c); + } else { + return (0); + } + } else if ((location == 0) && (c == '=')) { + attr[count] = '\0'; + + /* Check for existing attribute with same name */ + unsigned int i = _lxml->cur - 1; + /* Search attributes backwards in same parent */ + while (_lxml->rl[i] == parent && _lxml->tp[i] == XML_ATTR) { + if (strcmp(_lxml->el[i], attr) == 0) { + xml_error(_lxml, "XMLERR: Attribute '%s' already defined.", attr); + return (-1); + } + + /* Continue with previous element */ + if (i == 0) { + break; + } + i--; + } + + c = _xml_fgetc(fp); + if ((c != '"') && (c != '\'')) { + unsigned short int _err = 1; + if (isspace(c)) { + while ((c = _xml_fgetc(fp)) != EOF) { + if (isspace(c)) { + continue; + } else if ((c == '"') || (c == '\'')) { + _err = 0; + break; + } else { + break; + } + } + } + if (_err != 0) { + xml_error(_lxml, + "XMLERR: Attribute '%s' not followed by a \" or \'." + , attr); + return (-1); + } + } + + c_to_match = c; + location = 1; + count = 0; + } else if ((location == 0) && (isspace(c))) { + if (count == 0) { + continue; + } else { + xml_error(_lxml, "XMLERR: Attribute '%s' has no value.", attr); + return (-1); + } + } else if ((location == 1) && (c == c_to_match)) { + value[count] = '\0'; + + if (_writememory(attr, XML_ATTR, strlen(attr) + 1, + parent, _lxml) < 0) { + return (-1); + } + if (_writecontent(value, count + 1, _lxml->cur - 1, _lxml) < 0) { + return (-1); + } + c = _xml_fgetc(fp); + if (isspace(c)) { + return (_getattributes(fp, parent, _lxml)); + } else if (c == _R_CONFE) { + return (0); + } else if (c == '/') { + return (c); + } + + xml_error(_lxml, + "XMLERR: Bad attribute closing for '%s'='%s'.", + attr, value); + return (-1); + } else if (location == 0) { + attr[count++] = (char) c; + } else if (location == 1) { + value[count++] = (char) c; + } + } + + xml_error(_lxml, "XMLERR: End of file while reading an attribute."); + return (-1); +} + diff --git a/src/os_xml/os_xml.h b/src/os_xml/os_xml.h new file mode 100644 index 000000000..bf1c2c46b --- /dev/null +++ b/src/os_xml/os_xml.h @@ -0,0 +1,96 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* os_xml C Library */ + +#ifndef __OS_XML_H +#define __OS_XML_H + +/* XML Node structure */ +typedef struct _xml_node { + unsigned int key; + char *element; + char *content; + char **attributes; + char **values; +} xml_node; + +#define XML_ERR_LENGTH 128 +typedef enum _XML_TYPE { XML_ATTR, XML_ELEM, XML_VARIABLE_BEGIN = '$' } XML_TYPE; + +/* XML structure */ +typedef struct _OS_XML { + unsigned int cur; /* Current position (and last after reading) */ + int fol; /* Current position for the xml_access */ + XML_TYPE *tp; /* Item type */ + unsigned int *rl; /* Relation in the XML */ + int *ck; /* If the item was closed or not */ + unsigned int *ln; /* Current xml file line */ + unsigned int err_line; /* Line number of the possible error */ + char **ct; /* Content is stored */ + char **el; /* The element/attribute name is stored */ + char err[XML_ERR_LENGTH]; /* Error messages are stored in here */ +} OS_XML; + +typedef xml_node **XML_NODE; + +/* Start the XML structure reading a file */ +int OS_ReadXML(const char *file, OS_XML *lxml) __attribute__((nonnull)); + +/* Clear the XML structure memory */ +void OS_ClearXML(OS_XML *_lxml) __attribute__((nonnull)); + +/* Clear a node */ +void OS_ClearNode(xml_node **node); + + +/* Functions to read the XML */ + +/* Return 1 if element_name is a root element */ +unsigned int OS_RootElementExist(const OS_XML *_lxml, const char *element_name) __attribute__((nonnull)); + +/* Return 1 if the element_name exists */ +unsigned int OS_ElementExist(const OS_XML *_lxml, const char **element_name) __attribute__((nonnull)); + +/* Return the elements "children" of the element_name */ +char **OS_GetElements(const OS_XML *_lxml, const char **element_name) __attribute__((nonnull(1))); + +/* Return the elements "children" of the element_name */ +xml_node **OS_GetElementsbyNode(const OS_XML *_lxml, const xml_node *node) __attribute__((nonnull(1))); + +/* Return the attributes of the element name */ +char **OS_GetAttributes(const OS_XML *_lxml, const char **element_name) __attribute__((nonnull(1))); + +/* Return one value from element_name */ +char *OS_GetOneContentforElement(OS_XML *_lxml, const char **element_name) __attribute__((nonnull)); + +/* Return an array with the content of all entries of element_name */ +char **OS_GetElementContent(OS_XML *_lxml, const char **element_name) __attribute__((nonnull)); + +/* Return an array with the contents of an element_nane */ +char **OS_GetContents(OS_XML *_lxml, const char **element_name) __attribute__((nonnull(1))); + +/* Return the value of a specific attribute of the element_name */ +char *OS_GetAttributeContent(OS_XML *_lxml, const char **element_name, + const char *attribute_name) __attribute__((nonnull(1, 2))); + +/* Apply the variables to the xml */ +int OS_ApplyVariables(OS_XML *_lxml) __attribute__((nonnull)); + +/* Error from writer */ +#define XMLW_ERROR 006 +#define XMLW_NOIN 007 +#define XMLW_NOOUT 010 + +/* Write an XML file, based on the input and values to change */ +int OS_WriteXML(const char *infile, const char *outfile, const char **nodes, + const char *oldval, const char *newval) __attribute__((nonnull(1, 2, 3, 5))); + +#endif /* __OS_XML_H */ + diff --git a/src/os_xml/os_xml_access.c b/src/os_xml/os_xml_access.c new file mode 100644 index 000000000..eeeea2a5d --- /dev/null +++ b/src/os_xml/os_xml_access.c @@ -0,0 +1,360 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_xml.h" +#include "os_xml_internal.h" + +/* Prototypes */ +static char **_GetElements(const OS_XML *_lxml, const char **element_name, XML_TYPE type) __attribute__((nonnull(1))); +static char **_GetElementContent(OS_XML *_lxml, const char **element_name, const char *attr) __attribute__((nonnull(1, 2))); + + +/* Check if a element exists + * The element_name must be NULL terminated (last char) + */ +unsigned int OS_ElementExist(const OS_XML *_lxml, const char **element_name) +{ + unsigned int i = 0, j = 0, matched = 0, totalmatch = 0; + + if (element_name[0] == NULL) { + return (0); + } + + for (i = 0, j = 0; i < _lxml->cur; i++) { + if (element_name[j] == NULL) { + j = 0; + } + if ((_lxml->tp[i] == XML_ELEM) && (_lxml->rl[i] == j)) { + if (strcmp(_lxml->el[i], element_name[j]) == 0) { + j++; + matched = 1; + if (element_name[j] == NULL) { + j = 0; + totalmatch++; + } + continue; + } + } + if ((matched == 1) && (j > _lxml->rl[i]) && + (_lxml->tp[i] == XML_ELEM)) { + j = 0; + matched = 0; + } + } + return (totalmatch); +} + +/* Check if a root element exists */ +unsigned int OS_RootElementExist(const OS_XML *_lxml, const char *element_name) +{ + const char *(elements[]) = {element_name, NULL}; + return (OS_ElementExist(_lxml, elements)); +} + +/* Get the attributes of the element_name */ +char **OS_GetAttributes(const OS_XML *_lxml, const char **element_name) +{ + return (_GetElements(_lxml, element_name, XML_ATTR)); +} + +/* Get the elements children of the element_name */ +char **OS_GetElements(const OS_XML *_lxml, const char **element_name) +{ + return (_GetElements(_lxml, element_name, XML_ELEM)); +} + +/* Get the elements or attributes (internal use) */ +static char **_GetElements(const OS_XML *_lxml, const char **element_name, XML_TYPE type) +{ + unsigned i = 0, j = 0, k = 0, matched = 0, ready = 0; + char **ret = NULL; + char **ret_tmp = NULL; + + if ((type == XML_ELEM) && (element_name == NULL)) { + ready = 1; + } + + for (i = 0, j = 0; i < _lxml->cur; i++) { + if ((ready != 1) && (element_name[j] == NULL)) { + if (matched == 1) { + ready = 1; + } else { + break; + } + } + + if (j > 16) { + return (ret); + } + + if ((ready == 1) && (_lxml->tp[i] == type)) { + if (((type == XML_ATTR) && (_lxml->rl[i] == j - 1) + && (_lxml->el[i] != NULL)) || + ((type == XML_ELEM) && (_lxml->rl[i] == j) && + (_lxml->el[i] != NULL))) { + size_t el_size = strlen(_lxml->el[i]) + 1; + ret_tmp = (char **)realloc(ret, (k + 2) * sizeof(char *)); + if (ret_tmp == NULL) { + goto fail; + } + ret = ret_tmp; + ret[k + 1] = NULL; + ret[k] = (char *)calloc(el_size, sizeof(char)); + if (ret[k] == NULL) { + goto fail; + } + strncpy(ret[k], _lxml->el[i], el_size - 1); + k++; + } + } + + else if ((_lxml->tp[i] == XML_ELEM) && (_lxml->rl[i] == j) && + (element_name[j] != NULL)) { + if (strcmp(_lxml->el[i], element_name[j]) == 0) { + j++; + matched = 1; + continue; + } + } + + if (matched == 1) { + if (((_lxml->tp[i] == XML_ATTR) && (j > _lxml->rl[i] + 1)) || + ((_lxml->tp[i] == XML_ELEM) && (j > _lxml->rl[i]))) { + j = 0; + matched = 0; + if (element_name == NULL) { + ready = 1; + } else { + ready = 0; + } + } + } + } + + return (ret); + +fail: + i = 0; + if (ret) { + while (ret[i]) { + free(ret[i++]); + } + free(ret); + } + return (NULL); +} + +/* Get one value for a specific element */ +char *OS_GetOneContentforElement(OS_XML *_lxml, const char **element_name) +{ + int i = 1; + char *uniqret = NULL; + char **ret = NULL; + + _lxml->fol = 0; + ret = _GetElementContent(_lxml, element_name, NULL); + if (ret == NULL) { + return (NULL); + } + + if (ret[0] != NULL) { + uniqret = ret[0]; + } + + /* Free memory */ + while (ret[i]) { + free(ret[i]); + ret[i] = NULL; + i++; + } + free(ret); + + return (uniqret); +} + +/* Get all values for a specific element */ +char **OS_GetElementContent(OS_XML *_lxml, const char **element_name) +{ + _lxml->fol = 0; + return (_GetElementContent(_lxml, element_name, NULL)); +} + +/* Get the contents for a specific element + * Use element_name = NULL to start the state + */ +char **OS_GetContents(OS_XML *_lxml, const char **element_name) +{ + if (element_name == NULL) { + _lxml->fol = -1; + return (NULL); + } + return (_GetElementContent(_lxml, element_name, NULL)); +} + +/* Get one value for a specific attribute */ +char *OS_GetAttributeContent(OS_XML *_lxml, const char **element_name, + const char *attribute_name) +{ + char *uniqret = NULL; + char **ret = NULL; + + _lxml->fol = 0; + + ret = _GetElementContent(_lxml, element_name, attribute_name); + if (ret == NULL) { + return (NULL); + } + if (ret[0] != NULL) { + uniqret = ret[0]; + } + + int i = 1; + while (ret[i] != NULL) { + free(ret[i++]); + } + free(ret); + + return (uniqret); +} + +/* Get the values for an element or attribute */ +static char **_GetElementContent(OS_XML *_lxml, const char **element_name, const char *attr) +{ + int i = 0; + unsigned int j = 0, k = 0, l = 0, matched = 0; + char **ret = NULL; + char **ret_tmp; + + if (_lxml->fol >= 0 && (unsigned int)_lxml->fol == _lxml->cur) { + _lxml->fol = 0; + return (NULL); + } + + if (_lxml->fol > 0) { + for (i = _lxml->fol; i >= 0; i--) { + _lxml->fol = i; + if (_lxml->rl[i] == 0) { + break; + } + } + i = _lxml->fol; + } else { + i = 0; + } + + /* Loop over all nodes */ + for (j = 0, l = (unsigned int)i; l < _lxml->cur; l++) { + if (element_name[j] == NULL) { + if (matched != 1) { + break; + } + } + + /* Set maximum depth of 16 */ + if (j > 16) { + goto fail; + } + + /* If the type is not an element and the relation doesn't match, + * keep going + */ + if ((_lxml->tp[l] != XML_ELEM) || (_lxml->rl[l] != j)) { + /* If the node relation is higher than the current xml + * node, zero the position and look at it again (i--). + */ + if (j > _lxml->rl[l]) { + j = 0; + matched = 0; + l--; + } else { + continue; + } + } + + /* If the element name matches what we are looking for */ + else if (element_name[j] != NULL && strcmp(_lxml->el[l], element_name[j]) == 0) { + j++; + matched = 1; + + /* Get content if we are at the end of the array */ + if (element_name[j] == NULL) { + /* If we have an attribute to match */ + if (attr != NULL) { + unsigned int m = 0; + for (m = l + 1; m < _lxml->cur; m++) { + if (_lxml->tp[m] == XML_ELEM) { + break; + } + + if (strcmp(attr, _lxml->el[m]) == 0) { + l = m; + break; + } + } + } + + if (_lxml->ct[l] != NULL) { + /* Increase the size of the array */ + ret_tmp = (char **) realloc(ret, (k + 2) * sizeof(char *)); + if (ret_tmp == NULL) { + goto fail; + } + ret = ret_tmp; + + /* Add new entry */ + ret[k] = strdup(_lxml->ct[l]); + ret[k + 1] = NULL; + if (ret[k] == NULL) { + goto fail; + } + + matched = 1; + k++; + + if (attr != NULL) { + break; + } + + else if (_lxml->fol != 0) { + _lxml->fol = (int) l + 1; + break; + } + } + + /* Set new array pointer */ + if ((l < _lxml->cur - 1) && (_lxml->tp[l + 1] == XML_ELEM)) { + j = _lxml->rl[l + 1]; + } + } + continue; + } + + if (j > _lxml->rl[l]) { + j = 0; + matched = 0; + } + } + + return (ret); + +fail: + i = 0; + if (ret) { + while (ret[i]) { + free(ret[i++]); + } + free(ret); + } + return (NULL); +} + diff --git a/src/os_xml/os_xml_internal.h b/src/os_xml/os_xml_internal.h new file mode 100644 index 000000000..722bf6a54 --- /dev/null +++ b/src/os_xml/os_xml_internal.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef OS_XML_INTERNAL_H_ +#define OS_XML_INTERNAL_H_ + +#define _R_CONFS '<' +#define _R_CONFE '>' +#define _R_COM '!' + +#define LEOF -2 + +#define XML_MAXSIZE 8192 +#define XML_VARIABLE_MAXSIZE 256 + +#define XML_VAR "var" +#define XML_VAR_ATTRIBUTE "name" + +//#define XML_ELEM 101 +//#define XML_ATTR 102 +//#define XML_VARIABLE_BEGIN '$' + +#endif /* OS_XML_INTERNAL_H_ */ diff --git a/src/os_xml/os_xml_node_access.c b/src/os_xml/os_xml_node_access.c new file mode 100644 index 000000000..b7187c63b --- /dev/null +++ b/src/os_xml/os_xml_node_access.c @@ -0,0 +1,162 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_xml.h" +#include "os_xml_internal.h" + + +/* Clear the Node structure */ +void OS_ClearNode(xml_node **node) +{ + if (node) { + int i = 0; + while (node[i]) { + if (node[i]->element) { + free(node[i]->element); + } + if (node[i]->content) { + free(node[i]->content); + } + if (node[i]->attributes) { + int j = 0; + while (node[i]->attributes[j]) { + free(node[i]->attributes[j]); + j++; + } + free(node[i]->attributes); + } + if (node[i]->values) { + int j = 0; + while (node[i]->values[j]) { + free(node[i]->values[j]); + j++; + } + free(node[i]->values); + } + + node[i]->element = NULL; + node[i]->content = NULL; + node[i]->attributes = NULL; + node[i]->values = NULL; + free(node[i]); + node[i] = NULL; + i++; + } + free(node); + } +} + + +/* Get the elements by node */ +xml_node **OS_GetElementsbyNode(const OS_XML *_lxml, const xml_node *node) +{ + unsigned int i, k = 0, m; + xml_node **ret = NULL; + xml_node **ret_tmp = NULL; + + if (node == NULL) { + m = 0; + i = 0; + } else { + i = node->key; + m = _lxml->rl[i++] + 1; + } + + for (; i < _lxml->cur; i++) { + if (_lxml->tp[i] == XML_ELEM) { + if ((_lxml->rl[i] == m) && (_lxml->el[i] != NULL)) { + unsigned int l = i + 1; + /* Allocate for xml_node ** */ + ret_tmp = (xml_node **)realloc(ret, (k + 2) * sizeof(xml_node *)); + if (ret_tmp == NULL) { + goto fail; + } + ret = ret_tmp; + + /* Allocate for the xml_node * */ + ret[k] = (xml_node *)calloc(1, sizeof(xml_node)); + ret[k + 1] = NULL; + if (ret[k] == NULL) { + goto fail; + } + + ret[k]->element = NULL; + ret[k]->content = NULL; + ret[k]->attributes = NULL; + ret[k]->values = NULL; + + /* Get element */ + ret[k]->element = strdup(_lxml->el[i]); + if (ret[k]->element == NULL) { + goto fail; + } + + /* Get content */ + if (_lxml->ct[i]) { + ret[k]->content = strdup(_lxml->ct[i]); + if (ret[k]->content == NULL) { + goto fail; + } + } + /* Assign key */ + ret[k]->key = i; + + /* Get attributes */ + while (l < _lxml->cur) { + if ((_lxml->tp[l] == XML_ATTR) && (_lxml->rl[l] == m) && + (_lxml->el[l]) && (_lxml->ct[l])) { + char **tmp; + tmp = (char **)realloc(ret[k]->attributes, (l - i + 1) * sizeof(char *)); + if (tmp == NULL) { + goto fail; + } + ret[k]->attributes = tmp; + ret[k]->attributes[l - i] = NULL; + tmp = (char **)realloc(ret[k]->values, (l - i + 1) * sizeof(char *)); + if (tmp == NULL) { + goto fail; + } + ret[k]->values = tmp; + ret[k]->values[l - i] = NULL; + + ret[k]->attributes[l - i - 1] = strdup(_lxml->el[l]); + ret[k]->values[l - i - 1] = strdup(_lxml->ct[l]); + if (!(ret[k]->attributes[l - i - 1]) || + !(ret[k]->values[l - i - 1])) { + goto fail; + } + l++; + } else { + break; + } + } + k++; + continue; + } + } + if ((_lxml->tp[i] == XML_ELEM) && (m > _lxml->rl[i])) { + if (node == NULL) { + continue; + } else { + break; + } + } + } + + return (ret); + +fail: + OS_ClearNode(ret); + return (NULL); +} + diff --git a/src/os_xml/os_xml_variables.c b/src/os_xml/os_xml_variables.c new file mode 100644 index 000000000..efbbaf99d --- /dev/null +++ b/src/os_xml/os_xml_variables.c @@ -0,0 +1,235 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_xml.h" +#include "os_xml_internal.h" + + +int OS_ApplyVariables(OS_XML *_lxml) +{ + unsigned int i, j = 0, s = 0; + int retval = 0; + char **var = NULL; + char **value = NULL; + char **tmp = NULL; + char *p2 = NULL; + char *var_placeh = NULL; + + /* Get all variables */ + for (i = 0; i < _lxml->cur; i++) { + if (_lxml->tp[i] == XML_VARIABLE_BEGIN) { + int _found_var = 0; + + for (j = i + 1; j < _lxml->cur; j++) { + if (_lxml->rl[j] < _lxml->rl[i]) { + break; + } + + else if (_lxml->tp[j] == XML_ATTR) { + if ((_lxml->el[j]) && (strcasecmp(_lxml->el[j], XML_VAR_ATTRIBUTE) == 0)) { + if (!_lxml->ct[j]) { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Invalid variable content."); + _lxml->err_line = _lxml->ln[j]; + goto fail; + } else if (strlen(_lxml->ct[j]) >= XML_VARIABLE_MAXSIZE) { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Invalid variable name size."); + _lxml->err_line = _lxml->ln[j]; + goto fail; + } + + /* If not used, it will be cleaned later */ + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + + tmp = (char **)realloc(var, (s + 1) * sizeof(char *)); + if (tmp == NULL) { + goto fail; + } + var = tmp; + + var[s] = _lxml->ct[j]; + + /* Clean the lxml->err */ + strncpy(_lxml->err, " ", 3); + + _found_var = 1; + break; + } else { + snprintf(_lxml->err, XML_ERR_LENGTH, + "XMLERR: Only \""XML_VAR_ATTRIBUTE"\" is allowed" + " as an attribute for a variable."); + _lxml->err_line = _lxml->ln[j]; + goto fail; + } + } + } /* Attribute FOR */ + + + if ((_found_var == 0) || (!_lxml->ct[i])) { + snprintf(_lxml->err, XML_ERR_LENGTH, + "XMLERR: No value set for variable."); + _lxml->err_line = _lxml->ln[i]; + goto fail; + } + + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + + tmp = (char **)realloc(value, (s + 1) * sizeof(char *)); + if (tmp == NULL) { + goto fail; + } + value = tmp; + + value[s] = _lxml->ct[i]; + + strncpy(_lxml->err, " ", 3); + s++; + } else if (((_lxml->tp[i] == XML_ELEM) || (_lxml->tp[i] == XML_ATTR)) && + (_lxml->ct[i])) { + unsigned int tp = 0; + size_t init = 0; + char *p = NULL; + char lvar[XML_VARIABLE_MAXSIZE]; /* MAX Var size */ + + + if (strlen(_lxml->ct[i]) <= 2) { + continue; + } + + /* Check if any variable is defined */ + if (s == 0) { + continue; + } + + /* Duplicate string */ + p = strdup(_lxml->ct[i]); + p2 = p; + + if (p == NULL) { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + goto fail; + } + + /* Read the whole string */ + while (*p != '\0') { + if (*p == XML_VARIABLE_BEGIN) { + tp = 0; + p++; + memset(lvar, '\0', XML_VARIABLE_MAXSIZE); + + while (1) { + if ((*p == XML_VARIABLE_BEGIN) + || (*p == '\0') + || (*p == '.') + || (*p == '|') + || (*p == ',') + || (*p == ' ')) { + lvar[tp] = '\0'; + + /* Look for var */ + for (j = 0; j < s; j++) { + if (var[j] == NULL) { + break; + } + + if (strcasecmp(var[j], lvar) != 0) { + continue; + } + + size_t tsize = strlen(_lxml->ct[i]) + + strlen(value[j]) - tp + 1; + var_placeh = strdup(_lxml->ct[i]); + free(_lxml->ct[i]); + _lxml->ct[i] = (char *)calloc(tsize + 2, + sizeof(char)); + + if (_lxml->ct[i] == NULL || var_placeh == NULL) { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory " + "error."); + goto fail; + } + + strncpy(_lxml->ct[i], var_placeh, tsize); + + _lxml->ct[i][init] = '\0'; + strncat(_lxml->ct[i], value[j], tsize - init); + + init = strlen(_lxml->ct[i]); + strncat(_lxml->ct[i], p, + tsize - strlen(_lxml->ct[i])); + + free(var_placeh); + var_placeh = NULL; + + break; + } + + /* Variable not found */ + if ((j == s) && (strlen(lvar) >= 1)) { + snprintf(_lxml->err, XML_ERR_LENGTH, + "XMLERR: Unknown variable" + ": '%s'.", lvar); + _lxml->err_line = _lxml->ln[i]; + goto fail; + } else if (j == s) { + init++; + } + + goto go_next; + } + + /* Maximum size for a variable */ + if (tp >= XML_VARIABLE_MAXSIZE - 1) { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Invalid " + "variable name size: '%u'.", tp); + _lxml->err_line = _lxml->ln[i]; + goto fail; + + } + + lvar[tp] = *p; + tp++; + p++; + } + } /* IF XML_VAR_BEGIN */ + + p++; + init++; + +go_next: + continue; + + } /* WHILE END */ + + if (p2 != NULL) { + free(p2); + p2 = NULL; + p = NULL; + } + } + } + + goto cleanup; + +fail: + retval = -1; + +cleanup: + /* Clean up the variables */ + free(var); + free(value); + free(p2); + free(var_placeh); + + return (retval); +} + diff --git a/src/os_xml/os_xml_writer.c b/src/os_xml/os_xml_writer.c new file mode 100644 index 000000000..8993c1890 --- /dev/null +++ b/src/os_xml/os_xml_writer.c @@ -0,0 +1,314 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include + +#include "os_xml.h" +#include "os_xml_internal.h" + +/* Prototypes */ +static int _oswcomment(FILE *fp_in, FILE *fp_out) __attribute__((nonnull)); +static int _WReadElem(FILE *fp_in, FILE *fp_out, unsigned int position, unsigned int parent, + const char **node, const char *value, unsigned int node_pos) __attribute__((nonnull)); +static int _xml_wfgetc(FILE *fp_in, FILE *fp_out) __attribute__((nonnull)); + + +/* Local wfgetc */ +static int _xml_wfgetc(FILE *fp_in, FILE *fp_out) +{ + int c; + + /* Putting on fp_out, whatever we read */ + c = fgetc(fp_in); + if (c != EOF) { + fputc(c, fp_out); + } + + return (c); +} + +/* Write an XML file, based on the input and values to change */ +int OS_WriteXML(const char *infile, const char *outfile, const char **nodes, + const char *oldval, const char *newval) +{ + int r = 0; + FILE *fp_in; + FILE *fp_out; + + /* Open infile */ + fp_in = fopen(infile, "r"); + if (!fp_in) { + return (XMLW_NOIN); + } + + /* Open outfile */ + fp_out = fopen(outfile, "w"); + if (!fp_out) { + fclose(fp_in); + return (XMLW_NOOUT); + } + + if ((r = _WReadElem(fp_in, fp_out, 0, 0, + nodes, newval, 0)) < 0) { /* First position */ + fclose(fp_in); + fclose(fp_out); + return (XMLW_ERROR); + } + + /* We didn't find an entry, add at the end */ + if (!oldval && r == 0) { + int s = 0; + int rwidth = 0; + + fseek(fp_out, 0, SEEK_END); + fprintf(fp_out, "\n"); + + /* Print each node */ + while (nodes[s]) { + fprintf(fp_out, "%*c<%s>", rwidth, ' ', nodes[s]); + s++; + rwidth += 3; + + if (nodes[s]) { + fprintf(fp_out, "\n"); + } + } + + /* Print val */ + s--; + rwidth -= 6; + fprintf(fp_out, "%s\n", newval, nodes[s]); + s--; + + /* Close each node */ + while (s >= 0) { + fprintf(fp_out, "%*c\n", rwidth, ' ', nodes[s]); + s--; + rwidth -= 3; + } + } + + fclose(fp_in); + fclose(fp_out); + return (0); +} + +/* Get comments */ +static int _oswcomment(FILE *fp_in, FILE *fp_out) +{ + int c; + if ((c = fgetc(fp_in)) == _R_COM) { + fputc(c, fp_out); + while ((c = _xml_wfgetc(fp_in, fp_out)) != EOF) { + if (c == _R_COM) { + if ((c = fgetc(fp_in)) == _R_CONFE) { + fputc(c, fp_out); + return (1); + } + ungetc(c, fp_in); + } else if (c == '-') { /* W3C way of finishing comments */ + if ((c = fgetc(fp_in)) == '-') { + fputc(c, fp_out); + if ((c = fgetc(fp_in)) == _R_CONFE) { + fputc(c, fp_out); + return (1); + } + ungetc(c, fp_in); + } else { + ungetc(c, fp_in); + } + } else { + continue; + } + } + return (-1); + } else { + ungetc(c, fp_in); + } + + return (0); +} + +static int _WReadElem(FILE *fp_in, FILE *fp_out, unsigned int position, + unsigned int parent, const char **nodes, + const char *val, unsigned int node_pos) +{ + int c; + int ret_code = 0; + unsigned int count = 0; + short int location = -1; + + char elem[XML_MAXSIZE + 1]; + char cont[XML_MAXSIZE + 1]; + char closedelim[XML_MAXSIZE + 1]; + + memset(elem, '\0', XML_MAXSIZE + 1); + memset(cont, '\0', XML_MAXSIZE + 1); + memset(closedelim, '\0', XML_MAXSIZE + 1); + + while ((c = _xml_wfgetc(fp_in, fp_out)) != EOF) { + /* Max size */ + if (count >= XML_MAXSIZE) { + return (-1); + } + + /* Check for comments */ + if (c == _R_CONFS) { + int r = 0; + if ((r = _oswcomment(fp_in, fp_out)) < 0) { + return (-1); + } else if (r == 1) { + continue; + } + } + + /* Real checking */ + if (location == -1) { + /* Must be the opening element */ + if (c == _R_CONFS) { + if ((c = fgetc(fp_in)) == '/') { + return (-1); + } else { + ungetc(c, fp_in); + } + location = 0; + } else { + continue; + } + } + + /* Look for the closure */ + else if ((location == 0) && ((c == _R_CONFE) || (c == ' '))) { + int _ge = 0; + elem[count] = '\0'; + + /* Remove the / at the end of the element name */ + if (count > 0 && elem[count - 1] == '/') { + _ge = '/'; + elem[count - 1] = '\0'; + } + + /* If we may have more attributes */ + if (c == ' ') { + /* Write the attributes */ + while ((c = _xml_wfgetc(fp_in, fp_out)) != EOF) { + if (c == _R_CONFE) { + break; + } + } + } + + /* If the element is closed already (finished in />) */ + if (_ge == '/') { + count = 0; + location = -1; + + memset(elem, '\0', XML_MAXSIZE); + memset(closedelim, '\0', XML_MAXSIZE); + memset(cont, '\0', XML_MAXSIZE); + + if (parent > 0) { + return (ret_code); + } + } + /* Location == means we are getting the content */ + else { + count = 0; + location = 1; + } + + /* Check position of the node */ + if (node_pos > position) { + node_pos = 0; + } + + /* Check if the element name matches */ + if (node_pos == position && + nodes[node_pos] && strcmp(elem, nodes[node_pos]) == 0) { + node_pos++; + + /* Latest node, print value */ + if (!nodes[node_pos]) { + ret_code = 1; + fprintf(fp_out, "%s", val); + + while ((c = fgetc(fp_in)) != EOF) { + if (c == _R_CONFS) { + ungetc(c, fp_in); + break; + } + } + } + } + } + + else if ((location == 2) && (c == _R_CONFE)) { + closedelim[count] = '\0'; + if (strcmp(closedelim, elem) != 0) { + return (-1); + } + + memset(elem, '\0', XML_MAXSIZE); + memset(closedelim, '\0', XML_MAXSIZE); + memset(cont, '\0', XML_MAXSIZE); + + count = 0; + location = -1; + if (parent > 0) { + return (ret_code); + } + } + + /* If we are reading the element */ + else if ((location == 1) && (c == _R_CONFS)) { + if ((c = fgetc(fp_in)) == '/') { + fputc(c, fp_out); + + cont[count] = '\0'; + count = 0; + location = 2; + } else { + int wret_code; + ungetc(c, fp_in); + ungetc(_R_CONFS, fp_in); + if (fseek(fp_out, -1, SEEK_CUR)) { + return (-1); + } + + if ((wret_code = _WReadElem(fp_in, fp_out, position + 1, parent + 1, + nodes, val, node_pos)) < 0) { + return (-1); + } + + /* Set final return code */ + if (wret_code == 1) { + ret_code = 1; + } + + count = 0; + } + } else { + if (location == 0) { + elem[count++] = (char) c; + } else if (location == 1) { + cont[count++] = (char) c; + } else if (location == 2) { + closedelim[count++] = (char) c; + } + } + } + + if (location == -1) { + return (ret_code); + } + + return (-1); +} + diff --git a/src/os_zlib/os_zlib.c b/src/os_zlib/os_zlib.c new file mode 100644 index 000000000..5caf68057 --- /dev/null +++ b/src/os_zlib/os_zlib.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "os_zlib.h" + +#ifdef ZLIB_SYSTEM +#include +#else +#include "../external/zlib-1.2.11/zlib.h" +#endif + +unsigned long int os_zlib_compress(const char *src, char *dst, + unsigned long int src_size, + unsigned long int dst_size) +{ + if (compress2((Bytef *)dst, + &dst_size, + (const Bytef *)src, + src_size, + Z_BEST_COMPRESSION) == Z_OK) { + dst[dst_size] = '\0'; + return (dst_size); + } + + return (0); +} + +unsigned long int os_zlib_uncompress(const char *src, char *dst, + unsigned long int src_size, + unsigned long int dst_size) +{ + if (uncompress((Bytef *)dst, + &dst_size, + (const Bytef *)src, + src_size) == Z_OK) { + dst[dst_size] = '\0'; + return (dst_size); + } + + return (0); +} + diff --git a/src/os_zlib/os_zlib.h b/src/os_zlib/os_zlib.h new file mode 100644 index 000000000..9c3303e1f --- /dev/null +++ b/src/os_zlib/os_zlib.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __OS_ZLIB_H +#define __OS_ZLIB_H + +/* Compress a string with zlib + * src: the source string to compress + * dst: the destination buffer for the compressed string, will be + * null-terminated on success + * src_size: the length of the source string + * dst_size: the size of the destination buffer + * Returns 0 on failure, else the length of the compressed string + */ +unsigned long int os_zlib_compress(const char *src, char *dst, + unsigned long int src_size, + unsigned long int dst_size); + +/* Uncompress a string with zlib + * src: the source string to uncompress + * dst: the destination buffer for the uncompressed string, will be + * null-terminated on success + * src_size: the length of the source string + * dst_size: the size of the destination buffer + * Returns 0 on failure, else the length of the uncompressed string + */ +unsigned long int os_zlib_uncompress(const char *src, char *dst, + unsigned long int src_size, + unsigned long int dst_size); + +#endif /* __OS_ZLIB_H */ + diff --git a/src/os_zlib/zlib-test.c b/src/os_zlib/zlib-test.c new file mode 100644 index 000000000..8a132d619 --- /dev/null +++ b/src/os_zlib/zlib-test.c @@ -0,0 +1,62 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "os_zlib.h" + +#ifndef ARGV0 +#define ARGV0 "zlib-test" +#endif + + +/* Zlib test */ +int main(int argc, char **argv) +{ + unsigned long int ret, srcsize, dstsize = 2010; + char dst[2048]; + char dst2[2048]; + + memset(dst, 0, 2048); + memset(dst2, 0, 2048); + + if (argc < 2) { + printf("%s: string\n", argv[0]); + exit(1); + } + + srcsize = strlen(argv[1]); + if (srcsize > 2000) { + printf("%s: string too large\n", argv[0]); + exit(1); + + } + + if ((ret = os_zlib_compress(argv[1], dst, srcsize, dstsize))) { + printf("Compressed, from %lu->%lu\n", srcsize, ret); + } else { + printf("FAILED compressing.\n"); + exit(1); + } + + /* Set new srcsize for decompression */ + srcsize = ret; + + if ((ret = os_zlib_uncompress(dst, dst2, srcsize, dstsize))) { + printf("Uncompressed ok. String: '%s', size %lu->%lu\n", + dst2, srcsize, ret); + } else { + printf("FAILED uncompressing.\n"); + exit(1); + } + + return (0); +} diff --git a/src/remoted/COPYRIGHT b/src/remoted/COPYRIGHT new file mode 100644 index 000000000..25c69717a --- /dev/null +++ b/src/remoted/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (C) 2009 Trend Micro Inc. + All rights reserved. + This program is a free software; you can redistribute it + and/or modify it under the terms of the GNU General Public + License (version 2) as published by the FSF - Free Software + Foundation. + +openarmor, logremote. +Available at http://www.theopenarmor.org/ diff --git a/src/remoted/README b/src/remoted/README new file mode 100644 index 000000000..27886e1ba --- /dev/null +++ b/src/remoted/README @@ -0,0 +1,24 @@ +How Remoted works: + +Three daemons (forked): + +-Secured (udp port 1514) +-Syslogd (udp port 514) +-Syslogd (tcp port 514) + + +-How secured works: + +-Three threads. + +-Main thread (remote receiver). + - Receives data from remote clients. + - If the data is a log, send to analysisd. + - If data is connection related, send to the manager thread + (by save_controlmsg). +-AR_Forward (local receiver). + - Receives data (active responses) locally from analysisd. + - Forward them to the configured agent. +-Manager (sends data to remote clients). + - Waits for messages from the main thread (wait_for_msgs). + diff --git a/src/remoted/VERSION b/src/remoted/VERSION new file mode 100644 index 000000000..7e32cd569 --- /dev/null +++ b/src/remoted/VERSION @@ -0,0 +1 @@ +1.3 diff --git a/src/remoted/ar-forward.c b/src/remoted/ar-forward.c new file mode 100644 index 000000000..d04ecd700 --- /dev/null +++ b/src/remoted/ar-forward.c @@ -0,0 +1,158 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include + +#include "shared.h" +#include "remoted.h" +#include "os_net/os_net.h" + + +/* Start of a new thread. Only returns on unrecoverable errors. */ +void *AR_Forward(__attribute__((unused)) void *arg) +{ + int arq = 0; + int agent_id = 0; + int ar_location = 0; + + char msg_to_send[OS_SIZE_1024 + 1]; + + char msg[OS_SIZE_1024 + 1]; + char *location = NULL; + char *ar_location_str = NULL; + char *ar_agent_id = NULL; + char *tmp_str = NULL; + + /* Create the unix queue */ + if ((arq = StartMQ(ARQUEUE, READ)) < 0) { + ErrorExit(QUEUE_ERROR, ARGV0, ARQUEUE, strerror(errno)); + } + + memset(msg, '\0', OS_SIZE_1024 + 1); + + /* Daemon loop */ + while (1) { + if (OS_RecvUnix(arq, OS_SIZE_1024, msg)) { + /* Always zero the location */ + ar_location = 0; + + /* Get the location */ + location = msg; + + /* Location is going to be the agent name */ + tmp_str = strchr(msg, ')'); + if (!tmp_str) { + merror(EXECD_INV_MSG, ARGV0, msg); + continue; + } + *tmp_str = '\0'; + + /* Going after the ')' and space */ + tmp_str += 2; + + /* Extract the source IP */ + tmp_str = strchr(tmp_str, ' '); + if (!tmp_str) { + merror(EXECD_INV_MSG, ARGV0, msg); + continue; + } + tmp_str++; + location++; + + /* Set ar_location */ + ar_location_str = tmp_str; + if (*tmp_str == ALL_AGENTS_C) { + ar_location |= ALL_AGENTS; + } + tmp_str++; + if (*tmp_str == REMOTE_AGENT_C) { + ar_location |= REMOTE_AGENT; + } else if (*tmp_str == NO_AR_C) { + ar_location |= NO_AR_MSG; + } + tmp_str++; + if (*tmp_str == SPECIFIC_AGENT_C) { + ar_location |= SPECIFIC_AGENT; + } + + /* Extract the active response location */ + tmp_str = strchr(ar_location_str, ' '); + if (!tmp_str) { + merror(EXECD_INV_MSG, ARGV0, msg); + continue; + } + *tmp_str = '\0'; + tmp_str++; + + /* Extract the agent id */ + ar_agent_id = tmp_str; + tmp_str = strchr(tmp_str, ' '); + if (!tmp_str) { + merror(EXECD_INV_MSG, ARGV0, msg); + continue; + } + *tmp_str = '\0'; + tmp_str++; + + /* Create the new message */ + if (ar_location & NO_AR_MSG) { + snprintf(msg_to_send, OS_SIZE_1024, "%s%s", + CONTROL_HEADER, + tmp_str); + } else { + snprintf(msg_to_send, OS_SIZE_1024, "%s%s%s", + CONTROL_HEADER, + EXECD_HEADER, + tmp_str); + } + + /* Lock use of keys */ + key_lock(); + + /* Send to ALL agents */ + if (ar_location & ALL_AGENTS) { + unsigned int i; + for (i = 0; i < keys.keysize; i++) { + send_msg(i, msg_to_send); + } + } + + /* Send to the remote agent that generated the event */ + else if ((ar_location & REMOTE_AGENT) && (location != NULL)) { + agent_id = OS_IsAllowedName(&keys, location); + if (agent_id < 0) { + key_unlock(); + merror(AR_NOAGENT_ERROR, ARGV0, location); + continue; + } + + send_msg((unsigned)agent_id, msg_to_send); + } + + /* Send to a pre-defined agent */ + else if (ar_location & SPECIFIC_AGENT) { + ar_location++; + + agent_id = OS_IsAllowedID(&keys, ar_agent_id); + + if (agent_id < 0) { + key_unlock(); + merror(AR_NOAGENT_ERROR, ARGV0, ar_agent_id); + continue; + } + + send_msg((unsigned)agent_id, msg_to_send); + } + + /* Lock use of keys */ + key_unlock(); + } + } +} + diff --git a/src/remoted/config.c b/src/remoted/config.c new file mode 100644 index 000000000..02606b074 --- /dev/null +++ b/src/remoted/config.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_xml/os_xml.h" +#include "os_regex/os_regex.h" +#include "os_net/os_net.h" +#include "remoted.h" +#include "config/config.h" + + +/* Read the config file (the remote access) */ +int RemotedConfig(const char *cfgfile, remoted *cfg) +{ + int modules = 0; + + modules |= CREMOTE; + + cfg->port = NULL; + cfg->conn = NULL; + cfg->allowips = NULL; + cfg->denyips = NULL; + + if (ReadConfig(modules, cfgfile, cfg, NULL) < 0) { + return (OS_INVALID); + } + + return (1); +} + diff --git a/src/remoted/main.c b/src/remoted/main.c new file mode 100644 index 000000000..65900a729 --- /dev/null +++ b/src/remoted/main.c @@ -0,0 +1,189 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "remoted.h" + +/* Prototypes */ +static void help_remoted(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_remoted() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -u User to run as (default: %s)", REMUSER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int i = 0, c = 0; + uid_t uid; + gid_t gid; + int debug_level = 0; + int test_config = 0, run_foreground = 0; + + const char *cfg = DEFAULTCPATH; + const char *dir = DEFAULTDIR; + const char *user = REMUSER; + const char *group = GROUPGLOBAL; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vdthfu:g:c:D:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_remoted(); + break; + case 'd': + nowDebug(); + debug_level = 1; + break; + case 'f': + run_foreground = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 't': + test_config = 1; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c need an argument", ARGV0); + } + cfg = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + default: + help_remoted(); + break; + } + } + + /* Check current debug_level + * Command line setting takes precedence + */ + if (debug_level == 0) { + /* Get debug level */ + debug_level = getDefine_Int("remoted", "debug", 0, 2); + while (debug_level != 0) { + nowDebug(); + debug_level--; + } + } + + debug1(STARTED_MSG, ARGV0); + + /* Return 0 if not configured */ + if (RemotedConfig(cfg, &logr) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Exit if test_config is set */ + if (test_config) { + exit(0); + } + + if (logr.conn == NULL) { + /* Not configured */ + exit(0); + } + + /* Don't exit when client.keys empty (if set) */ + if (getDefine_Int("remoted", "pass_empty_keyfile", 0, 1)) { + OS_PassEmptyKeyfile(); + } + + + /* Check if the user and group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Setup random */ + srandom_init(); + + /* pid before going daemon */ + i = getpid(); + + if (!run_foreground) { + nowDaemon(); + goDaemon(); + } + + /* Set new group */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + + /* Start the signal manipulation */ + StartSIG(ARGV0); + + random(); + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* Really start the program */ + i = 0; + while (logr.conn[i] != 0) { + /* Fork for each connection handler */ + if (fork() == 0) { + /* On the child */ + debug1("%s: DEBUG: Forking remoted: '%d'.", ARGV0, i); + HandleRemote(i, uid); + } else { + i++; + continue; + } + } + + return (0); +} + diff --git a/src/remoted/manager.c b/src/remoted/manager.c new file mode 100644 index 000000000..e594ddc2b --- /dev/null +++ b/src/remoted/manager.c @@ -0,0 +1,543 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "remoted.h" +#include "os_crypto/md5/md5_op.h" +#include "os_net/os_net.h" +#include + +/* Internal structures */ +typedef struct _file_sum { + int mark; + char *name; + os_md5 sum; +} file_sum; + +/* Internal functions prototypes */ +static void read_controlmsg(unsigned int agentid, char *msg); +static int send_file_toagent(unsigned int agentid, const char *name, const char *sum); +static void f_files(void); +static void c_files(void); + +/* Global vars */ +static file_sum **f_sum; +static time_t _ctime; +static time_t _stime; + +/* For the last message tracking */ +static char *_msg[MAX_AGENTS + 1]; +static char *_keep_alive[MAX_AGENTS + 1]; +static int _changed[MAX_AGENTS + 1]; +static int modified_agentid; + +/* pthread mutex variables */ +static pthread_mutex_t lastmsg_mutex; +static pthread_cond_t awake_mutex; + + +/* Save a control message received from an agent + * read_controlmsg (other thread) is going to deal with it + * (only if message changed) + */ +void save_controlmsg(unsigned int agentid, char *r_msg) +{ + char msg_ack[OS_FLSIZE + 1]; + + /* Reply to the agent */ + snprintf(msg_ack, OS_FLSIZE, "%s%s", CONTROL_HEADER, HC_ACK); + send_msg(agentid, msg_ack); + + /* Check if there is a keep alive already for this agent */ + if (_keep_alive[agentid] && _msg[agentid] && + (strcmp(_msg[agentid], r_msg) == 0)) { + utimes(_keep_alive[agentid], NULL); + } + + else if (strcmp(r_msg, HC_STARTUP) == 0) { + return; + } + + else { + FILE *fp; + char *uname = r_msg; + char *random_leftovers; + + /* Lock mutex */ + if (pthread_mutex_lock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return; + } + + /* Update rmsg */ + if (_msg[agentid]) { + free(_msg[agentid]); + } + os_strdup(r_msg, _msg[agentid]); + + /* Unlock mutex */ + if (pthread_mutex_unlock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return; + } + + r_msg = strchr(r_msg, '\n'); + if (!r_msg) { + merror("%s: WARN: Invalid message from agent id: '%d'(uname)", + ARGV0, + agentid); + return; + } + + *r_msg = '\0'; + random_leftovers = strchr(r_msg, '\n'); + if (random_leftovers) { + *random_leftovers = '\0'; + } + + /* Update the keep alive */ + if (!_keep_alive[agentid]) { + char agent_file[OS_SIZE_1024 + 1]; + agent_file[OS_SIZE_1024] = '\0'; + + /* Write to the agent file */ + snprintf(agent_file, OS_SIZE_1024, "%s/%s-%s", + AGENTINFO_DIR, + keys.keyentries[agentid]->name, + keys.keyentries[agentid]->ip->ip); + os_strdup(agent_file, _keep_alive[agentid]); + } + + /* Write to the file */ + fp = fopen(_keep_alive[agentid], "w"); + if (fp) { + fprintf(fp, "%s\n", uname); + fclose(fp); + } else { + merror("openarmor-remoted: ERROR: Could not open %s: %s", _keep_alive[agentid], strerror(errno)); + } + } + + /* Lock now to notify of change */ + if (pthread_mutex_lock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return; + } + + /* Assign new values */ + _changed[agentid] = 1; + modified_agentid = (int) agentid; + + /* Signal that new data is available */ + pthread_cond_signal(&awake_mutex); + + /* Unlock mutex */ + if (pthread_mutex_unlock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return; + } + + return; +} + +/* Free the files memory */ +static void f_files() +{ + int i; + if (!f_sum) { + return; + } + for (i = 0;; i++) { + if (f_sum[i] == NULL) { + break; + } + + if (f_sum[i]->name) { + free(f_sum[i]->name); + } + + free(f_sum[i]); + f_sum[i] = NULL; + } + + free(f_sum); + f_sum = NULL; +} + +/* Create the structure with the files and checksums */ +static void c_files() +{ + DIR *dp; + struct dirent *entry; + os_md5 md5sum; + unsigned int f_size = 0; + + f_sum = NULL; + + /* Create merged file */ + os_realloc(f_sum, (f_size + 2) * sizeof(file_sum *), f_sum); + os_calloc(1, sizeof(file_sum), f_sum[f_size]); + f_sum[f_size]->mark = 0; + f_sum[f_size]->name = NULL; + f_sum[f_size]->sum[0] = '\0'; + MergeAppendFile(SHAREDCFG_FILE, NULL); + f_size++; + + /* Open directory */ + dp = opendir(SHAREDCFG_DIR); + if (!dp) { + merror("%s: Error opening directory: '%s': %s ", + ARGV0, + SHAREDCFG_DIR, + strerror(errno)); + return; + } + + /* Read directory */ + while ((entry = readdir(dp)) != NULL) { + char tmp_dir[512]; + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + snprintf(tmp_dir, 512, "%s/%s", SHAREDCFG_DIR, entry->d_name); + + /* Leave the shared config file for later */ + if (strcmp(tmp_dir, SHAREDCFG_FILE) == 0) { + continue; + } + + if (OS_MD5_File(tmp_dir, md5sum, OS_TEXT) != 0) { + merror("%s: Error accessing file '%s'", ARGV0, tmp_dir); + continue; + } + + f_sum = (file_sum **)realloc(f_sum, (f_size + 2) * sizeof(file_sum *)); + if (!f_sum) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + f_sum[f_size] = (file_sum *) calloc(1, sizeof(file_sum)); + if (!f_sum[f_size]) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + + strncpy(f_sum[f_size]->sum, md5sum, 32); + os_strdup(entry->d_name, f_sum[f_size]->name); + f_sum[f_size]->mark = 0; + + MergeAppendFile(SHAREDCFG_FILE, tmp_dir); + f_size++; + } + + if (f_sum != NULL) { + f_sum[f_size] = NULL; + } + + closedir(dp); + + if (OS_MD5_File(SHAREDCFG_FILE, md5sum, OS_TEXT) != 0) { + merror("%s: Error accessing file '%s'", ARGV0, SHAREDCFG_FILE); + f_sum[0]->sum[0] = '\0'; + } + strncpy(f_sum[0]->sum, md5sum, 32); + + os_strdup(SHAREDCFG_FILENAME, f_sum[0]->name); + + return; +} + +/* Send a file to the agent + * Returns -1 on error + */ +static int send_file_toagent(unsigned int agentid, const char *name, const char *sum) +{ + int i = 0; + size_t n = 0; + char file[OS_SIZE_1024 + 1]; + char buf[OS_SIZE_1024 + 1]; + FILE *fp; + + snprintf(file, OS_SIZE_1024, "%s/%s", SHAREDCFG_DIR, name); + fp = fopen(file, "r"); + if (!fp) { + merror(FOPEN_ERROR, ARGV0, file, errno, strerror(errno)); + return (-1); + } + + /* Send the file name first */ + snprintf(buf, OS_SIZE_1024, "%s%s%s %s\n", + CONTROL_HEADER, FILE_UPDATE_HEADER, sum, name); + if (send_msg(agentid, buf) == -1) { + merror(SEC_ERROR, ARGV0); + fclose(fp); + return (-1); + } + + /* Send the file contents */ + while ((n = fread(buf, 1, 900, fp)) > 0) { + buf[n] = '\0'; + + if (send_msg(agentid, buf) == -1) { + merror(SEC_ERROR, ARGV0); + fclose(fp); + return (-1); + } + + /* Sleep 1 every 30 messages -- no flood */ + if (i > 30) { + sleep(1); + i = 0; + } + i++; + } + + /* Send the message to close the file */ + snprintf(buf, OS_SIZE_1024, "%s%s", CONTROL_HEADER, FILE_CLOSE_HEADER); + if (send_msg(agentid, buf) == -1) { + merror(SEC_ERROR, ARGV0); + fclose(fp); + return (-1); + } + + fclose(fp); + + return (0); +} + +/* Read the available control message from the agent */ +static void read_controlmsg(unsigned int agentid, char *msg) +{ + int i; + + /* Remove uname */ + msg = strchr(msg, '\n'); + if (!msg) { + merror("%s: Invalid message from '%d' (uname)", ARGV0, agentid); + return; + } + + *msg = '\0'; + msg++; + + if (!f_sum) { + /* Nothing to share with agent */ + return; + } + + /* Parse message */ + while (*msg != '\0') { + char *md5; + char *file; + + md5 = msg; + file = msg; + + msg = strchr(msg, '\n'); + if (!msg) { + merror("%s: Invalid message from '%s' (strchr \\n)", + ARGV0, + keys.keyentries[agentid]->ip->ip); + break; + } + + *msg = '\0'; + msg++; + + file = strchr(file, ' '); + if (!file) { + merror("%s: Invalid message from '%s' (strchr ' ')", + ARGV0, + keys.keyentries[agentid]->ip->ip); + break; + } + + *file = '\0'; + file++; + + /* New agents only have merged.mg */ + if (strcmp(file, SHAREDCFG_FILENAME) == 0) { + if (strcmp(f_sum[0]->sum, md5) != 0) { + debug1("%s: DEBUG Sending file '%s' to agent.", ARGV0, + f_sum[0]->name); + if (send_file_toagent(agentid, f_sum[0]->name, f_sum[0]->sum) < 0) { + merror("%s: ERROR: Unable to send file '%s' to agent.", + ARGV0, + f_sum[0]->name); + } + } + + i = 0; + while (f_sum[i]) { + f_sum[i]->mark = 0; + i++; + } + + return; + } + + for (i = 1;; i++) { + if (f_sum[i] == NULL) { + break; + } + + else if (strcmp(f_sum[i]->name, file) != 0) { + continue; + } + + else if (strcmp(f_sum[i]->sum, md5) != 0) { + f_sum[i]->mark = 1; /* Marked to update */ + } + + else { + f_sum[i]->mark = 2; + } + break; + } + } + + /* Update each marked file */ + for (i = 1;; i++) { + if (f_sum[i] == NULL) { + break; + } + + if ((f_sum[i]->mark == 1) || + (f_sum[i]->mark == 0)) { + + debug1("%s: Sending file '%s' to agent.", ARGV0, f_sum[i]->name); + if (send_file_toagent(agentid, f_sum[i]->name, f_sum[i]->sum) < 0) { + merror("%s: Error sending file '%s' to agent.", + ARGV0, + f_sum[i]->name); + } + } + + f_sum[i]->mark = 0; + } + + return; +} + +/* Wait for new messages to read + * The messages will be sent using save_controlmsg + */ +void *wait_for_msgs(__attribute__((unused)) void *none) +{ + int id; + char msg[OS_SIZE_1024 + 2]; + + /* Initialize the memory */ + memset(msg, '\0', OS_SIZE_1024 + 2); + + /* Should never leave this loop */ + while (1) { + unsigned int i; + /* Every NOTIFY * 30 minutes, re-read the files + * If something changed, notify all agents + */ + _ctime = time(0); + if ((_ctime - _stime) > (NOTIFY_TIME * 30)) { + f_files(); + c_files(); + + _stime = _ctime; + } + + /* Lock mutex */ + if (pthread_mutex_lock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return (NULL); + } + + /* If no agent changed, wait for signal */ + if (modified_agentid == -1) { + pthread_cond_wait(&awake_mutex, &lastmsg_mutex); + } + + /* Unlock mutex */ + if (pthread_mutex_unlock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return (NULL); + } + + /* Check if any agent is ready */ + for (i = 0; i < keys.keysize; i++) { + /* If agent wasn't changed, try next */ + if (_changed[i] != 1) { + continue; + } + + id = 0; + + /* Lock mutex */ + if (pthread_mutex_lock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + break; + } + + if (_msg[i]) { + /* Copy the message to be analyzed */ + strncpy(msg, _msg[i], OS_SIZE_1024); + _changed[i] = 0; + + if (modified_agentid >= (int) i) { + modified_agentid = -1; + } + + id = 1; + } + + /* Unlock mutex */ + if (pthread_mutex_unlock(&lastmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + break; + } + + if (id) { + read_controlmsg(i, msg); + } + } + } + + return (NULL); +} + +/* Should be called before anything here */ +void manager_init(int isUpdate) +{ + int i; + + _stime = time(0); + + f_files(); + c_files(); + + debug1("%s: DEBUG: Running manager_init", ARGV0); + + modified_agentid = -1; + + for (i = 0; i < MAX_AGENTS + 1; i++) { + _keep_alive[i] = NULL; + _msg[i] = NULL; + _changed[i] = 0; + } + + /* Initialize mutexes */ + if (isUpdate == 0) { + pthread_mutex_init(&lastmsg_mutex, NULL); + pthread_cond_init(&awake_mutex, NULL); + } + + return; +} + diff --git a/src/remoted/remoted.c b/src/remoted/remoted.c new file mode 100644 index 000000000..dd6cd1a01 --- /dev/null +++ b/src/remoted/remoted.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* remote daemon + * Listen to remote packets and forward them to the analysis system + */ + +#include "shared.h" +#include "os_net/os_net.h" +#include "remoted.h" + +/* Global variables */ +keystore keys; +remoted logr; + + +/* Handle remote connections */ +void HandleRemote(int position, int uid) +{ + /* If syslog connection and allowips is not defined, exit */ + if (logr.conn[position] == SYSLOG_CONN) { + if (logr.allowips == NULL) { + ErrorExit(NO_SYSLOG, ARGV0); + } else { + os_ip **tmp_ips; + + tmp_ips = logr.allowips; + while (*tmp_ips) { + verbose("%s: Remote syslog allowed from: '%s'", + ARGV0, (*tmp_ips)->ip); + tmp_ips++; + } + } + } + + /* Bind TCP */ + if (logr.proto[position] == IPPROTO_TCP) { + logr.sock = 0; + logr.netinfo = OS_Bindporttcp(logr.port[position], logr.lip[position]); + if (logr.netinfo->status < 0) { + ErrorExit(BIND_ERROR, ARGV0, logr.port[position]); + } + } else { + /* Using UDP. Fast, unreliable... perfect */ + logr.sock = 0; + logr.netinfo = OS_Bindportudp(logr.port[position], logr.lip[position]); + if (logr.netinfo->status < 0) { + ErrorExit(BIND_ERROR, ARGV0, logr.port[position]); + } + } + + /* Revoke privileges */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, REMUSER, errno, strerror(errno)); + } + + /* Create PID */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* If secure connection, deal with it */ + if (logr.conn[position] == SECURE_CONN) { + HandleSecure(); + } + + else if (logr.proto[position] == IPPROTO_TCP) + { + HandleSyslogTCP(); + } + + /* If not, deal with syslog */ + else { + HandleSyslog(); + } +} + diff --git a/src/remoted/remoted.h b/src/remoted/remoted.h new file mode 100644 index 000000000..527d9dbd3 --- /dev/null +++ b/src/remoted/remoted.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __LOGREMOTE_H +#define __LOGREMOTE_H + +#ifndef ARGV0 +#define ARGV0 "openarmor-remoted" +#endif + +#include "config/remote-config.h" +#include "sec.h" + +/** Function prototypes **/ + +/* Read remoted config */ +int RemotedConfig(const char *cfgfile, remoted *cfg); + +/* Handle Remote connections */ +void HandleRemote(int position, int uid) __attribute__((noreturn)); + +/* Handle Syslog */ +void HandleSyslog(void) __attribute__((noreturn)); + +/* Handle Syslog TCP */ +void HandleSyslogTCP(void) __attribute__((noreturn)); + +/* Handle Secure connections */ +void HandleSecure(void) __attribute__((noreturn)); + +/* Forward active response events */ +void *AR_Forward(void *arg) __attribute__((noreturn)); + +/* Initialize the manager */ +void manager_init(int isUpdate); + +/* Wait for messages from the agent to analyze */ +void *wait_for_msgs(void *none); + +/* Save control messages */ +void save_controlmsg(unsigned int agentid, char *msg); + +/* Send message to agent */ +int send_msg(unsigned int agentid, const char *msg); + +/* Initializing send_msg */ +void send_msg_init(void); + +int check_keyupdate(void); + +void key_lock(void); + +void key_unlock(void); + +void keyupdate_init(void); + +/** Global variables **/ + +extern keystore keys; +extern remoted logr; + +#endif /* __LOGREMOTE_H */ diff --git a/src/remoted/secure.c b/src/remoted/secure.c new file mode 100644 index 000000000..861bfbae1 --- /dev/null +++ b/src/remoted/secure.c @@ -0,0 +1,208 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_net/os_net.h" +#include "remoted.h" + + +/* Handle secure connections */ +void HandleSecure() +{ + int agentid; + char buffer[OS_MAXSTR + 1]; + char cleartext_msg[OS_MAXSTR + 1]; + char srcip[IPSIZE + 1]; + char *tmp_msg; + char srcmsg[OS_FLSIZE + 1]; + ssize_t recv_b; + struct sockaddr_storage peer_info; + socklen_t peer_size; + fd_set fdsave, fdwork; /* select() work areas */ + int fdmax; /* max socket number + 1 */ + int sock; /* active socket */ + + /* Send msg init */ + send_msg_init(); + + /* Initialize key mutex */ + keyupdate_init(); + + /* Initialize manager */ + manager_init(0); + + /* Create Active Response forwarder thread */ + if (CreateThread(AR_Forward, (void *)NULL) != 0) { + ErrorExit(THREAD_ERROR, ARGV0); + } + + /* Create wait_for_msgs thread */ + if (CreateThread(wait_for_msgs, (void *)NULL) != 0) { + ErrorExit(THREAD_ERROR, ARGV0); + } + + /* + * Connect to the message queue + * Exit if it fails. + */ + if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + + verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS); + + /* Read authentication keys */ + verbose(ENC_READ, ARGV0); + + OS_ReadKeys(&keys); + + debug1("%s: DEBUG: OS_StartCounter.", ARGV0); + OS_StartCounter(&keys); + debug1("%s: DEBUG: OS_StartCounter completed.", ARGV0); + + /* Set up peer size */ + peer_size = sizeof(peer_info); + logr.peer_size = sizeof(peer_info); + + /* Initialize some variables */ + memset(buffer, '\0', OS_MAXSTR + 1); + memset(cleartext_msg, '\0', OS_MAXSTR + 1); + memset(srcmsg, '\0', OS_FLSIZE + 1); + tmp_msg = NULL; + + /* initialize select() save area */ + fdsave = logr.netinfo->fdset; + fdmax = logr.netinfo->fdmax; /* value preset to max fd + 1 */ + + while (1) { + /* process connections through select() for multiple sockets */ + fdwork = fdsave; + if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) { + ErrorExit("ERROR: Call to secure select() failed, errno %d - %s", + errno, strerror (errno)); + } + + /* read through socket list for active socket */ + for (sock = 0; sock <= fdmax; sock++) { + if (FD_ISSET (sock, &fdwork)) { + + /* Receive message */ + recv_b = recvfrom(sock, buffer, OS_MAXSTR, 0, + (struct sockaddr *)&peer_info, &peer_size); + + /* Nothing received */ + if (recv_b <= 0) { + continue; + } + + /* + * send_msg() needs a socket, but we don't know which + * socket is active until we receive our first packet. + * This sets the socket for send_msg(). + */ + + logr.sock = sock; + + /* Set the source IP */ + satop((struct sockaddr *) &peer_info, srcip, IPSIZE); + srcip[IPSIZE] = '\0'; + + /* Get a valid agent id */ + if (buffer[0] == '!') { + tmp_msg = buffer; + tmp_msg++; + + /* + * We need to make sure that we have a valid id + * and that we reduce the recv buffer size + */ + while (isdigit((int)*tmp_msg)) { + tmp_msg++; + recv_b--; + } + + if (*tmp_msg != '!') { + merror(ENCFORMAT_ERROR, __local_name, srcip); + continue; + } + + *tmp_msg = '\0'; + tmp_msg++; + recv_b -= 2; + + agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip); + if (agentid == -1) { + if (check_keyupdate()) { + agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip); + if (agentid == -1) { + merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip); + continue; + } + } else { + merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip); + continue; + } + } + } else { + agentid = OS_IsAllowedIP(&keys, srcip); + if (agentid < 0) { + if (check_keyupdate()) { + agentid = OS_IsAllowedIP(&keys, srcip); + if (agentid == -1) { + merror(DENYIP_WARN, ARGV0, srcip); + continue; + } + } else { + merror(DENYIP_WARN, ARGV0, srcip); + continue; + } + } + tmp_msg = buffer; + } + + /* Decrypt the message */ + tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg, + agentid, recv_b - 1); + if (tmp_msg == NULL) { + /* If duplicated, a warning was already generated */ + continue; + } + + /* Check if it is a control message */ + if (IsValidHeader(tmp_msg)) { + /* We need to save the peerinfo if it is a control msg */ + memcpy(&keys.keyentries[agentid]->peer_info, + &peer_info, peer_size); + keys.keyentries[agentid]->rcvd = time(0); + save_controlmsg((unsigned)agentid, tmp_msg); + continue; + } + + /* Generate srcmsg */ + snprintf(srcmsg, OS_FLSIZE, "(%s) %s", + keys.keyentries[agentid]->name, + keys.keyentries[agentid]->ip->ip); + + /* + * If we can't send the message, try to connect to the + * socket again. If it fails exit. + */ + if (SendMSG(logr.m_queue, tmp_msg, srcmsg, + SECURE_MQ) < 0) { + merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); + + if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + } + } /* if socket active */ + } /* for() loop on sockets */ + } /* while(1) loop for messages */ +} + diff --git a/src/remoted/sendmsg.c b/src/remoted/sendmsg.c new file mode 100644 index 000000000..f4d8bb271 --- /dev/null +++ b/src/remoted/sendmsg.c @@ -0,0 +1,158 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include + +#include "shared.h" +#include "remoted.h" +#include "os_net/os_net.h" + +/* pthread send_msg mutex */ +static pthread_mutex_t sendmsg_mutex; + +/* pthread key update mutex */ +static pthread_mutex_t keyupdate_mutex; + + +/* Initializes mutex */ +void keyupdate_init() +{ + /* Initialize mutex */ + pthread_mutex_init(&keyupdate_mutex, NULL); +} + +void key_lock() +{ + if (pthread_mutex_lock(&keyupdate_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + } +} + +void key_unlock() +{ + if (pthread_mutex_unlock(&keyupdate_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + } +} + +/* Check for key updates */ +int check_keyupdate() +{ + /* Check key for updates */ + if (!OS_CheckUpdateKeys(&keys)) { + return (0); + } + + key_lock(); + + /* Lock before using */ + if (pthread_mutex_lock(&sendmsg_mutex) != 0) { + key_unlock(); + merror(MUTEX_ERROR, ARGV0); + return (0); + } + + if (OS_UpdateKeys(&keys)) { + if (pthread_mutex_unlock(&sendmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + } + key_unlock(); + return (1); + } + + if (pthread_mutex_unlock(&sendmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + } + key_unlock(); + + return (0); +} + +/* Initialize send_msg */ +void send_msg_init() +{ + /* Initialize mutex */ + pthread_mutex_init(&sendmsg_mutex, NULL); +} + + +/* + * Send message to an agent + * Returns -1 on error + */ + +int send_msg(unsigned int agentid, const char *msg) +{ + size_t msg_size, sa_size; + char crypt_msg[OS_MAXSTR + 1]; + struct sockaddr * dest_sa; + + /* If we don't have the agent id, ignore it */ + if (keys.keyentries[agentid]->rcvd < (time(0) - (2 * NOTIFY_TIME))) { + return (-1); + } + + /* Lock before using */ + if (pthread_mutex_lock(&sendmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return (-1); + } + + msg_size = CreateSecMSG(&keys, msg, crypt_msg, agentid); + if (msg_size == 0) { + merror(SEC_ERROR, ARGV0); + return (-1); + } + + /* Send initial message */ + dest_sa = (struct sockaddr *)&keys.keyentries[agentid]->peer_info; + sa_size = (dest_sa->sa_family == AF_INET) ? + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + + /* + * Because we handle multiple IP addresses, we won't know what interfaces + * are active for network communication until we receive something on one + * of them. This is a work around in the event we need to send before + * we have identified the working interface in secure.c. (dgs - 2/26/18) + */ + + if (logr.sock == 0) { + int i, ok = 0; + + /* socket not established - try current sockets */ + for (i = 0; i < logr.netinfo->fdcnt; i++) { + if (sendto(logr.netinfo->fds[i], crypt_msg, msg_size, 0, + dest_sa, sa_size) < 0) { + continue; + } + + ok = 1; + break; + } + + /* if we tried all the sockets and noe of them worked, send an error */ + if (ok == 0) { + merror(SEND_ERROR, ARGV0, keys.keyentries[agentid]->id); + } + } else { + /* working socket identified in secure.c */ + if (sendto(logr.sock, crypt_msg, msg_size, 0, dest_sa, sa_size) < 0) { + merror(SEND_ERROR, ARGV0, keys.keyentries[agentid]->id); + } + } + + /* Unlock mutex */ + if (pthread_mutex_unlock(&sendmsg_mutex) != 0) { + merror(MUTEX_ERROR, ARGV0); + return (-1); + } + + return (0); +} + diff --git a/src/remoted/syslog.c b/src/remoted/syslog.c new file mode 100644 index 000000000..d581bfd43 --- /dev/null +++ b/src/remoted/syslog.c @@ -0,0 +1,129 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_net/os_net.h" +#include "remoted.h" + +/* Prototypes */ +static int OS_IPNotAllowed(const char *srcip); + + +/* Check if an IP is not allowed */ +static int OS_IPNotAllowed(const char *srcip) +{ + if (logr.denyips != NULL) { + if (OS_IPFoundList(srcip, logr.denyips)) { + return (1); + } + } + if (logr.allowips != NULL) { + if (OS_IPFoundList(srcip, logr.allowips)) { + return (0); + } + } + + /* If the IP is not allowed, it will be denied */ + return (1); +} + +/* Handle syslog connections */ +void HandleSyslog() +{ + char buffer[OS_SIZE_1024 + 2]; + char srcip[IPSIZE + 1]; + char *buffer_pt = NULL; + ssize_t recv_b; + struct sockaddr_storage peer_info; + socklen_t peer_size; + fd_set fdsave, fdwork; /* select() work areas */ + int fdmax; /* max socket number + 1 */ + int sock; /* active socket */ + + /* Set peer size */ + peer_size = sizeof(peer_info); + + /* Initialize some variables */ + memset(buffer, '\0', OS_SIZE_1024 + 2); + + /* initialize select() save area */ + fdsave = logr.netinfo->fdset; + fdmax = logr.netinfo->fdmax; /* value preset to max fd + 1 */ + + /* Connect to the message queue + * Exit if it fails. + */ + if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + + /* Infinite loop */ + while (1) { + /* process connections through select() for multiple sockets */ + fdwork = fdsave; + if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) { + ErrorExit("ERROR: Call to syslog select() failed, errno %d - %s", + errno, strerror (errno)); + } + + /* read through socket list for active socket */ + for (sock = 0; sock <= fdmax; sock++) { + if (FD_ISSET (sock, &fdwork)) { + + /* Receive message */ + recv_b = recvfrom(sock, buffer, OS_SIZE_1024, 0, + (struct sockaddr *)&peer_info, &peer_size); + + /* Nothing received */ + if (recv_b <= 0) { + continue; + } + + /* Null-terminate the message */ + buffer[recv_b] = '\0'; + + /* Remove newline */ + if (buffer[recv_b - 1] == '\n') { + buffer[recv_b - 1] = '\0'; + } + + /* Set the source IP */ + satop((struct sockaddr *) &peer_info, srcip, IPSIZE); + srcip[IPSIZE] = '\0'; + + /* Remove syslog header */ + if (buffer[0] == '<') { + buffer_pt = strchr(buffer + 1, '>'); + if (buffer_pt) { + buffer_pt++; + } else { + buffer_pt = buffer; + } + } else { + buffer_pt = buffer; + } + + /* Check if IP is allowed here */ + if (OS_IPNotAllowed(srcip)) { + merror(DENYIP_WARN, ARGV0, srcip); + continue; + } + + if (SendMSG(logr.m_queue, buffer_pt, srcip, SYSLOG_MQ) < 0) { + merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); + + if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + } + } /* if socket active */ + } /* for() loop on sockets */ + } /* while(1) loop for messages */ +} + diff --git a/src/remoted/syslogtcp.c b/src/remoted/syslogtcp.c new file mode 100644 index 000000000..f7d8d1d46 --- /dev/null +++ b/src/remoted/syslogtcp.c @@ -0,0 +1,219 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_net/os_net.h" +#include "remoted.h" + + +/* Checks if an IP is not allowed */ +static int OS_IPNotAllowed(char *srcip) +{ + if (logr.denyips != NULL) { + if (OS_IPFoundList(srcip, logr.denyips)) { + return (1); + } + } + if (logr.allowips != NULL) { + if (OS_IPFoundList(srcip, logr.allowips)) { + return (0); + } + } + + /* If the IP is not allowed, it will be denied */ + return (1); +} + +/* Handle each client */ +static void HandleClient(int client_socket, char *srcip) +{ + int sb_size = OS_MAXSTR; + int r_sz = 0; + + char buffer[OS_MAXSTR + 2]; + char storage_buffer[OS_MAXSTR + 2]; + char tmp_buffer[OS_MAXSTR + 2]; + + char *buffer_pt = NULL; + + /* Create PID file */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Initialize some variables */ + memset(buffer, '\0', OS_MAXSTR + 2); + memset(storage_buffer, '\0', OS_MAXSTR + 2); + memset(tmp_buffer, '\0', OS_MAXSTR + 2); + + + while (1) { + /* If we fail, we need to return and close the socket */ + if ((r_sz = OS_RecvTCPBuffer(client_socket, buffer, OS_MAXSTR - 2)) < 0) { + close(client_socket); + DeletePID(ARGV0); + return; + } + + /* We must have a new line at the end */ + buffer_pt = strchr(buffer, '\n'); + if (!buffer_pt) { + /* Buffer is full */ + if ((sb_size - r_sz) <= 2) { + merror("%s: Full buffer receiving from: '%s'", ARGV0, srcip); + sb_size = OS_MAXSTR; + storage_buffer[0] = '\0'; + continue; + } + + strncat(storage_buffer, buffer, sb_size); + sb_size -= r_sz; + continue; + } + + /* See if we received more than just one message */ + if (*(buffer_pt + 1) != '\0') { + *buffer_pt = '\0'; + buffer_pt++; + strncpy(tmp_buffer, buffer_pt, OS_MAXSTR); + } + + /* Store everything in the storage_buffer + * Check if buffer will be full + */ + if ((sb_size - r_sz) <= 2) { + merror("%s: Full buffer receiving from: '%s'.", ARGV0, srcip); + sb_size = OS_MAXSTR; + storage_buffer[0] = '\0'; + tmp_buffer[0] = '\0'; + continue; + } + + strncat(storage_buffer, buffer, sb_size); + + /* Remove carriage returns too */ + buffer_pt = strchr(storage_buffer, '\r'); + if (buffer_pt) { + *buffer_pt = '\0'; + } + + /* Remove syslog header */ + if (storage_buffer[0] == '<') { + buffer_pt = strchr(storage_buffer + 1, '>'); + if (buffer_pt) { + buffer_pt++; + } else { + buffer_pt = storage_buffer; + } + } else { + buffer_pt = storage_buffer; + } + + /* Send to the queue */ + if (SendMSG(logr.m_queue, buffer_pt, srcip, SYSLOG_MQ) < 0) { + merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); + + if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + } + + /* Clean up the buffers */ + if (tmp_buffer[0] != '\0') { + strncpy(storage_buffer, tmp_buffer, OS_MAXSTR); + sb_size = OS_MAXSTR - (strlen(storage_buffer) + 1); + tmp_buffer[0] = '\0'; + } else { + storage_buffer[0] = '\0'; + sb_size = OS_MAXSTR; + } + } +} + +/* Handle syslog TCP connections */ +void HandleSyslogTCP() +{ + int childcount = 0; + char srcip[IPSIZE + 1]; + fd_set fdsave, fdwork; /* select() work areas */ + int fdmax; /* max socket number + 1 */ + int sock; /* active socket */ + + /* Initialize some variables */ + memset(srcip, '\0', IPSIZE + 1); + + /* initialize select() save area */ + fdsave = logr.netinfo->fdset; + fdmax = logr.netinfo->fdmax; /* value preset to max fd + 1 */ + + /* Connecting to the message queue + * Exit if it fails. + */ + if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); + } + + while (1) { + /* Wait for the children */ + while (childcount) { + int wp; + wp = waitpid((pid_t) - 1, NULL, WNOHANG); + if (wp < 0) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + } + + /* if = 0, we still need to wait for the child process */ + else if (wp == 0) { + break; + } else { + childcount--; + } + } + + /* process connections through select() for multiple sockets */ + fdwork = fdsave; + if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) { + ErrorExit("ERROR: Call to syslogtcp select() failed, errno %d - %s", + errno, strerror (errno)); + } + + /* read through socket list for active socket */ + for (sock = 0; sock <= fdmax; sock++) { + if (FD_ISSET (sock, &fdwork)) { + + /* Accept new connections */ + int client_socket = OS_AcceptTCP(sock, srcip, IPSIZE); + if (client_socket < 0) { + merror("%s: WARN: Accepting tcp connection from client failed.", ARGV0); + continue; + } + + /* Check if IP is allowed here */ + if (OS_IPNotAllowed(srcip)) { + merror(DENYIP_WARN, ARGV0, srcip); + close(client_socket); + continue; + } + + /* Fork to deal with new client */ + if (fork() == 0) { + HandleClient(client_socket, srcip); + exit(0); + } else { + childcount++; + + /* Close client socket, since the child is handling it */ + close(client_socket); + continue; + } + } /* if socket active */ + } /* for() loop on available sockets */ + } /* while(1) loop for messages */ +} + diff --git a/src/reportd/report.c b/src/reportd/report.c new file mode 100644 index 000000000..ac8bb4056 --- /dev/null +++ b/src/reportd/report.c @@ -0,0 +1,207 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" + +/* Prototypes */ +static void help_reportd(void) __attribute__((noreturn)); + + +/* Print help statement */ +static void help_reportd() +{ + print_header(); + print_out(" Generate reports (via stdin)"); + print_out(" %s: -[Vhdtns] [-u user] [-g group] [-D dir] [-f filter value] [-r filter value]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -n Create description for the report"); + print_out(" -s Show the alert dump"); + print_out(" -u User to run as (default: %s)", USER); + print_out(" -g Group to run as (default: %s)", GROUPGLOBAL); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" -f Filter the results"); + print_out(" -r Show related entries"); + print_out(" Filters allowed: group, rule, level, location,"); + print_out(" user, srcip, filename"); + print_out(" Examples:"); + print_out(" -f group authentication_success (to filter on login success)"); + print_out(" -f level 10 (to filter on level >= 10)"); + print_out(" -f group authentication -r user srcip (to show srcip for all users)"); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, test_config = 0; + uid_t uid; + gid_t gid; + const char *dir = DEFAULTDIR; + const char *user = USER; + const char *group = GROUPGLOBAL; + + const char *filter_by = NULL; + const char *filter_value = NULL; + + const char *related_of = NULL; + const char *related_values = NULL; + report_filter r_filter; + + /* Set the name */ + OS_SetName(ARGV0); + + r_filter.group = NULL; + r_filter.rule = NULL; + r_filter.level = NULL; + r_filter.location = NULL; + r_filter.srcip = NULL; + r_filter.user = NULL; + r_filter.files = NULL; + r_filter.show_alerts = 0; + + r_filter.related_group = 0; + r_filter.related_rule = 0; + r_filter.related_level = 0; + r_filter.related_location = 0; + r_filter.related_srcip = 0; + r_filter.related_user = 0; + r_filter.related_file = 0; + + r_filter.report_name = NULL; + + while ((c = getopt(argc, argv, "Vdhstu:g:D:f:v:n:r:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_reportd(); + break; + case 'd': + nowDebug(); + break; + case 'n': + if (!optarg) { + ErrorExit("%s: -n needs an argument", ARGV0); + } + r_filter.report_name = optarg; + break; + case 'r': + if (!optarg || !argv[optind]) { + ErrorExit("%s: -r needs two argument", ARGV0); + } + related_of = optarg; + related_values = argv[optind]; + + if (os_report_configfilter(related_of, related_values, + &r_filter, REPORT_RELATED) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, "user argument"); + } + optind++; + break; + case 'f': + if (!optarg) { + ErrorExit("%s: -f needs two argument", ARGV0); + } + filter_by = optarg; + filter_value = argv[optind]; + + if (os_report_configfilter(filter_by, filter_value, + &r_filter, REPORT_FILTER) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, "user argument"); + } + optind++; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -u needs an argument", ARGV0); + } + user = optarg; + break; + case 'g': + if (!optarg) { + ErrorExit("%s: -g needs an argument", ARGV0); + } + group = optarg; + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + dir = optarg; + break; + case 't': + test_config = 1; + break; + case 's': + r_filter.show_alerts = 1; + break; + default: + help_reportd(); + break; + } + + } + + /* Start daemon */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the user/group given are valid */ + uid = Privsep_GetUser(user); + gid = Privsep_GetGroup(group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); + } + + /* Exit here if test config is set */ + if (test_config) { + exit(0); + } + + /* Privilege separation */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); + } + + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + + /* Change user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); + } + + debug1(CHROOT_MSG, ARGV0, dir); + debug1(PRIVSEP_MSG, ARGV0, user); + + /* Signal manipulation */ + StartSIG(ARGV0); + + /* Create PID files */ + if (CreatePID(ARGV0, getpid()) < 0) { + ErrorExit(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + /* The real stuff now */ + os_ReportdStart(&r_filter); + + exit(0); +} + diff --git a/src/rootcheck/check_open_ports.c b/src/rootcheck/check_open_ports.c new file mode 100644 index 000000000..7afc14d6a --- /dev/null +++ b/src/rootcheck/check_open_ports.c @@ -0,0 +1,153 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "headers/debug_op.h" +#include "headers/defs.h" +#include "rootcheck.h" + +#ifndef openarmorHIDS + +/* Prototypes */ +static int connect_to_port(int proto, int port); +static void try_to_access_ports(void); + +/* Global variables */ +static int _ports_open; +static int open_ports_size; +static char open_ports_str[OS_SIZE_1024 + 1]; + + +static int connect_to_port(int proto, int port) +{ + int rc = 0; + int ossock; + struct sockaddr_in server; + struct sockaddr_in6 server6; +#ifdef WIN32 + int salen = sizeof(struct sockaddr_in6); +#endif + + + if (proto == IPPROTO_UDP) { + if ((ossock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return (0); + } + } else if (proto == IPPROTO_TCP) { + if ((ossock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return (0); + } + } else { + return (0); + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(port); + server.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (connect(ossock, (struct sockaddr *)&server, sizeof(server)) == 0) { + rc = 1; + } + + close(ossock); + + /* repeat for IPv6 */ + if (proto == IPPROTO_UDP) { + if ((ossock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return(0); + } + } else if (proto == IPPROTO_TCP) { + if ((ossock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return(0); + } + } + + memset(&server6, 0, sizeof(server6)); +#ifdef WIN32 + WSAStringToAddress("::1", AF_INET6, NULL, (LPSOCKADDR) &server6, + (LPINT) &salen); +#else + server6.sin6_family = AF_INET6; + inet_pton(AF_INET6, "::1", &server6.sin6_addr.s6_addr); +#endif + server6.sin6_port = htons( port ); + + if(connect(ossock, (struct sockaddr *)&server6, sizeof(server6)) == 0) { + rc = 1; + } + + close(ossock); + + return (rc); +} + +static void try_to_access_ports() +{ + int i; + + for (i = 0; i <= 65535; i++) { + if (total_ports_tcp[i] && connect_to_port(IPPROTO_TCP, i)) { + char port_proto[64]; + + if (_ports_open == 0) { + snprintf(port_proto, 64, "\n %d (tcp),", i); + } else { + snprintf(port_proto, 64, "%d (tcp),", i); + } + strncat(open_ports_str, port_proto, open_ports_size); + open_ports_size -= strlen(port_proto) + 1; + + _ports_open++; + } + + if (total_ports_udp[i] && connect_to_port(IPPROTO_UDP, i)) { + char port_proto[64]; + + if (_ports_open == 0) { + snprintf(port_proto, 64, "\n %d (udp),", i); + } else { + snprintf(port_proto, 64, "%d (udp),", i); + } + + strncat(open_ports_str, port_proto, open_ports_size); + open_ports_size -= strlen(port_proto) + 1; + + _ports_open++; + } + + if (_ports_open >= 4) { + _ports_open = 0; + } + } + +} +#endif + +void check_open_ports() +{ +#ifndef openarmorHIDS + memset(open_ports_str, '\0', OS_SIZE_1024 + 1); + open_ports_size = OS_SIZE_1024 - 1; + _ports_open = 0; + + snprintf(open_ports_str, OS_SIZE_1024, "The following ports are open:"); + open_ports_size -= strlen(open_ports_str) + 1; + + /* Testing All ports */ + try_to_access_ports(); + + open_ports_str[strlen(open_ports_str) - 1] = '\0'; + + notify_rk(ALERT_OK, open_ports_str); + +#endif + return; +} + diff --git a/src/rootcheck/check_rc_dev.c b/src/rootcheck/check_rc_dev.c new file mode 100644 index 000000000..7acbc115d --- /dev/null +++ b/src/rootcheck/check_rc_dev.c @@ -0,0 +1,172 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 +#include "shared.h" +#include "rootcheck.h" + +/* Prototypes */ +static int read_dev_file(const char *file_name); +static int read_dev_dir(const char *dir_name); + +/* Global variables */ +static int _dev_errors; +static int _dev_total; + + +static int read_dev_file(const char *file_name) +{ + struct stat statbuf; + + if (lstat(file_name, &statbuf) < 0) { + return (-1); + } + + /* Process directories recursively */ + if (S_ISDIR(statbuf.st_mode)) { +#ifdef DEBUG + verbose("%s: Reading dir: %s\n", ARGV0, file_name); +#endif + return (read_dev_dir(file_name)); + } + + else if (S_ISREG(statbuf.st_mode)) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "File '%s' present on /dev." + " Possible hidden file.", file_name); + notify_rk(ALERT_SYSTEM_CRIT, op_msg); + + _dev_errors++; + } + + return (0); +} + +static int read_dev_dir(const char *dir_name) +{ + int i; + DIR *dp; + struct dirent *entry; + + /* When will these people learn that /dev is not + * meant to store log files or other kind of texts? + */ + const char *(ignore_dev[]) = {"MAKEDEV", "README.MAKEDEV", + "MAKEDEV.README", ".udevdb", + ".udev.tdb", ".initramfs-tools", + "MAKEDEV.local", ".udev", ".initramfs", + "oprofile", "fd", "cgroup", +#ifdef SOLARIS + ".devfsadm_dev.lock", + ".devlink_db_lock", + ".devlink_db", + ".devfsadm_daemon.lock", + ".devfsadm_deamon.lock", + ".devfsadm_synch_door", + ".zone_reg_door", +#endif + NULL + }; + + /* Full path ignore */ + const char *(ignore_dev_full_path[]) = {"/dev/shm/sysconfig", + "/dev/bus/usb/.usbfs", + "/dev/shm", + "/dev/gpmctl", + NULL + }; + + if (dir_name == NULL || strlen(dir_name) > PATH_MAX) { + merror("%s: Invalid directory given.", ARGV0); + return (-1); + } + + /* Open directory */ + dp = opendir(dir_name); + if (!dp) { + return (-1); + } + + /* Iterate over all files in the directory */ + while ((entry = readdir(dp)) != NULL) { + char f_name[PATH_MAX + 2]; + + /* Ignore . and .. */ + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) { + continue; + } + + _dev_total++; + + /* Do not look for the ignored files */ + for (i = 0; ignore_dev[i] != NULL; i++) { + if (strcmp(ignore_dev[i], entry->d_name) == 0) { + break; + } + } + if (ignore_dev[i] != NULL) { + continue; + } + + f_name[PATH_MAX + 1] = '\0'; + snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name); + + /* Do not look for the full ignored files */ + for (i = 0; ignore_dev_full_path[i] != NULL; i++) { + if (strcmp(ignore_dev_full_path[i], f_name) == 0) { + break; + } + } + + /* Check against the full path */ + if (ignore_dev_full_path[i] != NULL) { + continue; + } + + /* Found a non-ignored entry in the directory, so process it */ + read_dev_file(f_name); + } + + closedir(dp); + return (0); +} + +void check_rc_dev(const char *basedir) +{ + char file_path[OS_SIZE_1024 + 1]; + + _dev_total = 0, _dev_errors = 0; + debug1("%s: DEBUG: Starting on check_rc_dev", ARGV0); + + snprintf(file_path, OS_SIZE_1024, "%s/dev", basedir); + + read_dev_dir(file_path); + if (_dev_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "No problem detected on the /dev " + "directory. Analyzed %d files", + _dev_total); + notify_rk(ALERT_OK, op_msg); + } + + return; +} + +#else + +/* Not relevant on Windows */ +void check_rc_dev(__attribute__((unused)) char *basedir) +{ + return; +} + +#endif /* WIN32 */ + diff --git a/src/rootcheck/check_rc_files.c b/src/rootcheck/check_rc_files.c new file mode 100644 index 000000000..a7f63f6d3 --- /dev/null +++ b/src/rootcheck/check_rc_files.c @@ -0,0 +1,185 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + + +/* Read the file pointer specified (rootkit_files) + * and check if the configured file is there + */ +void check_rc_files(const char *basedir, FILE *fp) +{ + char buf[OS_SIZE_1024 + 1]; + char file_path[OS_SIZE_1024 + 1]; + + char *file; + char *name; + char *link; + + int _errors = 0; + int _total = 0; + + debug1("%s: DEBUG: Starting on check_rc_files", ARGV0); + + while (fgets(buf, OS_SIZE_1024, fp) != NULL) { + char *nbuf; + + /* Remove newline at the end */ + nbuf = strchr(buf, '\n'); + if (nbuf) { + *nbuf = '\0'; + } + + /* Assign buf to be used */ + nbuf = buf; + + /* Skip comments and blank lines */ + while (*nbuf != '\0') { + if (*nbuf == ' ' || *nbuf == '\t') { + nbuf++; + continue; + } else if (*nbuf == '#') { + goto newline; + } else { + break; + } + } + + if (*nbuf == '\0') { + goto newline; + } + + /* File now may be valid */ + file = nbuf; + name = nbuf; + + /* Get the file and the rootkit name */ + while (*nbuf != '\0') { + if (*nbuf == ' ' || *nbuf == '\t') { + /* Set the limit for the file */ + *nbuf = '\0'; + nbuf++; + break; + } else { + nbuf++; + } + } + + if (*nbuf == '\0') { + goto newline; + } + + /* Some ugly code to remove spaces and \t */ + while (*nbuf != '\0') { + if (*nbuf == '!') { + nbuf++; + if (*nbuf == ' ' || *nbuf == '\t') { + nbuf++; + name = nbuf; + + break; + } + } else if (*nbuf == ' ' || *nbuf == '\t') { + nbuf++; + continue; + } else { + goto newline; + } + } + + /* Get the link (if present) */ + link = strchr(nbuf, ':'); + if (link) { + *link = '\0'; + + link++; + if (*link == ':') { + link++; + } + } + + /* Clean any space or tab at the end */ + nbuf = strchr(nbuf, ' '); + if (nbuf) { + *nbuf = '\0'; + + nbuf = strchr(nbuf, '\t'); + if (nbuf) { + *nbuf = '\0'; + } + } + + _total++; + + /* Check if it is a file to search everywhere */ + if (*file == '*') { + /* Maximum number of global files reached */ + if (rk_sys_count >= MAX_RK_SYS) { + merror(MAX_RK_MSG, ARGV0, MAX_RK_SYS); + } + + else { + /* Remove all slashes from the file */ + file++; + if (*file == '/') { + file++; + } + + rk_sys_file[rk_sys_count] = strdup(file); + rk_sys_name[rk_sys_count] = strdup(name); + + if (!rk_sys_name[rk_sys_count] || + !rk_sys_file[rk_sys_count] ) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + + if (rk_sys_file[rk_sys_count]) { + free(rk_sys_file[rk_sys_count]); + } + if (rk_sys_name[rk_sys_count]) { + free(rk_sys_name[rk_sys_count]); + } + + rk_sys_file[rk_sys_count] = NULL; + rk_sys_name[rk_sys_count] = NULL; + } + + rk_sys_count++; + + /* Always assign the last as NULL */ + rk_sys_file[rk_sys_count] = NULL; + rk_sys_name[rk_sys_count] = NULL; + } + continue; + } + + snprintf(file_path, OS_SIZE_1024, "%s/%s", basedir, file); + + if (is_file(file_path)) { + char op_msg[OS_SIZE_1024 + 1]; + + _errors = 1; + snprintf(op_msg, OS_SIZE_1024, "Rootkit '%s' detected " + "by the presence of file '%s'.", name, file_path); + + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + } + +newline: + continue; + } + + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "No presence of public rootkits detected." + " Analyzed %d files.", _total); + notify_rk(ALERT_OK, op_msg); + } +} + diff --git a/src/rootcheck/check_rc_if.c b/src/rootcheck/check_rc_if.c new file mode 100644 index 000000000..ccedb668b --- /dev/null +++ b/src/rootcheck/check_rc_if.c @@ -0,0 +1,129 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef SOLARIS +#include +#include +#endif + +#include "headers/debug_op.h" +#include "headers/defs.h" +#include "rootcheck.h" + +#ifndef IFCONFIG +#define IFCONFIG "ifconfig %s | grep PROMISC > /dev/null 2>&1" +#endif + +/* Prototypes */ +static int run_ifconfig(const char *ifconfig); + + +/* Execute the ifconfig command + * Returns 1 if the interface is in promiscuous mode + */ +static int run_ifconfig(const char *ifconfig) +{ + char nt[OS_SIZE_1024 + 1]; + + snprintf(nt, OS_SIZE_1024, IFCONFIG, ifconfig); + if (system(nt) == 0) { + return (1); + } + + return (0); +} + +/* Check all interfaces for promiscuous mode */ +void check_rc_if() +{ + int _fd, _errors = 0, _total = 0; + struct ifreq tmp_str[16]; + + struct ifconf _if; + struct ifreq *_ir; + struct ifreq *_ifend; + struct ifreq _ifr; + + _fd = socket(AF_INET, SOCK_DGRAM, 0); + if (_fd < 0) { + merror("%s: Error checking interfaces (socket)", ARGV0); + return; + } + + memset(tmp_str, 0, sizeof(struct ifreq) * 16); + _if.ifc_len = sizeof(tmp_str); + _if.ifc_buf = (caddr_t)(tmp_str); + + if (ioctl(_fd, SIOCGIFCONF, &_if) < 0) { + close(_fd); + merror("%s: Error checking interfaces (ioctl)", ARGV0); + return; + } + + _ifend = (struct ifreq *) (void *) ((char *)tmp_str + _if.ifc_len); + _ir = tmp_str; + + /* Loop over all interfaces */ + for (; _ir < _ifend; _ir++) { + strncpy(_ifr.ifr_name, _ir->ifr_name, sizeof(_ifr.ifr_name)); + + /* Get information from each interface */ + if (ioctl(_fd, SIOCGIFFLAGS, (char *)&_ifr) == -1) { + continue; + } + + _total++; + + if ((_ifr.ifr_flags & IFF_PROMISC) ) { + char op_msg[OS_SIZE_1024 + 1]; + if (run_ifconfig(_ifr.ifr_name)) { + snprintf(op_msg, OS_SIZE_1024, "Interface '%s' in promiscuous" + " mode.", _ifr.ifr_name); + notify_rk(ALERT_SYSTEM_CRIT, op_msg); + } else { + snprintf(op_msg, OS_SIZE_1024, "Interface '%s' in promiscuous" + " mode, but ifconfig is not showing it" + "(probably trojaned).", _ifr.ifr_name); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + } + _errors++; + } + } + close(_fd); + + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "No problem detected on ifconfig/ifs." + " Analyzed %d interfaces.", _total); + notify_rk(ALERT_OK, op_msg); + } + + return; +} + +#else /* WIN32 */ + +/* Not implemented on Windows */ +void check_rc_if() +{ + return; +} + +#endif /* WIN32 */ + diff --git a/src/rootcheck/check_rc_pids.c b/src/rootcheck/check_rc_pids.c new file mode 100644 index 000000000..d3e271aa3 --- /dev/null +++ b/src/rootcheck/check_rc_pids.c @@ -0,0 +1,329 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 +#include "shared.h" +#include "rootcheck.h" + +/* Prototypes */ +static int proc_read(int pid); +static int proc_chdir(int pid); +static int proc_stat(int pid); +static void loop_all_pids(const char *ps, pid_t max_pid, int *_errors, int *_total); + +/* Global variables */ +static int noproc; + + +/* If /proc is mounted, check to see if the pid is present */ +static int proc_read(int pid) +{ + char dir[OS_SIZE_1024 + 1]; + + if (noproc) { + return (0); + } + + snprintf(dir, OS_SIZE_1024, "%d", pid); + if (isfile_ondir(dir, "/proc")) { + return (1); + } + return (0); +} + +/* If /proc is mounted, check to see if the pid is present */ +static int proc_chdir(int pid) +{ + int ret = 0; + char curr_dir[OS_SIZE_1024 + 1]; + char dir[OS_SIZE_1024 + 1]; + + if (noproc) { + return (0); + } + if (getcwd(curr_dir, OS_SIZE_1024) == NULL) { + return (0); + } + if (chdir("/proc") == -1) { + return (0); + } + + snprintf(dir, OS_SIZE_1024, "/proc/%d", pid); + if (chdir(dir) == 0) { + ret = 1; + } + + /* Returning to the previous directory */ + if (chdir(curr_dir) == -1) { + return (0); + } + + return (ret); +} + +/* If /proc is mounted, check to see if the pid is present there */ +static int proc_stat(int pid) +{ + char proc_dir[OS_SIZE_1024 + 1]; + + if (noproc) { + return (0); + } + + snprintf(proc_dir, OS_SIZE_1024, "%s/%d", "/proc", pid); + + if (is_file(proc_dir)) { + return (1); + } + + return (0); +} + +/* Check all the available PIDs for hidden stuff */ +static void loop_all_pids(const char *ps, pid_t max_pid, int *_errors, int *_total) +{ + int _kill0 = 0; + int _kill1 = 0; + int _gsid0 = 0; + int _gsid1 = 0; + int _gpid0 = 0; + int _gpid1 = 0; + int _ps0 = -1; + int _proc_stat = 0; + int _proc_read = 0; + int _proc_chdir = 0; + + pid_t i = 1; + pid_t my_pid; + + char command[OS_SIZE_1024 + 1]; + + my_pid = getpid(); + + for (;; i++) { + if ((i <= 0) || (i > max_pid)) { + break; + } + + (*_total)++; + + _kill0 = 0; + _kill1 = 0; + _gsid0 = 0; + _gsid1 = 0; + _gpid0 = 0; + _gpid1 = 0; + _ps0 = -1; + + /* kill test */ + if (!((kill(i, 0) == -1) && (errno == ESRCH))) { + _kill0 = 1; + } + + /* getsid test */ + if (!((getsid(i) == -1) && (errno == ESRCH))) { + _gsid0 = 1; + } + + /* getpgid test */ + if (!((getpgid(i) == -1) && (errno == ESRCH))) { + _gpid0 = 1; + } + + /* /proc test */ + _proc_stat = proc_stat(i); + _proc_read = proc_read(i); + _proc_chdir = proc_chdir(i); + + /* If PID does not exist, move on */ + if (!_kill0 && !_gsid0 && !_gpid0 && + !_proc_stat && !_proc_read && !_proc_chdir) { + continue; + } + + /* Ignore our own pid */ + if (i == my_pid) { + continue; + } + + /* Check the number of errors */ + if ((*_errors) > 15) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Excessive number of hidden processes" + ". It maybe a false-positive or " + "something really bad is going on."); + notify_rk(ALERT_SYSTEM_CRIT, op_msg); + return; + } + + /* Check if the process appears in ps(1) output */ + if (*ps) { + snprintf(command, OS_SIZE_1024, "%s -p %d > /dev/null 2>&1", ps, (int)i); + _ps0 = 0; + if (system(command) == 0) { + _ps0 = 1; + } + } + + /* If we are run in the context of openarmor-HIDS, sleep here (no rush) */ +#ifdef openarmorHIDS + debug1("%s: DEBUG: pause for %u", ARGV0, rootcheck.tsleep); + sleep(rootcheck.tsleep); +#endif + + /* Everything fine, move on */ + if (_ps0 && _kill0 && _gsid0 && _gpid0 && _proc_stat && _proc_read) { + continue; + } + + /* + * If our kill or getsid system call got the PID but ps(1) did not, + * find out if the PID is deleted (not used anymore) + */ + if (!((getsid(i) == -1) && (errno == ESRCH))) { + _gsid1 = 1; + } + if (!((kill(i, 0) == -1) && (errno == ESRCH))) { + _kill1 = 1; + } + if (!((getpgid(i) == -1) && (errno == ESRCH))) { + _gpid1 = 1; + } + + _proc_stat = proc_stat(i); + _proc_read = proc_read(i); + _proc_chdir = proc_chdir(i); + + /* If it matches, process was terminated in the meantime, so move on */ + if (!_gsid1 && !_kill1 && !_gpid1 && !_proc_stat && + !_proc_read && !_proc_chdir) { + continue; + } + +#ifdef AIX + /* Ignore AIX wait and sched programs */ + if (_gsid0 == _gsid1 && + _kill0 == _kill1 && + _gpid0 == _gpid1 && + _ps0 == 1 && + _gsid0 == 1 && + _kill0 == 0) { + /* The wait and sched programs do not respond to kill 0. + * So if everything else finds it, including ps, getpid, getsid, + * but not kill, we can safely ignore on AIX. + * A malicious program would specially try to hide from ps. + */ + continue; + } +#endif + + if (_gsid0 == _gsid1 && + _kill0 == _kill1 && + _gsid0 != _kill0) { + /* If kill worked, but getsid and getpgid did not, it may + * be a defunct process -- ignore. + */ + if (! (_kill0 == 1 && _gsid0 == 0 && _gpid0 == 0) ) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " + "kill (%d) or getsid (%d). Possible kernel-level" + " rootkit.", (int)i, _kill0, _gsid0); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + (*_errors)++; + } + } else if (_kill1 != _gsid1 || + _gpid1 != _kill1 || + _gpid1 != _gsid1) { + /* See defunct process comment above */ + if (! (_kill1 == 1 && _gsid0 == 0 && _gpid0 == 0 && _gsid1 == 0) ) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " + "kill (%d), getsid (%d) or getpgid. Possible " + "kernel-level rootkit.", (int)i, _kill1, _gsid1); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + (*_errors)++; + } + } else if (_proc_read != _proc_stat || + _proc_read != _proc_chdir || + _proc_stat != _kill1) { + /* Check if the pid is a thread (not showing in /proc */ + if (!noproc && !check_rc_readproc((int)i)) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " + "/proc. Possible kernel level rootkit.", (int)i); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + (*_errors)++; + } + } else if (_gsid1 && _kill1 && !_ps0) { + /* checking if the pid is a thread (not showing on ps */ + if (!check_rc_readproc((int)i)) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " + "ps. Possible trojaned version installed.", + (int)i); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + (*_errors)++; + } + } + } +} + +/* Scan the whole filesystem looking for possible issues */ +void check_rc_pids() +{ + int _total = 0; + int _errors = 0; + + char ps[OS_SIZE_1024 + 1]; + + char proc_0[] = "/proc"; + char proc_1[] = "/proc/1"; + + pid_t max_pid = MAX_PID; + noproc = 1; + + /* Checking where ps is */ + memset(ps, '\0', OS_SIZE_1024 + 1); + strncpy(ps, "/bin/ps", OS_SIZE_1024); + if (!is_file(ps)) { + strncpy(ps, "/usr/bin/ps", OS_SIZE_1024); + if (!is_file(ps)) { + ps[0] = '\0'; + } + } + + /* Proc is mounted */ + if (is_file(proc_0) && is_file(proc_1)) { + noproc = 0; + } + + loop_all_pids(ps, max_pid, &_errors, &_total); + + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "No hidden process by Kernel-level " + "rootkits.\n %s is not trojaned. " + "Analyzed %d processes.", ps, _total); + notify_rk(ALERT_OK, op_msg); + } + + return; +} + +#else +void check_rc_pids() +{ + return; +} +#endif + diff --git a/src/rootcheck/check_rc_policy.c b/src/rootcheck/check_rc_policy.c new file mode 100644 index 000000000..143d755a8 --- /dev/null +++ b/src/rootcheck/check_rc_policy.c @@ -0,0 +1,49 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + + +/* Read the file pointer specified + * and check if the configured file is there + */ +void check_rc_unixaudit(FILE *fp, OSList *p_list) +{ + debug1("%s: DEBUG: Starting on check_rc_unixaudit", ARGV0); + rkcl_get_entry(fp, "System Audit:", p_list); +} + +/* Read the file pointer specified + * and check if the configured file is there + */ +void check_rc_winaudit(FILE *fp, OSList *p_list) +{ + debug1("%s: DEBUG: Starting on check_rc_winaudit", ARGV0); + rkcl_get_entry(fp, "Windows Audit:", p_list); +} + +/* Read the file pointer specified + * and check if the configured file is there + */ +void check_rc_winmalware(FILE *fp, OSList *p_list) +{ + debug1("%s: DEBUG: Starting on check_rc_winmalware", ARGV0); + rkcl_get_entry(fp, "Windows Malware:", p_list); +} + +/* Read the file pointer specified + * and check if the configured file is there + */ +void check_rc_winapps(FILE *fp, OSList *p_list) +{ + debug1("%s: DEBUG: Starting on check_rc_winapps", ARGV0); + rkcl_get_entry(fp, "Application Found:", p_list); +} + diff --git a/src/rootcheck/check_rc_ports.c b/src/rootcheck/check_rc_ports.c new file mode 100644 index 000000000..933fdf5a8 --- /dev/null +++ b/src/rootcheck/check_rc_ports.c @@ -0,0 +1,213 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 + +#include "shared.h" +#include "rootcheck.h" + +#if defined(sun) || defined(__sun__) +#define NETSTAT "netstat -an -P %s | "\ + "grep \"[^0-9]%d \" > /dev/null 2>&1" +#else +#define NETSTAT "netstat -an | grep \"^%s\" | " \ + "grep \"[^0-9]%d \" > /dev/null 2>&1" +#endif + +/* Prototypes */ +static int run_netstat(int proto, int port); +static int conn_port(int proto, int port); +static void test_ports(int proto, int *_errors, int *_total); + + +static int run_netstat(int proto, int port) +{ + int ret; + char nt[OS_SIZE_1024 + 1]; + + if (proto == IPPROTO_TCP) { + snprintf(nt, OS_SIZE_1024, NETSTAT, "tcp", port); + } else if (proto == IPPROTO_UDP) { + snprintf(nt, OS_SIZE_1024, NETSTAT, "udp", port); + } else { + merror("%s: Netstat error (wrong protocol)", ARGV0); + return (0); + } + + ret = system(nt); + + if (ret == 0) { + return (1); + } else if (ret == 1) { + return (0); + } + + return (1); +} + +static int conn_port(int proto, int port) +{ + int rc = 0; + int ossock; + struct sockaddr_in server; + struct sockaddr_in6 server6; + + if (proto == IPPROTO_UDP) { + if ((ossock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return (0); + } + } else if (proto == IPPROTO_TCP) { + if ((ossock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return (0); + } + } else { + return (0); + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(port); + server.sin_addr.s_addr = htonl(INADDR_ANY); + + /* If we can't bind, it means the port is open */ + if (bind(ossock, (struct sockaddr *) &server, sizeof(server)) < 0) { + rc = 1; + } + + /* Setting if port is open or closed */ + if (proto == IPPROTO_TCP) { + total_ports_tcp[port] = (char) rc; + } else { + total_ports_udp[port] = (char) rc; + } + + close(ossock); + + /* repeat for IPv6 */ + if (proto == IPPROTO_UDP) { + if ((ossock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + return(0); + } + } else if (proto == IPPROTO_TCP) { + if ((ossock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return(0); + } + } + + + memset(&server6, 0, sizeof(server6)); + server6.sin6_family = AF_INET6; + server6.sin6_port = htons( port ); + memcpy(&server6.sin6_addr.s6_addr, &in6addr_any, sizeof in6addr_any); + + + /* If we can't bind, it means the port is open */ + if(bind(ossock, (struct sockaddr *) &server6, sizeof(server6)) < 0) { + rc = 1; + } + + /* Setting if port is open or closed */ + if(proto == IPPROTO_TCP) { + total_ports_tcp[port] = rc; + } else { + total_ports_udp[port] = rc; + } + + close(ossock); + + return (rc); +} + +static void test_ports(int proto, int *_errors, int *_total) +{ + int i; + + for (i = 0; i <= 65535; i++) { + (*_total)++; + if (conn_port(proto, i)) { + /* Check if we can find it using netstat. If not, + * check again to see if the port is still being used. + */ + if (run_netstat(proto, i)) { + continue; + } + +#ifdef openarmorHIDS + /* If we are in the context of openarmor-HIDS, sleep here (no rush) */ + debug1("%s: DEBUG: pause for %u", ARGV0, rootcheck.tsleep); + sleep(rootcheck.tsleep); +#endif + + if (!run_netstat(proto, i) && conn_port(proto, i)) { + char op_msg[OS_SIZE_1024 + 1]; + + (*_errors)++; + + snprintf(op_msg, OS_SIZE_1024, "Port '%d'(%s) hidden. " + "Kernel-level rootkit or trojaned " + "version of netstat.", i, + (proto == IPPROTO_UDP) ? "udp" : "tcp"); + + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + } + } + + if ((*_errors) > 20) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "Excessive number of '%s' ports " + "hidden. It maybe a false-positive or " + "something really bad is going on.", + (proto == IPPROTO_UDP) ? "udp" : "tcp" ); + notify_rk(ALERT_SYSTEM_CRIT, op_msg); + return; + } + } + +} + +void check_rc_ports() +{ + int _errors = 0; + int _total = 0; + + int i = 0; + + while (i <= 65535) { + total_ports_tcp[i] = 0; + total_ports_udp[i] = 0; + i++; + } + + /* Test both TCP and UDP ports */ + test_ports(IPPROTO_TCP, &_errors, &_total); + test_ports(IPPROTO_UDP, &_errors, &_total); + + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(op_msg, OS_SIZE_1024, "No kernel-level rootkit hiding any port." + "\n Netstat is acting correctly." + " Analyzed %d ports.", _total); + notify_rk(ALERT_OK, op_msg); + } + + return; +} + +#else /* WIN32 */ + +/* Not implemented on Windows */ +void check_rc_ports() +{ + return; +} + +#endif /* WIN32 */ + diff --git a/src/rootcheck/check_rc_readproc.c b/src/rootcheck/check_rc_readproc.c new file mode 100644 index 000000000..81351ac85 --- /dev/null +++ b/src/rootcheck/check_rc_readproc.c @@ -0,0 +1,128 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 + +#include "shared.h" +#include "rootcheck.h" + +#define PROC 0 +#define PID 1 +#define TASK 2 + +/* Prototypes */ +static int read_proc_file(const char *file_name, const char *pid, int position); +static int read_proc_dir(const char *dir_name, const char *pid, int position); + +/* Global variables */ +static int proc_pid_found; + + +static int read_proc_file(const char *file_name, const char *pid, int position) +{ + struct stat statbuf; + + if (lstat(file_name, &statbuf) < 0) { + return (-1); + } + + /* If directory, read the directory */ + if (S_ISDIR(statbuf.st_mode)) { + return (read_proc_dir(file_name, pid, position)); + } + + return (0); +} + +int read_proc_dir(const char *dir_name, const char *pid, int position) +{ + DIR *dp; + struct dirent *entry; + + if ((dir_name == NULL) || (strlen(dir_name) > PATH_MAX)) { + merror("%s: Invalid directory given", ARGV0); + return (-1); + } + + /* Open the directory */ + dp = opendir(dir_name); + if (!dp) { + return (0); + } + + while ((entry = readdir(dp)) != NULL) { + char f_name[PATH_MAX + 2]; + + /* Ignore . and .. */ + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) { + continue; + } + + if (position == PROC) { + char *tmp_str; + + tmp_str = entry->d_name; + while (*tmp_str != '\0') { + if (!isdigit((int)*tmp_str)) { + break; + } + tmp_str++; + } + + if (*tmp_str != '\0') { + continue; + } + + snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name); + read_proc_file(f_name, pid, position + 1); + } else if (position == PID) { + if (strcmp(entry->d_name, "task") == 0) { + snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name); + read_proc_file(f_name, pid, position + 1); + } + } else if (position == TASK) { + /* Check under proc/pid/task/lwp */ + if (strcmp(entry->d_name, pid) == 0) { + proc_pid_found = 1; + break; + } + } else { + break; + } + } + + closedir(dp); + + return (0); +} + +/* Read the /proc directory (if present) and check if it can find + * the given pid (as a pid or as a thread) + */ +int check_rc_readproc(int pid) +{ + char char_pid[32]; + + proc_pid_found = 0; + + /* NL threads */ + snprintf(char_pid, 31, "/proc/.%d", pid); + if (is_file(char_pid)) { + return (1); + } + + snprintf(char_pid, 31, "%d", pid); + read_proc_dir("/proc", char_pid, PROC); + + return (proc_pid_found); +} + +#endif + diff --git a/src/rootcheck/check_rc_sys.c b/src/rootcheck/check_rc_sys.c new file mode 100644 index 000000000..3a6816c1a --- /dev/null +++ b/src/rootcheck/check_rc_sys.c @@ -0,0 +1,459 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + +/* Prototypes */ +static int read_sys_file(const char *file_name, int do_read); +static int read_sys_dir(const char *dir_name, int do_read); + +/* Global variables */ +static int _sys_errors; +static int _sys_total; +static dev_t did; +static FILE *_wx; +static FILE *_ww; +static FILE *_suid; + + +static int read_sys_file(const char *file_name, int do_read) +{ + struct stat statbuf; + + _sys_total++; + +#ifdef WIN32 + /* Check for NTFS ADS on Windows */ + os_check_ads(file_name); +#endif + if (lstat(file_name, &statbuf) < 0) { +#ifndef WIN32 + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Anomaly detected in file '%s'. " + "Hidden from stats, but showing up on readdir. " + "Possible kernel level rootkit.", + file_name); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + _sys_errors++; +#endif + return (-1); + } + + /* If directory, read the directory */ + else if (S_ISDIR(statbuf.st_mode)) { + /* Make Darwin happy. For some reason, + * when I read /dev/fd, it goes forever on + * /dev/fd5, /dev/fd6, etc.. weird + */ + if (strstr(file_name, "/dev/fd") != NULL) { + return (0); + } + + /* Ignore the /proc directory (it has size 0) */ + if (statbuf.st_size == 0) { + return (0); + } + + return (read_sys_dir(file_name, do_read)); + } + + /* Check if the size from stats is the same as when we read the file */ + if (S_ISREG(statbuf.st_mode) && do_read) { + char buf[OS_SIZE_1024]; + int fd; + ssize_t nr; + long int total = 0; + + fd = open(file_name, O_RDONLY, 0); + + /* It may not necessarily open */ + if (fd >= 0) { + while ((nr = read(fd, buf, sizeof(buf))) > 0) { + total += nr; + } + close(fd); + + if (strcmp(file_name, "/dev/bus/usb/.usbfs/devices") == 0) { + /* Ignore .usbfs/devices */ + } else if (total != statbuf.st_size) { + struct stat statbuf2; + + if ((lstat(file_name, &statbuf2) == 0) && + (total != statbuf2.st_size) && + (statbuf.st_size == statbuf2.st_size)) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Anomaly detected in file " + "'%s'. File size doesn't match what we found. " + "Possible kernel level rootkit.", + file_name); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + _sys_errors++; + } + } + } + } + + /* If has OTHER write and exec permission, alert */ +#ifndef WIN32 + if ((statbuf.st_mode & S_IWOTH) == S_IWOTH && S_ISREG(statbuf.st_mode)) { + if ((statbuf.st_mode & S_IXUSR) == S_IXUSR) { + if (_wx) { + fprintf(_wx, "%s\n", file_name); + } + + _sys_errors++; + } else { + if (_ww) { + fprintf(_ww, "%s\n", file_name); + } + } + + if (statbuf.st_uid == 0) { + char op_msg[OS_SIZE_1024 + 1]; +#ifdef openarmorHIDS + snprintf(op_msg, OS_SIZE_1024, "File '%s' is owned by root " + "and has write permissions to anyone.", file_name); +#else + snprintf(op_msg, OS_SIZE_1024, "File '%s' is: \n" + " - owned by root,\n" + " - has write permissions to anyone.", + file_name); +#endif + notify_rk(ALERT_SYSTEM_CRIT, op_msg); + + } + _sys_errors++; + } else if ((statbuf.st_mode & S_ISUID) == S_ISUID) { + if (_suid) { + fprintf(_suid, "%s\n", file_name); + } + } +#endif /* WIN32 */ + return (0); +} + +static int read_sys_dir(const char *dir_name, int do_read) +{ + int i = 0; + unsigned int entry_count = 0; + int did_changed = 0; + DIR *dp; + struct dirent *entry; + struct stat statbuf; + short is_nfs; + short skip_fs; + +#ifndef WIN32 + const char *(dirs_to_doread[]) = { "/bin", "/sbin", "/usr/bin", + "/usr/sbin", "/dev", "/etc", + "/boot", NULL + }; +#endif + + if ((dir_name == NULL) || (strlen(dir_name) > PATH_MAX)) { + merror("%s: Invalid directory given.", ARGV0); + return (-1); + } + + /* Ignore user-supplied list */ + if (rootcheck.ignore) { + while (rootcheck.ignore[i]) { + if (strcmp(dir_name, rootcheck.ignore[i]) == 0) { + return (1); + } + i++; + } + i = 0; + } + + /* Should we check for NFS? */ + if(rootcheck.skip_nfs) + { + is_nfs = IsNFS(dir_name); + if(is_nfs != 0) + { + // Error will be -1, and 1 means skipped + return(is_nfs); + } + } + + /* Getting the number of nodes. The total number on opendir + * must be the same + */ + if(lstat(dir_name, &statbuf) < 0) + { + return(-1); + } + + /* Current device id */ + if (did != statbuf.st_dev) { + if (did != 0) { + did_changed = 1; + } + did = statbuf.st_dev; + } + + if (!S_ISDIR(statbuf.st_mode)) { + return (-1); + } + +#ifndef WIN32 + /* Check if the do_read is valid for this directory */ + while (dirs_to_doread[i]) { + if (strcmp(dir_name, dirs_to_doread[i]) == 0) { + do_read = 1; + break; + } + i++; + } +#else + do_read = 0; +#endif + + /* Open the directory */ + dp = opendir(dir_name); + if (!dp) { + if ((strcmp(dir_name, "") == 0) && + (dp = opendir("/"))) { + /* ok */ + } else { + return (-1); + } + } + + /* Read every entry in the directory */ + while ((entry = readdir(dp)) != NULL) { + char f_name[PATH_MAX + 2]; + struct stat statbuf_local; + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { + entry_count++; + continue; + } + + /* Create new file + path string */ + if (strcmp(dir_name, "/") == 0) { + snprintf(f_name, PATH_MAX + 1, "/%s", entry->d_name); + } else { + snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name); + } + + /* Check if file is a directory */ + if (lstat(f_name, &statbuf_local) == 0) { + /* On all the systems except Darwin, the + * link count is only increased on directories + */ +#ifndef Darwin + if (S_ISDIR(statbuf_local.st_mode)) +#else + if (S_ISDIR(statbuf_local.st_mode) || + S_ISREG(statbuf_local.st_mode) + /* No S_ISLNK on Windows */ +#ifndef WIN32 + || S_ISLNK(statbuf_local.st_mode) +#endif + ) +#endif + { + entry_count++; + } + } + + /* Check every file against the rootkit database */ + for (i = 0; i <= rk_sys_count; i++) { + if (!rk_sys_file[i]) { + break; + } + + if (strcmp(rk_sys_file[i], entry->d_name) == 0) { + char op_msg[OS_SIZE_1024 + 1]; + + _sys_errors++; + snprintf(op_msg, OS_SIZE_1024, "Rootkit '%s' detected " + "by the presence of file '%s/%s'.", + rk_sys_name[i], dir_name, rk_sys_file[i]); + + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + } + } + + /* Ignore the /proc and /sys filesystems */ + if ((strcmp(f_name, "/proc") == 0) || (strcmp(f_name, "/sys") == 0)) { + continue; + } + + read_sys_file(f_name, do_read); + } + + /* skip further test because the FS cant deliver the stats (btrfs link count always is 1) */ + skip_fs = skipFS(dir_name); + if(skip_fs != 0) + { + // Error will be -1, and 1 means skipped + closedir(dp); + return(0); + } + + /* Entry count for directory different than the actual + * link count from stats + */ + if ((entry_count != (unsigned) statbuf.st_nlink) && + ((did_changed == 0) || ((entry_count + 1) != (unsigned) statbuf.st_nlink))) { +#ifndef WIN32 + struct stat statbuf2; + char op_msg[OS_SIZE_1024 + 1]; + + if ((lstat(dir_name, &statbuf2) == 0) && + (statbuf2.st_nlink != entry_count)) { + snprintf(op_msg, OS_SIZE_1024, "Files hidden inside directory " + "'%s'. Link count does not match number of files " + "(%d,%d).", + dir_name, entry_count, (int)statbuf.st_nlink); + + /* Solaris /boot is terrible :) */ +#ifdef SOLARIS + if (strncmp(dir_name, "/boot", strlen("/boot")) != 0) { + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + _sys_errors++; + } +#elif defined(Darwin) || defined(FreeBSD) + if (strncmp(dir_name, "/dev", strlen("/dev")) != 0) { + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + _sys_errors++; + } +#else + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + _sys_errors++; +#endif + } +#endif /* WIN32 */ + } + + closedir(dp); + + return (0); +} + +/* Scan the whole filesystem looking for possible issues */ +void check_rc_sys(const char *basedir) +{ + char file_path[OS_SIZE_1024 + 1]; + + debug1("%s: DEBUG: Starting on check_rc_sys", ARGV0); + + _sys_errors = 0; + _sys_total = 0; + did = 0; /* device id */ + + snprintf(file_path, OS_SIZE_1024, "%s", basedir); + + /* Open output files */ + if (rootcheck.notify != QUEUE) { + _wx = fopen("rootcheck-rw-rw-rw-.txt", "w"); + _ww = fopen("rootcheck-rwxrwxrwx.txt", "w"); + _suid = fopen("rootcheck-suid-files.txt", "w"); + } else { + _wx = NULL; + _ww = NULL; + _suid = NULL; + } + + if (rootcheck.scanall) { + /* Scan the whole file system -- may be slow */ +#ifndef WIN32 + snprintf(file_path, 3, "%s", "/"); +#endif + read_sys_dir(file_path, rootcheck.readall); + } else { + /* Scan only specific directories */ + int _i; +#ifndef WIN32 + const char *(dirs_to_scan[]) = {"/bin", "/sbin", "/usr/bin", + "/usr/sbin", "/dev", "/lib", + "/etc", "/root", "/var/log", + "/var/mail", "/var/lib", "/var/www", + "/usr/lib", "/usr/include", + "/tmp", "/boot", "/usr/local", + "/var/tmp", "/sys", NULL + }; + +#else + const char *(dirs_to_scan[]) = {"C:\\WINDOWS", "C:\\Program Files", NULL}; +#endif + + _i = 0; + while (dirs_to_scan[_i] != NULL) { +#ifndef WIN32 + snprintf(file_path, OS_SIZE_1024, "%s%s", + basedir, + dirs_to_scan[_i]); + read_sys_dir(file_path, rootcheck.readall); + +#else + read_sys_dir(dirs_to_scan[_i], rootcheck.readall); +#endif + + _i++; + } + } + + if (_sys_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "No problem found on the system." + " Analyzed %d files.", _sys_total); + notify_rk(ALERT_OK, op_msg); + } + + else if (_wx && _ww && _suid) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Check the following files for more " + "information:\n%s%s%s", + (ftell(_wx) == 0) ? "" : + " rootcheck-rw-rw-rw-.txt (list of world writable files)\n", + (ftell(_ww) == 0) ? "" : + " rootcheck-rwxrwxrwx.txt (list of world writtable/executable files)\n", + (ftell(_suid) == 0) ? "" : + " rootcheck-suid-files.txt (list of suid files)"); + + notify_rk(ALERT_SYSTEM_ERR, op_msg); + } + + if (_wx) { + if (ftell(_wx) == 0) { + if ((unlink("rootcheck-rw-rw-rw-.txt")) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", ARGV0, "rootcheck-rw-rw-rw-.txt", strerror(errno)); + } + } + fclose(_wx); + } + + if (_ww) { + if (ftell(_ww) == 0) { + if ((unlink("rootcheck-rwxrwxrwx.txt")) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", ARGV0, "rootcheck-rwxrwxrwx.txt", strerror(errno)); + } + } + fclose(_ww); + } + + if (_suid) { + if (ftell(_suid) == 0) { + if ((unlink("rootcheck-suid-files.txt")) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", ARGV0, "rootcheck-suid-files.txt", strerror(errno)); + } + } + fclose(_suid); + } + + return; +} + diff --git a/src/rootcheck/check_rc_trojans.c b/src/rootcheck/check_rc_trojans.c new file mode 100644 index 000000000..5a07fc4d0 --- /dev/null +++ b/src/rootcheck/check_rc_trojans.c @@ -0,0 +1,119 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + + +/* Read the file pointer specified (rootkit_trojans) + * and check if any trojan entry is in the configured files + */ +void check_rc_trojans(const char *basedir, FILE *fp) +{ + int i = 0, _errors = 0, _total = 0; + char buf[OS_SIZE_1024 + 1]; + char file_path[OS_SIZE_1024 + 1]; + char *file; + char *string_to_look; + +#ifndef WIN32 + const char *(all_paths[]) = {"bin", "sbin", "usr/bin", "usr/sbin", NULL}; +#else + const char *(all_paths[]) = {"C:\\Windows\\", "D:\\Windows\\", NULL}; +#endif + + debug1("%s: DEBUG: Starting on check_rc_trojans", ARGV0); + + while (fgets(buf, OS_SIZE_1024, fp) != NULL) { + char *nbuf; + char *message = NULL; + + i = 0; + /* Remove end of line */ + nbuf = strchr(buf, '\n'); + if (nbuf) { + *nbuf = '\0'; + } + + nbuf = normalize_string(buf); + + if (*nbuf == '\0' || *nbuf == '#') { + continue; + } + + /* File now may be valid */ + file = nbuf; + + string_to_look = strchr(file, '!'); + if (!string_to_look) { + continue; + } + + *string_to_look = '\0'; + string_to_look++; + + message = strchr(string_to_look, '!'); + if (!message) { + continue; + } + *message = '\0'; + message++; + + string_to_look = normalize_string(string_to_look); + file = normalize_string(file); + message = normalize_string(message); + + if (*file == '\0' || *string_to_look == '\0') { + continue; + } + + _total++; + + /* Try with all possible paths */ + while (all_paths[i] != NULL) { + if (*file != '/') { + snprintf(file_path, OS_SIZE_1024, "%s/%s/%s", basedir, + all_paths[i], + file); + } else { + strncpy(file_path, file, OS_SIZE_1024); + file_path[OS_SIZE_1024 - 1] = '\0'; + } + + /* Check if entry is found */ + if (is_file(file_path) && os_string(file_path, string_to_look)) { + char op_msg[OS_SIZE_1024 + 1]; + _errors = 1; + + snprintf(op_msg, OS_SIZE_1024, "Trojaned version of file " + "'%s' detected. Signature used: '%s' (%s).", + file_path, + string_to_look, + *message == '\0' ? + "Generic" : message); + + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + } + + if (*file == '/') { + break; + } + i++; + } + continue; + } + + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "No binaries with any trojan detected. " + "Analyzed %d files.", _total); + notify_rk(ALERT_OK, op_msg); + } +} + diff --git a/src/rootcheck/common.c b/src/rootcheck/common.c new file mode 100644 index 000000000..cb5d96795 --- /dev/null +++ b/src/rootcheck/common.c @@ -0,0 +1,639 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" +#include "os_regex/os_regex.h" + +/* Prototypes */ +static int _is_str_in_array(char *const *ar, const char *str); + + +/* Check if the specified string is already in the array */ +static int _is_str_in_array(char *const *ar, const char *str) +{ + while (*ar) { + if (strcmp(*ar, str) == 0) { + return (1); + } + ar++; + } + return (0); +} + +int rk_check_dir(const char *dir, const char *file, char *pattern) +{ + int ret_code = 0; + char f_name[PATH_MAX + 2]; + struct dirent *entry; + struct stat statbuf_local; + DIR *dp = NULL; + + f_name[PATH_MAX + 1] = '\0'; + + dp = opendir(dir); + if (!dp) { + return (0); + } + + while ((entry = readdir(dp)) != NULL) { + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + /* Create new file + path string */ + snprintf(f_name, PATH_MAX + 1, "%s/%s", dir, entry->d_name); + + /* Check if the read entry matches the provided file name */ + if (strncasecmp(file, "r:", 2) == 0) { + if (OS_Regex(file + 2, entry->d_name)) { + if (rk_check_file(f_name, pattern)) { + ret_code = 1; + } + } + } else { + /* ... otherwise try without regex */ + if (OS_Match2(file, entry->d_name)) { + if (rk_check_file(f_name, pattern)) { + ret_code = 1; + } + } + } + + /* Check if file is a directory */ + if (lstat(f_name, &statbuf_local) == 0) { + if (S_ISDIR(statbuf_local.st_mode)) { + if (rk_check_dir(f_name, file, pattern)) { + ret_code = 1; + } + } + } + } + + closedir(dp); + return (ret_code); + +} + +int rk_check_file(char *file, char *pattern) +{ + char *split_file; + int full_negate = 0; + int pt_result = 0; + FILE *fp; + char buf[OS_SIZE_2048 + 1]; + + if (file == NULL) { + return (0); + } + + /* Check if the file is divided */ + split_file = strchr(file, ','); + if (split_file) { + *split_file = '\0'; + split_file++; + } + + /* Get each file */ + do { + /* If we don't have a pattern, just check if the file/dir is there */ + if (pattern == NULL) { + if (is_file(file)) { + int i = 0; + char _b_msg[OS_SIZE_1024 + 1]; + + _b_msg[OS_SIZE_1024] = '\0'; + snprintf(_b_msg, OS_SIZE_1024, " File: %s.", + file); + + /* Already present */ + if (_is_str_in_array(rootcheck.alert_msg, _b_msg)) { + return (1); + } + + while (rootcheck.alert_msg[i] && (i < 255)) { + i++; + } + + if (!rootcheck.alert_msg[i]) { + os_strdup(_b_msg, rootcheck.alert_msg[i]); + } + + return (1); + } + } else { + full_negate = pt_check_negate(pattern); + /* Check for content in the file */ + debug1("checking file: %s", file); + fp = fopen(file, "r"); + if (fp) { + + debug1(" starting new file: %s", file); + buf[OS_SIZE_2048] = '\0'; + while (fgets(buf, OS_SIZE_2048, fp) != NULL) { + char *nbuf; + + /* Remove end of line */ + nbuf = strchr(buf, '\n'); + if (nbuf) { + *nbuf = '\0'; + } +#ifdef WIN32 + /* Remove end of line */ + nbuf = strchr(buf, '\r'); + if (nbuf) { + *nbuf = '\0'; + } +#endif + /* Matched */ + pt_result = pt_matches(buf, pattern); + debug1("Buf == \"%s\"", buf); + debug1("Pattern == \"%s\"", pattern); + debug1("pt_result == %d and full_negate == %d", pt_result, full_negate); + if ((pt_result == 1 && full_negate == 0) ) { + debug1("alerting file %s on line %s", file, buf); + int i = 0; + char _b_msg[OS_SIZE_1024 + 1]; + + /* Close the file before dealing with the alert */ + fclose(fp); + + /* Generate the alert itself */ + _b_msg[OS_SIZE_1024] = '\0'; + snprintf(_b_msg, OS_SIZE_1024, " File: %s.", + file); + + /* Already present */ + if (_is_str_in_array(rootcheck.alert_msg, _b_msg)) { + return (1); + } + + while (rootcheck.alert_msg[i] && (i < 255)) { + i++; + } + + if (!rootcheck.alert_msg[i]) { + os_strdup(_b_msg, rootcheck.alert_msg[i]); + } + + return (1); + } else if ((pt_result == 0 && full_negate == 1) ) { + /* Found a full+negate match so no longer need to search + * break out of loop and make sure the full negate does + * not alert. + */ + debug1("found a complete match for full_negate"); + full_negate = 0; + break; + } + } + + fclose(fp); + + if (full_negate == 1) { + debug1("full_negate alerting - file %s", file); + int i = 0; + char _b_msg[OS_SIZE_1024 + 1]; + + /* Generate the alert itself */ + _b_msg[OS_SIZE_1024] = '\0'; + snprintf(_b_msg, OS_SIZE_1024, " File: %s.", + file); + + /* Already present */ + if (_is_str_in_array(rootcheck.alert_msg, _b_msg)) { + return (1); + } + + while (rootcheck.alert_msg[i] && (i < 255)) { + i++; + } + + if (!rootcheck.alert_msg[i]) { + os_strdup(_b_msg, rootcheck.alert_msg[i]); + } + + return (1); + } + } + } + + if (split_file) { + file = split_file; + split_file = strchr(split_file, ','); + if (split_file) { + split_file++; + } + } + + + } while (split_file); + + return (0); +} + +/* Check if the pattern is all negate values */ +int pt_check_negate(const char *pattern) +{ + char *mypattern = NULL; + os_strdup(pattern, mypattern); + char *tmp_pt = mypattern; + char *tmp_pattern = mypattern; + + while (tmp_pt != NULL) { + /* First look for " && " */ + tmp_pt = strchr(tmp_pattern, ' '); + if (tmp_pt && tmp_pt[1] == '&' && tmp_pt[2] == '&' && tmp_pt[3] == ' ') { + *tmp_pt = '\0'; + tmp_pt += 4; + } else { + tmp_pt = NULL; + } + + if (*tmp_pattern != '!') { + free(mypattern); + return 0; + } + + tmp_pattern = tmp_pt; + } + + debug1("pattern: %s is fill_negate", pattern); + free(mypattern); + return (1); +} + +/* Checks if the specific pattern is present on str. + * A pattern can be preceded by: + * =: (for equal) - default - strcasecmp + * r: (for openarmor regexes) + * >: (for strcmp greater) + * <: (for strcmp lower) + * + * Multiple patterns can be specified by using " && " between them. + * All of them must match for it to return true. + */ +int pt_matches(const char *str, char *pattern) +{ + int neg = 0; + int ret_code = 0; + char *tmp_pt = pattern; + char *tmp_ret = NULL; + + if (str == NULL) { + return (0); + } + + while (tmp_pt != NULL) { + /* First look for " && " */ + tmp_pt = strchr(pattern, ' '); + if (tmp_pt && tmp_pt[1] == '&' && tmp_pt[2] == '&' && tmp_pt[3] == ' ') { + /* Mark pointer to clean it up */ + tmp_ret = tmp_pt; + + *tmp_pt = '\0'; + tmp_pt += 4; + } else { + tmp_pt = NULL; + } + + /* Check for negate values */ + neg = 0; + ret_code = 0; + if (*pattern == '!') { + pattern++; + neg = 1; + } + + /* Do the actual comparison */ + if (strncasecmp(pattern, "=:", 2) == 0) { + pattern += 2; + if (strcasecmp(pattern, str) == 0) { + ret_code = 1; + } + } else if (strncasecmp(pattern, "r:", 2) == 0) { + pattern += 2; + if (OS_Regex(pattern, str)) { + debug1("pattern: %s matches %s.", pattern, str); + ret_code = 1; + } + } else if (strncasecmp(pattern, "<:", 2) == 0) { + pattern += 2; + if (strcmp(pattern, str) < 0) { + ret_code = 1; + } + } else if (strncasecmp(pattern, ">:", 2) == 0) { + pattern += 2; + if (strcmp(pattern, str) > 0) { + ret_code = 1; + } + } else { +#ifdef WIN32 + char final_file[2048 + 1]; + + /* Try to get Windows variable */ + if (*pattern == '%') { + final_file[0] = '\0'; + final_file[2048] = '\0'; + + ExpandEnvironmentStrings(pattern, final_file, 2047); + } else { + strncpy(final_file, pattern, 2047); + } + + /* Compare against the expanded variable */ + if (strcasecmp(final_file, str) == 0) { + ret_code = 1; + } +#else + if (strcasecmp(pattern, str) == 0) { + ret_code = 1; + } +#endif + } + /* Fix tmp_ret entry */ + if (tmp_ret != NULL) { + *tmp_ret = ' '; + tmp_ret = NULL; + } + + /* If we have "!", return true if we don't match */ + if (neg == 1) { + if (ret_code) { + ret_code = 0; + break; + } + } else { + if (!ret_code) { + ret_code = 0; + break; + } + } + + ret_code = 1; + pattern = tmp_pt; + } + + return (ret_code); +} + +/* Normalizes a string, removing white spaces and tabs + * from the beginning and the end of it. + */ +char *normalize_string(char *str) +{ + size_t str_sz = strlen(str); + /* Return zero-length str as is */ + if (str_sz == 0) { + return str; + } else { + str_sz--; + } + /* Remove trailing spaces */ + while (str[str_sz] == ' ' || str[str_sz] == '\t') { + if (str_sz == 0) { + break; + } + + str[str_sz--] = '\0'; + } + /* ignore leading spaces */ + while (*str != '\0') { + if (*str == ' ' || *str == '\t') { + str++; + } else { + break; + } + } + + return (str); +} + +/* Check if 'file' is present on 'dir' using readdir */ +int isfile_ondir(const char *file, const char *dir) +{ + DIR *dp = NULL; + struct dirent *entry; + dp = opendir(dir); + + if (!dp) { + return (0); + } + + while ((entry = readdir(dp)) != NULL) { + if (strcmp(entry->d_name, file) == 0) { + closedir(dp); + return (1); + } + } + + closedir(dp); + return (0); +} + +/* Check if the file is present using several methods + * to avoid being tricked by syscall hiding + */ +int is_file(char *file_name) +{ + int ret = 0; + struct stat statbuf; + FILE *fp = NULL; + DIR *dp = NULL; + +#ifndef WIN32 + char curr_dir[1024]; + char *file_dirname; + char *file_basename; + + curr_dir[1023] = '\0'; + + if (!getcwd(curr_dir, 1022)) { + return (0); + } + + /* Get dir name */ + file_basename = strrchr(file_name, '/'); + if (!file_basename) { + merror("%s: RK: Invalid file name: %s!", ARGV0, file_name); + return (0); + } + + /* If file_basename == file_name, then the file + * only has one slash at the beginning + */ + if (file_basename != file_name) { + /* Dir name and base name are now set */ + *file_basename = '\0'; + file_basename++; + file_dirname = file_name; + + /* chdir test */ + if (chdir(file_dirname) == 0) { + if (chdir(file_basename) == 0) { + ret = 1; + } + /* Check errno (if file exists, but it is not + * a directory. + */ + else if (errno == ENOTDIR) { + ret = 1; + } + + /* Trying open dir */ + dp = opendir(file_basename); + if (dp) { + closedir(dp); + ret = 1; + } else if (errno == ENOTDIR) { + ret = 1; + } + + /* Return to the previous directory */ + if (chdir(curr_dir) == -1) { + merror(CHDIR_ERROR, ARGV0, curr_dir, errno, strerror(errno)); + return (0); + } + } + + file_basename--; + *file_basename = '/'; + } else { + if (chdir(file_name) == 0) { + ret = 1; + + /* Return to the previous directory */ + if (chdir(curr_dir) == -1) { + merror(CHDIR_ERROR, ARGV0, curr_dir, errno, strerror(errno)); + return (0); + } + } else if (errno == ENOTDIR) { + ret = 1; + } + } + +#else + dp = opendir(file_name); + if (dp) { + closedir(dp); + ret = 1; + } +#endif /* WIN32 */ + /* Trying other calls */ + if ( (stat(file_name, &statbuf) < 0) && +#ifndef WIN32 + (access(file_name, F_OK) < 0) && +#endif + ((fp = fopen(file_name, "r")) == NULL)) { + return (ret); + } + + if (fp) { + fclose(fp); + } + + return (1); +} + +/* Delete the process list */ +int del_plist(OSList *p_list) +{ + OSListNode *l_node; + OSListNode *p_node = NULL; + + if (p_list == NULL) { + return (0); + } + + l_node = OSList_GetFirstNode(p_list); + while (l_node) { + Proc_Info *pinfo; + + pinfo = (Proc_Info *)l_node->data; + + if (pinfo->p_name) { + free(pinfo->p_name); + } + + if (pinfo->p_path) { + free(pinfo->p_path); + } + + free(l_node->data); + + if (p_node) { + free(p_node); + p_node = NULL; + } + p_node = l_node; + + l_node = OSList_GetNextNode(p_list); + } + + if (p_node) { + free(p_node); + p_node = NULL; + } + + free(p_list); + + return (1); +} + +/* Check if a process is running */ +int is_process(char *value, OSList *p_list) +{ + OSListNode *l_node; + if (p_list == NULL) { + return (0); + } + if (!value) { + return (0); + } + + l_node = OSList_GetFirstNode(p_list); + while (l_node) { + Proc_Info *pinfo; + + pinfo = (Proc_Info *)l_node->data; + + /* Check if value matches */ + if (pt_matches(pinfo->p_path, value)) { + int i = 0; + char _b_msg[OS_SIZE_1024 + 1]; + + _b_msg[OS_SIZE_1024] = '\0'; + + snprintf(_b_msg, OS_SIZE_1024, " Process: %s.", + pinfo->p_path); + + /* Already present */ + if (_is_str_in_array(rootcheck.alert_msg, _b_msg)) { + return (1); + } + + while (rootcheck.alert_msg[i] && (i < 255)) { + i++; + } + + if (!rootcheck.alert_msg[i]) { + os_strdup(_b_msg, rootcheck.alert_msg[i]); + } + + return (1); + } + + l_node = OSList_GetNextNode(p_list); + } + + return (0); +} + diff --git a/src/rootcheck/common_rcl.c b/src/rootcheck/common_rcl.c new file mode 100644 index 000000000..f92dda118 --- /dev/null +++ b/src/rootcheck/common_rcl.c @@ -0,0 +1,592 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + +/* Prototypes */ +static char *_rkcl_getfp(FILE *fp, char *buf); +static int _rkcl_is_name(const char *buf); +static int _rkcl_get_vars(OSStore *vars, char *nbuf); +static char *_rkcl_get_name(char *buf, char *ref, int *condition); +static char *_rkcl_get_pattern(char *value); +static char *_rkcl_get_value(char *buf, int *type); + +/* Types of values */ +#define RKCL_TYPE_FILE 1 +#define RKCL_TYPE_REGISTRY 2 +#define RKCL_TYPE_PROCESS 3 +#define RKCL_TYPE_DIR 4 + +#define RKCL_COND_ALL 0x001 +#define RKCL_COND_ANY 0x002 +#define RKCL_COND_REQ 0x004 +#define RKCL_COND_INV 0x010 + + +#ifdef WIN32 +char *_rkcl_getrootdir(char *root_dir, int dir_size) +{ + char final_file[2048 + 1]; + char *tmp; + + final_file[0] = '\0'; + final_file[2048] = '\0'; + + ExpandEnvironmentStrings("%WINDIR%", final_file, 2047); + + tmp = strchr(final_file, '\\'); + if (tmp) { + *tmp = '\0'; + strncpy(root_dir, final_file, dir_size); + return (root_dir); + } + + return (NULL); +} +#endif + +/* Get next available buffer in file */ +static char *_rkcl_getfp(FILE *fp, char *buf) +{ + while (fgets(buf, OS_SIZE_1024, fp) != NULL) { + char *nbuf; + + /* Remove end of line */ + nbuf = strchr(buf, '\n'); + if (nbuf) { + *nbuf = '\0'; + } + + /* Assign buf to be used */ + nbuf = buf; + + /* Exclude commented lines or blanked ones */ + while (*nbuf != '\0') { + if (*nbuf == ' ' || *nbuf == '\t') { + nbuf++; + continue; + } else if (*nbuf == '#') { + *nbuf = '\0'; + continue; + } else { + break; + } + } + + /* Go to next line if empty */ + if (*nbuf == '\0') { + continue; + } + + return (nbuf); + } + + return (NULL); +} + +static int _rkcl_is_name(const char *buf) +{ + if (*buf == '[' && buf[strlen(buf) - 1] == ']') { + return (1); + } + return (0); +} + +static int _rkcl_get_vars(OSStore *vars, char *nbuf) +{ + char *var_value; + char *tmp; + + /* If not a variable, return 0 */ + if (*nbuf != '$') { + return (0); + } + + /* Remove semicolon from the end */ + tmp = strchr(nbuf, ';'); + if (tmp) { + *tmp = '\0'; + } else { + return (-1); + } + + /* Get value */ + tmp = strchr(nbuf, '='); + if (tmp) { + *tmp = '\0'; + tmp++; + } else { + return (-1); + } + + /* Dump the variable options */ + os_strdup(tmp, var_value); + + /* Add entry to the storage */ + OSStore_Put(vars, nbuf, var_value); + return (1); +} + +static char *_rkcl_get_name(char *buf, char *ref, int *condition) +{ + char *tmp_location; + char *tmp_location2; + *condition = 0; + + /* Check if name is valid */ + if (!_rkcl_is_name(buf)) { + return (NULL); + } + + /* Set name */ + buf++; + tmp_location = strchr(buf, ']'); + if (!tmp_location) { + return (NULL); + } + *tmp_location = '\0'; + + /* Get condition */ + tmp_location++; + if (*tmp_location != ' ' && tmp_location[1] != '[') { + return (NULL); + } + tmp_location += 2; + + tmp_location2 = strchr(tmp_location, ']'); + if (!tmp_location2) { + return (NULL); + } + *tmp_location2 = '\0'; + tmp_location2++; + + /* Get condition */ + if (strcmp(tmp_location, "all") == 0) { + *condition |= RKCL_COND_ALL; + } else if (strcmp(tmp_location, "any") == 0) { + *condition |= RKCL_COND_ANY; + } else if (strcmp(tmp_location, "any required") == 0) { + *condition |= RKCL_COND_ANY; + *condition |= RKCL_COND_REQ; + } else if (strcmp(tmp_location, "all required") == 0) { + *condition |= RKCL_COND_ALL; + *condition |= RKCL_COND_REQ; + } else { + *condition = RKCL_COND_INV; + return (NULL); + } + + /* Get reference */ + if (*tmp_location2 != ' ' && tmp_location2[1] != '[') { + return (NULL); + } + + tmp_location2 += 2; + tmp_location = strchr(tmp_location2, ']'); + if (!tmp_location) { + return (NULL); + } + *tmp_location = '\0'; + + /* Copy reference */ + strncpy(ref, tmp_location2, 255); + + return (strdup(buf)); +} + +static char *_rkcl_get_pattern(char *value) +{ + while (*value != '\0') { + if ((*value == ' ') && (value[1] == '-') && + (value[2] == '>') && (value[3] == ' ')) { + *value = '\0'; + value += 4; + + return (value); + } + value++; + } + + return (NULL); +} + +static char *_rkcl_get_value(char *buf, int *type) +{ + char *tmp_str; + char *value; + + /* Zero type before using it to make sure return is valid + * in case of error. + */ + *type = 0; + + value = strchr(buf, ':'); + if (value == NULL) { + return (NULL); + } + + *value = '\0'; + value++; + + tmp_str = strchr(value, ';'); + if (tmp_str == NULL) { + return (NULL); + } + *tmp_str = '\0'; + + /* Get types - removing negate flag (using later) */ + if (*buf == '!') { + buf++; + } + + if (strcmp(buf, "f") == 0) { + *type = RKCL_TYPE_FILE; + } else if (strcmp(buf, "r") == 0) { + *type = RKCL_TYPE_REGISTRY; + } else if (strcmp(buf, "p") == 0) { + *type = RKCL_TYPE_PROCESS; + } else if (strcmp(buf, "d") == 0) { + *type = RKCL_TYPE_DIR; + } else { + return (NULL); + } + + return (value); +} + +int rkcl_get_entry(FILE *fp, const char *msg, OSList *p_list) +{ + int type = 0, condition = 0; + char *nbuf; + char buf[OS_SIZE_1024 + 2]; + char root_dir[OS_SIZE_1024 + 2]; + char final_file[2048 + 1]; + char ref[255 + 1]; + char *value; + char *name = NULL; + OSStore *vars; + + /* Initialize variables */ + memset(buf, '\0', sizeof(buf)); + memset(root_dir, '\0', sizeof(root_dir)); + memset(final_file, '\0', sizeof(final_file)); + memset(ref, '\0', sizeof(ref)); + +#ifdef WIN32 + /* Get Windows rootdir */ + _rkcl_getrootdir(root_dir, sizeof(root_dir) - 1); + if (root_dir[0] == '\0') { + merror(INVALID_ROOTDIR, ARGV0); + } +#endif + /* Get variables */ + vars = OSStore_Create(); + + /* We first read all variables -- they must be defined at the top */ + while (1) { + int rc_code = 0; + nbuf = _rkcl_getfp(fp, buf); + if (nbuf == NULL) { + goto clean_return; + } + + rc_code = _rkcl_get_vars(vars, nbuf); + if (rc_code == 0) { + break; + } else if (rc_code == -1) { + merror(INVALID_RKCL_VAR, ARGV0, nbuf); + goto clean_return; + } + } + + /* Get first name */ + name = _rkcl_get_name(nbuf, ref, &condition); + if (name == NULL || condition == RKCL_COND_INV) { + merror(INVALID_RKCL_NAME, ARGV0, nbuf); + goto clean_return; + } + + /* Get the real entries */ + do { + int g_found = 0; + + debug2("%s: DEBUG: Checking entry: '%s'.", ARGV0, name); + + /* Get each value */ + do { + int negate = 0; + int found = 0; + value = NULL; + + nbuf = _rkcl_getfp(fp, buf); + if (nbuf == NULL) { + break; + } + + /* First try to get the name, looking for new entries */ + if (_rkcl_is_name(nbuf)) { + break; + } + + /* Get value to look for */ + value = _rkcl_get_value(nbuf, &type); + if (value == NULL) { + merror(INVALID_RKCL_VALUE, ARGV0, nbuf); + goto clean_return; + } + + /* Get negate value */ + if (*value == '!') { + negate = 1; + value++; + } + + /* Check for a file */ + if (type == RKCL_TYPE_FILE) { + char *pattern = NULL; + char *f_value = NULL; + + pattern = _rkcl_get_pattern(value); + f_value = value; + + /* Get any variable */ + if (value[0] == '$') { + f_value = (char *) OSStore_Get(vars, value); + if (!f_value) { + merror(INVALID_RKCL_VAR, ARGV0, value); + continue; + } + } + +#ifdef WIN32 + else if (value[0] == '\\') { + final_file[0] = '\0'; + final_file[sizeof(final_file) - 1] = '\0'; + + snprintf(final_file, sizeof(final_file) - 2, "%s%s", + root_dir, value); + f_value = final_file; + } else { + final_file[0] = '\0'; + final_file[sizeof(final_file) - 1] = '\0'; + + ExpandEnvironmentStrings(value, final_file, + sizeof(final_file) - 2); + f_value = final_file; + } +#endif + + debug2("%s: DEBUG: Checking file: '%s'.", ARGV0, f_value); + if (rk_check_file(f_value, pattern)) { + debug1("%s: DEBUG: found file.", ARGV0); + found = 1; + } + } + +#ifdef WIN32 + /* Check for a registry entry */ + else if (type == RKCL_TYPE_REGISTRY) { + char *entry = NULL; + char *pattern = NULL; + + /* Look for additional entries in the registry + * and a pattern to match. + */ + entry = _rkcl_get_pattern(value); + if (entry) { + pattern = _rkcl_get_pattern(entry); + } + + debug2("%s: DEBUG: Checking registry: '%s'.", ARGV0, value); + if (is_registry(value, entry, pattern)) { + debug2("%s: DEBUG: found registry.", ARGV0); + found = 1; + } + + } +#endif + /* Check for a directory */ + else if (type == RKCL_TYPE_DIR) { + char *file = NULL; + char *pattern = NULL; + char *f_value = NULL; + char *dir = NULL; + + file = _rkcl_get_pattern(value); + if (!file) { + merror(INVALID_RKCL_VAR, ARGV0, value); + continue; + } + + pattern = _rkcl_get_pattern(file); + + /* Get any variable */ + if (value[0] == '$') { + f_value = (char *) OSStore_Get(vars, value); + if (!f_value) { + merror(INVALID_RKCL_VAR, ARGV0, value); + continue; + } + } else { + f_value = value; + } + + /* Check for multiple comma separated directories */ + dir = f_value; + f_value = strchr(dir, ','); + if (f_value) { + *f_value = '\0'; + } + + while (dir) { + + debug2("%s: Checking dir: %s", ARGV0, dir); + + short is_nfs = IsNFS(dir); + if( is_nfs == 1 && rootcheck.skip_nfs ) { + debug1("%s: DEBUG: rootcheck.skip_nfs enabled and %s is flagged as NFS.", ARGV0, dir); + } + else { + debug2("%s: DEBUG: %s => is_nfs=%d, skip_nfs=%d", ARGV0, dir, is_nfs, rootcheck.skip_nfs); + + if (rk_check_dir(dir, file, pattern)) { + debug2("%s: DEBUG: Found dir.", ARGV0); + found = 1; + } + } + + if (f_value) { + *f_value = ','; + f_value++; + + dir = f_value; + + f_value = strchr(dir, ','); + if (f_value) { + *f_value = '\0'; + } + } else { + dir = NULL; + } + } + } + + /* Check for a process */ + else if (type == RKCL_TYPE_PROCESS) { + debug2("%s: DEBUG: Checking process: '%s'.", ARGV0, value); + if (is_process(value, p_list)) { + debug2("%s: DEBUG: found process.", ARGV0); + found = 1; + } + } + + /* Switch the values if ! is present */ + if (negate) { + if (found) { + found = 0; + } else { + found = 1; + } + } + + /* Check the conditions */ + if (condition & RKCL_COND_ANY) { + debug2("%s: DEBUG: Condition ANY.", ARGV0); + if (found) { + g_found = 1; + } + } else { + /* Condition for ALL */ + debug2("%s: DEBUG: Condition ALL.", ARGV0); + if (found && (g_found != -1)) { + g_found = 1; + } else { + g_found = -1; + } + } + } while (value != NULL); + + /* Alert if necessary */ + if (g_found == 1) { + int j = 0; + char op_msg[OS_SIZE_1024 + 1]; + char **p_alert_msg = rootcheck.alert_msg; + + while (1) { + if (ref[0] != '\0') { + snprintf(op_msg, OS_SIZE_1024, "%s %s.%s" + " Reference: %s .", msg, name, + p_alert_msg[j] ? p_alert_msg[j] : "\0", + ref); + } else { + snprintf(op_msg, OS_SIZE_1024, "%s %s.%s", msg, + name, p_alert_msg[j] ? p_alert_msg[j] : "\0"); + } + + if ((type == RKCL_TYPE_DIR) || (j == 0)) { + notify_rk(ALERT_POLICY_VIOLATION, op_msg); + } + + if (p_alert_msg[j]) { + free(p_alert_msg[j]); + p_alert_msg[j] = NULL; + j++; + + if (!p_alert_msg[j]) { + break; + } + } else { + break; + } + } + } else { + int j = 0; + while (rootcheck.alert_msg[j]) { + free(rootcheck.alert_msg[j]); + rootcheck.alert_msg[j] = NULL; + j++; + } + + /* Check if this entry is required for the rest of the file */ + if (condition & RKCL_COND_REQ) { + goto clean_return; + } + } + + /* End if we don't have anything else */ + if (!nbuf) { + goto clean_return; + } + + /* Clean up name */ + if (name) { + free(name); + name = NULL; + } + + /* Get name already read */ + name = _rkcl_get_name(nbuf, ref, &condition); + if (!name) { + merror(INVALID_RKCL_NAME, ARGV0, nbuf); + goto clean_return; + } + } while (nbuf != NULL); + + /* Clean up memory */ +clean_return: + if (name) { + free(name); + name = NULL; + } + OSStore_Free(vars); + + return (1); +} + diff --git a/src/rootcheck/config.c b/src/rootcheck/config.c new file mode 100644 index 000000000..20518194c --- /dev/null +++ b/src/rootcheck/config.c @@ -0,0 +1,35 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifdef openarmorHIDS +#include "shared.h" +#include "rootcheck.h" +#include "config/config.h" + + +/* Read the rootcheck config */ +int Read_Rootcheck_Config(const char *cfgfile) +{ + int modules = 0; + + modules |= CROOTCHECK; + if (ReadConfig(modules, cfgfile, &rootcheck, NULL) < 0) { + return (OS_INVALID); + } + +#ifdef CLIENT + /* Read shared config */ + modules |= CAGENT_CONFIG; + ReadConfig(modules, AGENTCONFIG, &rootcheck, NULL); +#endif + + return (0); +} +#endif /* openarmorHIDS */ + diff --git a/src/rootcheck/db/acsc_office2016_rcl.txt b/src/rootcheck/db/acsc_office2016_rcl.txt new file mode 100644 index 000000000..e6a5ee1bd --- /dev/null +++ b/src/rootcheck/db/acsc_office2016_rcl.txt @@ -0,0 +1,427 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# Hardening Checks for Microsoft Office 2016 +# Based on Australian Cyper Security Centre Hardening Microsoft Office Guide - May 2018 (https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf) +# +# +#7 Ensure Attack Surface Reduction is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7 Ensure Attack Surface Reduction is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> ExploitGuard_ASR_Rules -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> !ExploitGuard_ASR_Rules; +# +# +#7a Ensure 'Block executable content from email client and webmail' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7a Ensure 'Block executable content from email client and webmail' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550; +# +# +#7b Ensure 'block Office applications from creating child processes' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7b Ensure 'block Office applications from creating child processes' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D4F940AB-401B-4EFC-AADC-AD5F3C50688A -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D4F940AB-401B-4EFC-AADC-AD5F3C50688A; +# +# +#7c Ensure 'block Office applications from creating executable content' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7c Ensure 'block Office applications from creating executable content' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 3B576869-A4EC-4529-8536-B80A7769E899 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !3B576869-A4EC-4529-8536-B80A7769E899; +# +# +#7d Ensure 'block Office applications from injecting code into other processes' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7d Ensure 'block Office applications from injecting code into other processes' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84; +# +# +#7e Ensure 'block JavaScript and VBScript from launching downloaded executable content' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7e Ensure 'block JavaScript and VBScript from launching downloaded executable content' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D3E037E1-3EB8-44C8-A917-57927947596D -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D3E037E1-3EB8-44C8-A917-57927947596D; +# +# +#7f Ensure 'block execution of potentially obfuscated scripts' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7f Ensure 'block execution of potentially obfuscated scripts' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !5BEB7EFE-FD9A-4556-801D-275E5FFC04CC; +# +# +#7g Ensure 'block Win32 API calls from Office macro' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 7g Ensure 'block Win32 API calls from Office macro' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B; +# +# +#17 Ensure 'Disable All Active X' is set to 'Enabled' +[ACSC - Microsoft Office 2016 - 17 Ensure 'Disable All Active X' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\common\security -> disableallactivex -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\common\security -> !disableallactivex; +# +# +#19a Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Excel +[ACSC - Microsoft Office 2016 - 19a Ensure'Block all unmanaged add-ins' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency -> restricttolist -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency -> !restricttolist; +# +# +#19b Ensure 'List of managed add-ins' is set to 'Enabled' for Excel +[ACSC - Microsoft Office 2016 - 19b Ensure 'List of managed add-ins' is set to 'Enabled'] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency\addinlist -> policyon -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\resiliency\addinlist -> !policyon; +# +# +#19c Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Excel +[ACSC - Microsoft Office 2016 - 19c Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency -> restricttolist -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency -> !restricttolist; +# +# +#19d Ensure 'List of managed add-ins' is set to 'Enabled' for PowerPoint +[ACSC - Microsoft Office 2016 - 19d Ensure 'List of managed add-ins' is set to 'Enabled' for PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency\addinlist -> policyon -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\resiliency\addinlist -> !policyon; +# +# +#19e Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Word +[ACSC - Microsoft Office 2016 - 19e Ensure'Block all unmanaged add-ins' is set to 'Enabled' for Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency -> restricttolist -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency -> !restricttolist; +# +# +#19f Ensure 'List of managed add-ins' is set to 'Enabled' for Word +[ACSC - Microsoft Office 2016 - 19f Ensure 'List of managed add-ins' is set to 'Enabled' for Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency\addinlist -> policyon -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\resiliency\addinlist -> !policyon; +# +# +#21 Ensure if Extension Hardening functionality in Microsoft Excel is enabled +[ACSC - Microsoft Office 2016 - 21 Ensure if Extension Hardening functionality in Microsoft Excel is enabled] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security -> extensionhardening -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security -> !extensionhardening; +# +# +#23a Ensure dBase III / IV files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23a Ensure dBase III / IV files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> dbasefiles -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !dbasefiles; +# +# +#23b Ensure Dif and Sylk files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23b Ensure Dif and Sylk files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> difandsylkfiles -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !difandsylkfiles; +# +# +#23c Ensure Excel 2 macrosheets and add-in files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23c Ensure Excel 2 macrosheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl2macros -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl2macros; +# +# +#23d Ensure Excel 2 worksheets are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23d Ensure Excel 2 worksheets are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl2worksheets -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl2worksheets; +# +# +#23e Ensure Excel 3 macrosheets and add-in files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23e Ensure Excel 3 macrosheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl3macros -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl3macros; +# +# +#23f Ensure Excel 3 worksheets and add-in files are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23f Ensure Excel 3 worksheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl3worksheets -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl3worksheets; +# +# +#23g Ensure Excel 4 macrosheets and add-in files are blocked in Microsoft Escel +[ACSC - Microsoft Office 2016 - 23g Ensure Excel 4 macrosheets and add-in files are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl4macros -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl4macros; +# +# +#23h Ensure Excel 4 workbooks are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23h Ensure Excel 4 workbooks are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl4workbooks -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl4workbooks; +# +# +#23i Ensure Excel 4 worksheets are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23i Ensure Excel 4 worksheets are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl4worksheets -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl4worksheets; +# +# +#23j Ensure Excel 95 workbooks are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23j Ensure Excel 95 workbooks are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl95workbooks -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl95workbooks; +# +# +#23k Ensure Excel 95-97 workbooks and templates are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23k Ensure Excel 95-97 workbooks and templates are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> xl9597workbooksandtemplates -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !xl9597workbooksandtemplates; +# +# +#23l Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Excel +[ACSC - Microsoft Office 2016 - l Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !openinprotectedview; +# +# +#23m Ensure Web pages and Excel 2003 XML spreadsheets are blocked in Microsoft Excel +[ACSC - Microsoft Office 2016 - 23m Ensure Web pages and Excel 2003 XML spreadsheets are blocked in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> htmlandxmlssfiles -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\fileblock -> !htmlandxmlssfiles; +# +# +#23n Ensure PowerPoint beta converters are blocked in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 23n Ensure PowerPoint beta converters are blocked in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> powerpoint12betafilesfromconverters -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> !powerpoint12betafilesfromconverters; +# +# +#23o Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Powerpoint +[ACSC - Microsoft Office 2016 - 23o Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Powerpoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\fileblock -> !openinprotectedview; +# +# +#23p Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Word +[ACSC - Microsoft Office 2016 - 23p Ensure Set default file block behavior is set to 'Enabled' (Blocked files are not opened) in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !openinprotectedview; +# +# +#23q Ensure Word 2 and earlier binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23q Ensure Word 2 and earlier binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word2files -> !2; +# +# +#23r Ensure Word 6.0 binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23r Ensure Word 6.0 binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word60files -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !word60files; +# +# +#23s Ensure Word 95 binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23s Ensure Word 95 binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word95files -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !word95files; +# +# +#23t Ensure Word 97 binary documents and templates are blocked in Microsoft Word +[ACSC - Microsoft Office 2016 - 23t Ensure Word 97 binary documents and templates are blocked in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> word97files -> !2; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\fileblock -> !word97files; +# +# +#25a Ensure Make hidden markup visible is set to 'Enabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 25a Ensure Make hidden markup visible is set to 'Enabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\options -> markupopensave -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\options -> !markupopensave; +# +# +#25b Ensure Make hidden markup visible is set to 'Enabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 25b Ensure Make hidden markup visible is set to 'Enabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\options -> showmarkupopensave -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\options -> !showmarkupopensave; +# +# +#27a Ensure Turn off error reporting for files that fail file validation is set to 'Enabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 27a Ensure Turn off error reporting for files that fail file validation is set to 'Enabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\security\filevalidation -> disablereporting -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\security\filevalidation -> !disablereporting; +# +# +#27b Ensure Turn off file validation ins set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 27b Ensure Turn off file validation ins set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> enableonload -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> !enableonload; +# +# +#27c Ensure Turn off file validation ins set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 27c Ensure Turn off file validation ins set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> enableonload -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> !enableonload; +# +# +#27d Ensure Turn off file validation ins set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 27d Ensure Turn off file validation ins set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> enableonload -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> !enableonload; +# +# +#29a Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29a Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> disableinternetfilesinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> !disableinternetfilesinpv; +# +# +#29b Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29b Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> disableunsafelocationsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> !disableunsafelocationsinpv; +# +# +#29c Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29c Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\filevalidation -> !openinprotectedview; +# +# +#29d Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 29d Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> disableattachmentsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\protectedview -> !disableattachmentsinpv; +# +# +#29e Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29e Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> disableinternetfilesinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> !disableinternetfilesinpv; +# +# +#29f Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29f Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> disableunsafelocationsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> !disableunsafelocationsinpv; +# +# +#29g Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29g Ensure Set document behaviour if file validation fails is set to 'Enabled' (Block files) in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\filevalidation -> !openinprotectedview; +# +# +#29h Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft PowerPoint +[ACSC - Microsoft Office 2016 - 29h Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft PowerPoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> disableattachmentsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\protectedview -> !disableattachmentsinpv; +# +# +#29i Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 29i Ensure Do not open files from the Internet zone in Protected View is set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableinternetfilesinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableinternetfilesinpv; +# +# +#29j Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 29j Ensure Do not open files in unsafe locations in Protected View is set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableunsafelocationsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> !disableunsafelocationsinpv; +# +# +#29k Ensure Set document behaviour if file validation fails is set to 'Enable' (Block files) in Microsoft Word +[ACSC - Microsoft Office 2016 - 29k Ensure Set document behaviour if file validation fails is set to 'Enable' (Block files) in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> openinprotectedview -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\filevalidation -> !openinprotectedview; +# +# +#29l Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 29l Ensure Turn off Protected View for attachments opened from Outlook is set to 'Disabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> disableattachmentsinpv -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\protectedview -> !disableattachmentsinpv; +# +# +#31a Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 31a Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> disabletrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> !disabletrusteddocuments; +# +# +#31b Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Excel +[ACSC - Microsoft Office 2016 - 31b Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Excel] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> disablenetworktrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\excel\security\trusted documents -> !disablenetworktrusteddocuments; +# +# +#31c Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Powerpoint +[ACSC - Microsoft Office 2016 - 31c Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Powerpoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> disabletrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> !disabletrusteddocuments; +# +# +#31d Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Powerpoint +[ACSC - Microsoft Office 2016 - 31d Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Powerpoint] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> disablenetworktrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\powerpoint\security\trusted documents -> disabletrusteddocuments -> !disablenetworktrusteddocuments; +# +# +#31e Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 31e Ensure Turn off trusted documents is set to 'Enabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> disabletrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> !disabletrusteddocuments; +# +# +#31f Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Word +[ACSC - Microsoft Office 2016 - 31f Ensure Turn off Trusted Documents on the network is set to 'Enabled' in Microsoft Word] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> disablenetworktrusteddocuments -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\word\security\trusted documents -> !disablenetworktrusteddocuments; +# +# +#34a Ensure Allow including screenshot with Office Feedback is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34a Ensure Allow including screenshot with Office Feedback is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> includescreenshot -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> !includescreenshot; +# +# +#34b Ensure Automatically receive small updates to improve reliability is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34b Ensure Automatically receive small updates to improve reliability is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> updatereliabilitydata -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> !updatereliabilitydata; +# +# +#34c Ensure Disable Opt-in Wizard on first run is set to 'Enabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34c Ensure Disable Opt-in Wizard on first run is set to 'Enabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\general -> shownfirstrunoptin -> !1; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\general -> !shownfirstrunoptin; +# +# +#34d Ensure Enable Customer Experience Improvement Program is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34d Ensure Enable Customer Experience Improvement Program is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> qmenable -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> !qmenable; +# +# +#34e Ensure Page Send Office Feedback is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34e Ensure Page Send Office Feedback is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> enabled -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common\feedback -> !enabled; +# +# +#34f Ensure Send personal information is set to 'Disabled' in Microsoft Office +[ACSC - Microsoft Office 2016 - 34f Ensure Send personal information is set to 'Disabled' in Microsoft Office] [any] [https://acsc.gov.au/publications/protect/Hardening_MS_Office_2016.pdf] +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> sendcustomerdata -> !0; +r:HKEY_CURRENT_USER\software\policies\microsoft\office\16.0\common -> !sendcustomerdata; +# +# +# diff --git a/src/rootcheck/db/cis_apache2224_rcl.txt b/src/rootcheck/db/cis_apache2224_rcl.txt new file mode 100644 index 000000000..aa3c92126 --- /dev/null +++ b/src/rootcheck/db/cis_apache2224_rcl.txt @@ -0,0 +1,505 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Apache Https Server +# Based on Center for Internet Security Benchmark for Apache HttpSserver 2.4 v1.3.1 and Apache HttpsServer 2.2 v3.4.1 (https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308) +# +# +$main-conf=/etc/apache2/apache2.conf,/etc/httpd/conf/httpd.conf; +$conf-dirs=/etc/apache2/conf-enabled,/etc/apache2/mods-enabled,/etc/apache2/sites-enabled,/etc/httpd/conf.d,/etc/httpd/modsecurity.d; +$ssl-confs=/etc/apache2/mods-enabled/ssl.conf,/etc/httpd/conf.d/ssl.conf; +$mods-en=/etc/apache2/mods-enabled; +$request-confs=/etc/httpd/conf/httpd.conf,/etc/apache2/mods-enabled/reqtimeout.conf; +$traceen=/etc/apache2/apache2.conf,/etc/httpd/conf/httpd.conf,/etc/apache2/conf-enabled/security.conf; +# +# +#2.3 Disable WebDAV Modules +[CIS - Apache Configuration - 2.3: WebDAV Modules are enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sdav; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sdav; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sdav; +d:$mods-en -> dav.load; +# +# +#2.4 Disable Status Module +[CIS - Apache Configuration - 2.4: Status Module is enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sstatus; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sstatus; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sstatus; +d:$mods-en -> status.load; +# +# +#2.5 Disable Autoindex Module +[CIS - Apache Configuration - 2.5: Autoindex Module is enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sautoindex; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sautoindex; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sautoindex; +d:$mods-en -> autoindex.load; +# +# +#2.6 Disable Proxy Modules +[CIS - Apache Configuration - 2.6: Proxy Modules are enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sproxy; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sproxy; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\sproxy; +d:$mods-en -> proxy.load; +# +# +#2.7 Disable User Directories Modules +[CIS - Apache Configuration - 2.7: User Directories Modules are enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\suserdir; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\suserdir; +f:/etc/httpd/conf.d -> !r:^# && r:loadmodule\suserdir; +d:$mods-en -> userdir.load; +# +# +#2.8 Disable Info Module +[CIS - Apache Configuration - 2.8: Info Module is enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sinfo; +d:$conf-dirs -> load -> !r:^# && r:loadmodule\sinfo; +d:$conf-dirs -> conf -> !r:^# && r:loadmodule\sinfo; +d:$mods-en -> info.load; +# +# +#3.2 Give the Apache User Account an Invalid Shell +[CIS - Apache Configuration - 3.2: Apache User Account has got a valid shell] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/passwd -> r:/var/www && !r:\.*/bin/false$|/sbin/nologin$; +# +# +#3.3 Lock the Apache User Account +[CIS - Apache Configuration - 3.3: Lock the Apache User Account] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/shadow -> r:^daemon|^wwwrun|^www-data|^apache && !r:\p!\.*$; +# +# +#4.4 Restrict Override for All Directories +[CIS - Apache Configuration - 4.4: Restrict Override for All Directories] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && !r:\w+ && r:allowoverride && !r:none$; +d:$conf-dirs -> conf -> !r:^# && !r:\w+ && r:allowoverridelist; +f:$main-conf -> !r:^# && !r:\w+ && r:allowoverride && !r:none$; +f:$main-conf -> !r:^# && !r:\w+ && r:allowoverridelist; +# +# +#5.3 Minimize Options for Other Directories +[CIS - Apache Configuration - 5.3: Minimize Options for other directories] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:options\sincludes; +f:$main-conf -> !r:^# && r:options\sincludes; +# +# +#5.4.1 Remove default index.html sites +[CIS - Apache Configuration - 5.4.1: Remove default index.html sites] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/var/www -> index.html; +d:/var/www/html -> index.html; +# +# +#5.4.2 Remove the Apache user manual +[CIS - Apache Configuration - 5.4.2: Remove the Apache user manual] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/etc/httpd/conf.d -> manual.conf; +d:/etc/apache2/conf-enabled -> apache2-doc.conf; +# +# +#5.4.5 Verify that no Handler is enabled +[CIS - Apache Configuration - 5.4.5: A Handler is configured] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:/wsethandler; +f:$main-conf -> !r:^# && r:/wsethandler; +# +# +#5.5 Remove default CGI content printenv +[CIS - Apache Configuration - 5.5: Remove default CGI content printenv] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/var/www/cgi-bin -> printenv; +d:/usr/lib/cgi-bin -> printenv; +# +# +#5.6 Remove default CGI content test-cgi +[CIS - Apache Configuration - 5.6: Remove default CGI content test-cgi] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:/var/www/cgi-bin -> test-cgi; +d:/usr/lib/cgi-bin -> test-cgi; +# +# +#5.7 Limit HTTP Request Method +[CIS - Apache Configuration - 5.7: Disable HTTP Request Method] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:; +# +# +#5.8 Disable HTTP Trace Method +[CIS - Apache Configuration - 5.8: Disable HTTP Trace Method] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$traceen -> !r:^# && r:traceenable\s+on\s*$; +# +# +#5.9 Restrict HTTP Protocol Versions +[CIS - Apache Configuration - 5.9: Restrict HTTP Protocol Versions] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:loadmodule\srewrite; +d:$mods-en -> !f:rewrite.load; +f:$main-conf -> !r:rewriteengine\son; +f:$main-conf -> !r:rewritecond && !r:%{THE_REQUEST} && !r:!HTTP/1\\.1\$; +f:$main-conf -> !r:rewriterule && !r:.* - [F]; +# +# +#5.12 Deny IP Address Based Requests +[CIS - Apache Configuration - 5.12: Deny IP Address Based Requests] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:loadmodule\srewrite; +d:$mods-en -> !f:rewrite.load; +f:$main-conf -> !r:rewriteengine\son; +f:$main-conf -> !r:rewritecond && !r:%{HTTP_HOST} && !r:www\\.\w+\\.\w+ [NC]$; +f:$main-conf -> !r:rewritecond && !r:%{REQUEST_URI} && !r:/error [NC]$; +f:$main-conf -> !r:rewriterule && !r:.\(.*\) - [L,F]$; +# +# +#5.13 Restrict Listen Directive +[CIS - Apache Configuration - 5.13: Restrict Listen Directive] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:listen\s80$; +d:$conf-dirs -> conf -> !r:^# && r:listen\s0.0.0.0\p80; +d:$conf-dirs -> conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p80; +f:$main-conf -> !r:^# && r:listen\s80$; +f:$main-conf -> !r:^# && r:listen\s0.0.0.0\p\d*; +f:$main-conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p\d*; +f:/etc/apache2/sites-enabled/000-default.conf -> !r:^# && r:listen\s80$; +f:/etc/apache2/sites-enabled/000-default.conf -> !r:^# && r:listen\s0.0.0.0\p\d*; +f:/etc/apache2/sites-enabled/000-default.conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p\d*; +f:/etc/apache2/ports.conf -> !r:^# && r:listen\s80$; +f:/etc/apache2/ports.conf -> !r:^# && r:listen\s0.0.0.0\p\d*; +f:/etc/apache2/ports.conf -> !r:^# && r:listen\s[\p\pffff\p0.0.0.0]\p\d*; +# +# +#5.14 Restrict Browser Frame Options +[CIS - Apache Configuration - 5.14: Restrict Browser Frame Options] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:header\salways\sappend\sx-frame-options && !r:sameorigin|deny; +# +# +#6.1 Configure the Error Log to notice at least +[CIS - Apache Configuration - 6.1: Configure the Error Log to notice at least] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^# && r:loglevel\snotice\score\p && r:warn|emerg|alert|crit|error|notice; +f:$main-conf -> !r:loglevel\snotice\score\p && !r:info|debug; +# +# +#6.2 Configure a Syslog facility for Error Log +[CIS - Apache Configuration - 6.2: Configure a Syslog facility for Error Log] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:errorlog\s+\p*syslog\p\.*\p*; +# +# +#7.6 Disable SSL Insecure Renegotiation +[CIS - Apache Configuration - 7.6: Disable SSL Insecure Renegotiation] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$ssl-confs -> !r:^\t*\s*# && r:sslinsecurerenegotiation\s+on\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslinsecurerenegotiation\s*$; +# +# +#7.7 Ensure SSL Compression is not enabled +[CIS - Apache Configuration - 7.7: Ensure SSL Compression is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$ssl-confs -> !r:^\t*\s*# && r:sslcompression\s+on\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslcompression\s*$; +# +# +#7.8 Disable SSL TLS v1.0 Protocol +[CIS - Apache Configuration - 7.8: Disable insecure TLS Protocol] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$ssl-confs -> !r:^\t*\s*sslprotocol; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+all; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+\.*tlsv1\P\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+\.*sslv2\P\s*; +f:$ssl-confs -> !r:^\t*\s*# && r:sslprotocol\s+\.*sslv3\P\s*; +# +# +#7.9 Enable OCSP Stapling +[CIS - Apache Configuration - 7.9: Enable OCSP Stapling] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:^loadmodule\s+ssl; +d:$mods-en -> !f:ssl.load; +f:$ssl-confs -> !r:\t*\s*# && r:sslusestapling\s+off; +f:$ssl-confs -> !r:\t*\s*sslusestapling\s+on; +f:$ssl-confs -> !r:\t*\s*sslstaplingcache\s+\.+; +# +# +#7.10 Enable HTTP Strict Transport Security +[CIS - Apache Configuration - 7.10: Enable HTTP Strict Transport Security] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/apache2/apache2.conf -> !r:Header\salways\sset\sStrict-Transport-Security\s"max-age=\d\d\d\d*"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=1\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=2\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=3\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=4\d\d"; +f:/etc/apache2/apache2.conf -> !r:^# && r:Header\salways\sset\sStrict-Transport-Security\s"max-age=5\d\d"; +# +# +#8.1 Set ServerToken to Prod or ProductOnly +[CIS - Apache Configuration - 8.1: Set ServerToken to Prod or ProductOnly] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+major; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+minor; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+min; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+minimal; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+os; +d:$conf-dirs -> conf -> !r:^# && r:servertokens\s+full; +# +# +#8.2: Set ServerSignature to Off +[CIS - Apache Configuration - 8.2: Set ServerSignature to Off] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^# && r:serversignature\s+email; +d:$conf-dirs -> conf -> !r:^# && r:serversignature\s+on; +# +# +#8.3: Prevent Information Leakage via Default Apache Content +[CIS - Apache Configuration - 8.3: Prevent Information Leakage via Default Apache Content] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +d:$conf-dirs -> conf -> !r:^\t*\s*# && r:include\s*\w*httpd-autoindex.conf; +d:$conf-dirs -> conf -> !r:^\t*\s*# && r:alias\s*/icons/\s*\.*; +# +# +#9.1:Set TimeOut to 10 or less +[CIS - Apache Configuration - 9.1: Set TimeOut to 10 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^# && r:timeout\s+9\d; +f:$main-conf -> !r:^# && r:timeout\s+8\d; +f:$main-conf -> !r:^# && r:timeout\s+7\d; +f:$main-conf -> !r:^# && r:timeout\s+6\d; +f:$main-conf -> !r:^# && r:timeout\s+5\d; +f:$main-conf -> !r:^# && r:timeout\s+4\d; +f:$main-conf -> !r:^# && r:timeout\s+3\d; +f:$main-conf -> !r:^# && r:timeout\s+2\d; +f:$main-conf -> !r:^# && r:timeout\s+11; +f:$main-conf -> !r:^# && r:timeout\s+12; +f:$main-conf -> !r:^# && r:timeout\s+13; +f:$main-conf -> !r:^# && r:timeout\s+14; +f:$main-conf -> !r:^# && r:timeout\s+15; +f:$main-conf -> !r:^# && r:timeout\s+16; +f:$main-conf -> !r:^# && r:timeout\s+17; +f:$main-conf -> !r:^# && r:timeout\s+18; +f:$main-conf -> !r:^# && r:timeout\s+19; +f:$main-conf -> !r:^timeout\s+\d\d*; +f:$main-conf -> !r:^# && r:timeout\s+\d\d\d+; +# +# +#9.2:Set the KeepAlive directive to On +[CIS - Apache Configuration - 9.2: Set the KeepAlive directive to On] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^# && r:keepalive\s+off; +f:$main-conf -> !r:keepalive\s+on; +# +# +#9.3:Set MaxKeepAliveRequests to 100 or greater +[CIS - Apache Configuration - 9.3: Set MaxKeepAliveRequest to 100 or greater] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^maxkeepaliverequests\s+\d\d\d+; +# +# +#9.4: Set KeepAliveTimeout Low to Mitigate Denial of Service +[CIS - Apache Configuration - 9.4: Set KeepAliveTimeout Low] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:keepalivetimeout\s+\d\d*; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+16; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+17; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+18; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+19; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+2\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+3\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+4\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+5\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+6\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+7\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+8\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+9\d; +f:$main-conf -> !r:^# && r:keepalivetimeout\s+\d\d\d+; +# +# +#9.5 Set Timeout Limits for Request Headers +[CIS - Apache Configuration - 9.5: Set Timeout Limits for Request Headers] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:^loadmodule\s+reqtimeout; +d:$mods-en -> !f:reqtimeout.load; +f:$request-confs -> !r:^\t*\s*requestreadtimeout\.+header\p\d\d*\D\d\d*; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D41; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D42; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D43; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D44; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D45; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D46; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D47; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D48; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D49; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D5\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D6\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D7\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D8\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D9\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+header\p\d\d\D\d\d\d+; +# +# +#9.6 Set Timeout Limits for Request Body +[CIS - Apache Configuration - 9.6: Set Timeout Limits for Request Body] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:/etc/httpd/conf/httpd.conf -> !r:^loadmodule\s+reqtimeout; +d:$mods-en -> !f:reqtimeout.load; +f:$request-confs -> !r:\t*\s*requestreadtimeout\.+body\p\d\d*; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p21; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p22; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p23; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p24; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p25; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p26; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p27; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p28; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p29; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p3\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p4\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p5\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p6\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p7\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p8\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p9\d; +f:$request-confs -> !r:^\t*\s*# && r:\t*\s*requestreadtimeout\.+body\p\d\d\d+; +# +# +#10.1 Set the LimitRequestLine directive to 512 or less +[CIS - Apache Configuration - 10.1: Set LimitRequestLine to 512 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestline\s+\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\13; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\14; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\15; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\16; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\17; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\18; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\19; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\2\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\3\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\4\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\5\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\6\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\7\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\8\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+5\9\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+6\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+7\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+8\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+9\d\d; +f:$main-conf -> !r:^# && r:limitrequestline\s+\d\d\d\d+; +# +# +#10.2 Set the LimitRequestFields directive to 100 or less +[CIS - Apache Configuration - 10.2: Set LimitRequestFields to 100 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestfields\s\d\d*; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d1; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d2; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d3; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d4; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d5; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d6; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d7; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d8; +f:$main-conf -> !r:^# && r:limitrequestfields\s+1\d9; +f:$main-conf -> !r:^# && r:limitrequestfields\s+11\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+12\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+13\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+14\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+15\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+16\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+17\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+18\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+19\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+2\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+3\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+4\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+5\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+6\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+7\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+8\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+9\d\d; +f:$main-conf -> !r:^# && r:limitrequestfields\s+\d\d\d\d+; +# +# +#10.3 Set the LimitRequestFieldsize directive to 1024 or less +[CIS - Apache Configuration - 10.3: Set LimitRequestFieldsize to 1024 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestfieldsize\s+\d\d*; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d25; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d26; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d27; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d28; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d29; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d3\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d4\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d5\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d6\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d7\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d8\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+1\d9\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+11\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+12\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+13\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+14\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+15\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+16\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+17\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+18\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+19\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+2\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+3\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+4\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+5\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+6\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+7\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+8\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+9\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestfieldsize\s+\d\d\d\d\d+; +# +# +#10.4 Set the LimitRequestBody directive to 102400 or less +[CIS - Apache Configuration - 10.4: Set LimitRequestBody to 102400 or less] [any] [https://workbench.cisecurity.org/benchmarks/307, https://workbench.cisecurity.org/benchmarks/308] +f:$main-conf -> !r:^limitrequestbody\s+\d\d*; +f:$main-conf -> !r:^# && r:limitrequestbody\s+0\s*$; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d1; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d2; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d3; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d4; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d5; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d6; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d7; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d8; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d24\d9; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d241\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d242\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d243\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d244\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d245\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d246\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d247\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d248\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d249\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d25\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d26\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d27\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d28\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d29\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d3\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d4\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d5\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d6\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d7\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d8\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+1\d9\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+11\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+12\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+13\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+14\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+15\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+16\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+17\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+18\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+19\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+2\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+3\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+4\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+5\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+6\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+7\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+8\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+9\d\d\d\d\d; +f:$main-conf -> !r:^# && r:limitrequestbody\s+\d\d\d\d\d\d\d+; diff --git a/src/rootcheck/db/cis_debian_linux_rcl.txt b/src/rootcheck/db/cis_debian_linux_rcl.txt new file mode 100644 index 000000000..949fd4fe1 --- /dev/null +++ b/src/rootcheck/db/cis_debian_linux_rcl.txt @@ -0,0 +1,196 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Debian/Ubuntu +# Based on Center for Internet Security Benchmark for Debian Linux v1.0 + +# Main one. Only valid for Debian/Ubuntu. +[CIS - Testing against the CIS Debian Linux Benchmark v1.0] [all required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/debian_version; +f:/proc/sys/kernel/ostype -> Linux; + + +# Section 1.4 - Partition scheme. +[CIS - Debian Linux - 1.4 - Robust partition scheme - /tmp is not on its own partition {CIS: 1.4 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +[CIS - Debian Linux - 1.4 - Robust partition scheme - /opt is not on its own partition {CIS: 1.4 Debian Linux}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/opt; +f:/etc/fstab -> !r:/opt; + +[CIS - Debian Linux - 1.4 - Robust partition scheme - /var is not on its own partition {CIS: 1.4 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:/var; + + +# Section 2.3 - SSH configuration +[CIS - Debian Linux - 2.3 - SSH Configuration - Protocol version 1 enabled {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +[CIS - Debian Linux - 2.3 - SSH Configuration - IgnoreRHosts disabled {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +[CIS - Debian Linux - 2.3 - SSH Configuration - Empty passwords permitted {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +[CIS - Debian Linux - 2.3 - SSH Configuration - Host based authentication enabled {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +[CIS - Debian Linux - 2.3 - SSH Configuration - Root login allowed {CIS: 2.3 Debian Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + + +# Section 2.4 Enable system accounting +#[CIS - Debian Linux - 2.4 - System Accounting - Sysstat not installed {CIS: 2.4 Debian Linux}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +#f:!/etc/default/sysstat; +#f:!/var/log/sysstat; + +#[CIS - Debian Linux - 2.4 - System Accounting - Sysstat not enabled {CIS: 2.4 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +#f:!/etc/default/sysstat; +#f:/etc/default/sysstat -> !r:^# && r:ENABLED="false"; + + +# Section 2.5 Install and run Bastille +#[CIS - Debian Linux - 2.5 - System harderning - Bastille is not installed {CIS: 2.5 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +#f:!/etc/Bastille; + + +# Section 2.6 Ensure sources.list Sanity +[CIS - Debian Linux - 2.6 - Sources list sanity - Security updates not enabled {CIS: 2.6 Debian Linux} {PCI_DSS: 6.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:!/etc/apt/sources.list; +f:!/etc/apt/sources.list -> !r:^# && r:http://security.debian|http://security.ubuntu; + + +# Section 3 - Minimize inetd services +[CIS - Debian Linux - 3.3 - Telnet enabled on inetd {CIS: 3.3 Debian Linux} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:telnet; + +[CIS - Debian Linux - 3.4 - FTP enabled on inetd {CIS: 3.4 Debian Linux} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:/ftp; + +[CIS - Debian Linux - 3.5 - rsh/rlogin/rcp enabled on inetd {CIS: 3.5 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:shell|login; + +[CIS - Debian Linux - 3.6 - tftpd enabled on inetd {CIS: 3.6 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:tftp; + +[CIS - Debian Linux - 3.7 - imap enabled on inetd {CIS: 3.7 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:imap; + +[CIS - Debian Linux - 3.8 - pop3 enabled on inetd {CIS: 3.8 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:pop; + +[CIS - Debian Linux - 3.9 - Ident enabled on inetd {CIS: 3.9 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inetd.conf -> !r:^# && r:ident; + + +# Section 4 - Minimize boot services +[CIS - Debian Linux - 4.1 - Disable inetd - Inetd enabled but no services running {CIS: 4.1 Debian Linux} {PCI_DSS: 2.2.2}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +p:inetd; +f:!/etc/inetd.conf -> !r:^# && r:wait; + +[CIS - Debian Linux - 4.3 - GUI login enabled {CIS: 4.3 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +[CIS - Debian Linux - 4.6 - Disable standard boot services - Samba Enabled {CIS: 4.6 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/samba; + +[CIS - Debian Linux - 4.7 - Disable standard boot services - NFS Enabled {CIS: 4.7 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/nfs-common; +f:/etc/init.d/nfs-user-server; +f:/etc/init.d/nfs-kernel-server; + +[CIS - Debian Linux - 4.9 - Disable standard boot services - NIS Enabled {CIS: 4.9 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/nis; + +[CIS - Debian Linux - 4.13 - Disable standard boot services - Web server Enabled {CIS: 4.13 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/apache; +f:/etc/init.d/apache2; + +[CIS - Debian Linux - 4.15 - Disable standard boot services - DNS server Enabled {CIS: 4.15 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/bind; + +[CIS - Debian Linux - 4.16 - Disable standard boot services - MySQL server Enabled {CIS: 4.16 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/mysql; + +[CIS - Debian Linux - 4.16 - Disable standard boot services - PostgreSQL server Enabled {CIS: 4.16 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/postgresql; + +[CIS - Debian Linux - 4.17 - Disable standard boot services - Webmin Enabled {CIS: 4.17 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/webmin; + +[CIS - Debian Linux - 4.18 - Disable standard boot services - Squid Enabled {CIS: 4.18 Debian Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/init.d/squid; + + +# Section 5 - Kernel tuning +[CIS - Debian Linux - 5.1 - Network parameters - Source routing accepted {CIS: 5.1 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +[CIS - Debian Linux - 5.1 - Network parameters - ICMP broadcasts accepted {CIS: 5.1 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +[CIS - Debian Linux - 5.2 - Network parameters - IP Forwarding enabled {CIS: 5.2 Debian Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + + +# Section 7 - Permissions +[CIS - Debian Linux - 7.1 - Partition /var without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/var && !r:nodev; + +[CIS - Debian Linux - 7.1 - Partition /tmp without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/tmp && !r:nodev; + +[CIS - Debian Linux - 7.1 - Partition /opt without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/opt && !r:nodev; + +[CIS - Debian Linux - 7.1 - Partition /home without 'nodev' set {CIS: 7.1 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/home && !r:nodev ; + +[CIS - Debian Linux - 7.2 - Removable partition /media without 'nodev' set {CIS: 7.2 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +[CIS - Debian Linux - 7.2 - Removable partition /media without 'nosuid' set {CIS: 7.2 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +[CIS - Debian Linux - 7.3 - User-mounted removable partition /media {CIS: 7.3 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && r:user; + + +# Section 8 - Access and authentication +[CIS - Debian Linux - 8.8 - LILO Password not set {CIS: 8.8 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/lilo.conf -> !r:^# && !r:restricted; +f:/etc/lilo.conf -> !r:^# && !r:password=; + +[CIS - Debian Linux - 8.8 - GRUB Password not set {CIS: 8.8 Debian Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +[CIS - Debian Linux - 9.2 - Account with empty password present {CIS: 9.2 Debian Linux} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - Debian Linux - 13.11 - Non-root account with uid 0 {CIS: 13.11 Debian Linux} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Debian_Benchmark_v1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + diff --git a/src/rootcheck/db/cis_debianlinux7-8_L1_rcl.txt b/src/rootcheck/db/cis_debianlinux7-8_L1_rcl.txt new file mode 100644 index 000000000..ed885dbce --- /dev/null +++ b/src/rootcheck/db/cis_debianlinux7-8_L1_rcl.txt @@ -0,0 +1,686 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# Level 1 CIS Checks for Debian Linux 7 and Debian Linux 8 +# Based on Center for Internet Security Benchmark v1.0.0 for Debian Linux 7 (https://workbench.cisecurity.org/benchmarks/80) and Benchmark v1.0.0 for Debian Linux 8 (https://workbench.cisecurity.org/benchmarks/81) +# +$rc_dirs=/etc/rc0.d,/etc/rc1.d,/etc/rc2.d,/etc/rc3.d,/etc/rc4.d,/etc/rc5.d,/etc/rc6.d,/etc/rc7.d,/etc/rc8.d,/etc/rc9.d,/etc/rca.d,/etc/rcb.d,/etc/rcc.d,/etc/rcs.d,/etc/rcS.d; +$rsyslog_files=/etc/rsyslog.conf,/etc/rsyslog.d/*; +$profiledfiles=/etc/profile.d/*; +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +# +# +#2.1 Create Separate Partition for /tmp +[CIS - Debian Linux 7/8 - 2.1 Create Separate Partition for /tmp] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp; +# +# +#2.2 Set nodev option for /tmp Partition +[CIS - Debian Linux 7/8 - 2.2 Set nodev option for /tmp Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+\w+\s+\.*nodev; +# +# +#2.3 Set nosuid option for /tmp Partition +[CIS - Debian Linux 7/8 - 2.3 Set nosuid option for /tmp Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+\w+\s+\.*nosuid; +# +# +#2.4 Set noexec option for /tmp Partition +[CIS - Debian Linux 7/8 - 2.4 Set noexec option for /tmp Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+\w+\s+\.*noexec; +# +# +#2.5 Create Separate Partition for /var +[CIS - Debian Linux 7/8 - 2.5 Create Separate Partition for /var] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/var; +# +# +#2.6 Bind Mount the /var/tmp directory to /tmp +[CIS - Debian Linux 7/8 - 2.6 Bind Mount the /var/tmp directory to /tmp] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/tmp\s+/var/tmp\s+none\s+\.*bind\.*0\s+0; +# +# +#2.7 Create Separate Partition for /var/log +[CIS - Debian Linux 7/8 - 2.7 Create Separate Partition for /var/log] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/var/log; +# +# +#2.8 Create Separate Partition for /var/log/audit +[CIS - Debian Linux 7/8 - 2.8 Create Separate Partition for /var/log/audit] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/var/log/audit; +# +# +#2.9 Create Separate Partition for /home +[CIS - Debian Linux 7/8 - 2.9 Create Separate Partition for /home] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/home; +# +# +#2.10 Add nodev Option to /home +[CIS - Debian Linux 7/8 - 2.10 Add nodev Option to /home] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/home\s+\w+\s+\.*nodev; +# +# +#2.11 Add nodev Option to Removable Media Partitions +[CIS - Debian Linux 7/8 - 2.11 Add nodev Option to Removable Media Partitions] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/media\.*\s+\w+\s+\.*nodev; +# +# +#2.12 Add noexec Option to Removable Media Partitions +[CIS - Debian Linux 7/8 - 2.12 Add noexec Option to Removable Media Partitions] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/media\.*\s+\w+\s+\.*noexec; +# +# +#2.13 Add nosuid Option to Removable Media Partitions +[CIS - Debian Linux 7/8 - 2.13 Add nosuid Option to Removable Media Partitions] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/media\.*\s+\w+\s+\.*nosuid; +# +# +#2.14 Add nodev Option to /run/shm Partition +[CIS - Debian Linux 7/8 - 2.14 Add nodev Option to /run/shm Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/run/shm\s+\w+\s+\.*nodev; +# +# +#2.15 Add nosuid Option to /run/shm Partition +[CIS - Debian Linux 7/8 - 2.15 Add nosuid Option to /run/shm Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/run/shm\s+\w+\s+\.*nosuid; +# +# +#2.16 Add noexec Option to /run/shm Partition +[CIS - Debian Linux 7/8 - 2.16 Add noexec Option to /run/shm Partition] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/fstab -> !r:/run/shm\s+\w+\s+\.*noexec; +# +# +#2.25 Disable Automounting +[CIS - Debian Linux 7/8 - 2.25 Disable Automounting] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:autofsc; +# +# +#3.3 Set Boot Loader Password +[CIS - Debian Linux 7/8 - 3.3 Set Boot Loader Password] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/boot/grub/grub.cfg -> !r:^set superusers; +f:/boot/grub/grub.cfg -> !r:^password; +f:/etc/grub.d -> !r:^set superusers; +f:/etc/grub.d -> !r:^password; +# +# +#3.4 Require Authentication for Single-User Mode +[CIS - Debian Linux 7/8 - 3.4 Require Authentication for Single-User Mode] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/shadow -> r:^root:!:; +f:/etc/shadow -> r:^root:*:; +f:/etc/shadow -> r:^root:*!:; +f:/etc/shadow -> r:^root:!*:; +# +# +#4.1 Restrict Core Dumps +[CIS - Debian Linux 7/8 - 4.1 Restrict Core Dumps] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/security/limits.conf -> !r:^* hard core 0; +f:/etc/sysctl.conf -> !r:^fs.suid_dumpable = 0; +# +# +#4.3 Enable Randomized Virtual Memory Region Placement +[CIS - Debian Linux 7/8 - 4.3 Enable Randomized Virtual Memory Region Placement] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^kernel.randomize_va_space = 2; +# +# +#5.1.1 Ensure NIS is not installed +[CIS - Debian Linux 7/8 - 5.1.1 Ensure NIS is not installed] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/init.d/nis; +# +# +#5.1.2 Ensure rsh server is not enabled +[CIS - Debian Linux 7/8 - 5.1.2 Ensure rsh server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:shell|login|exec; +# +# +#5.1.4 Ensure talk server is not enabled +[CIS - Debian Linux 7/8 - 5.1.4 Ensure talk server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:talk|ntalk; +# +# +#5.1.6 Ensure telnet server is not enabled +[CIS - Debian Linux 7/8 - 5.1.6 Ensure telnet server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:telnet; +# +# +#5.1.7 Ensure tftp-server is not enabled +[CIS - Debian Linux 7/8 - 5.1.7 Ensure tftp-server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:tftp; +# +# +#5.1.8 Ensure xinetd is not enabled +[CIS - Debian Linux 7/8 - 5.1.8 Ensure xinetd is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:xinetd; +# +# +#5.2 Ensure chargen is not enabled +[CIS - Debian Linux 7/8 - 5.2 Ensure chargen is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:chargen; +# +# +#5.3 Ensure daytime is not enabled +[CIS - Debian Linux 7/8 - 5.3 Ensure daytime is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:daytime; +# +# +#5.4 Ensure echo is not enabled +[CIS - Debian Linux 7/8 - 5.4 Ensure echo is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:echo; +# +# +#5.5 Ensure discard is not enabled +[CIS - Debian Linux 7/8 - 5.5 Ensure discard is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:discard; +# +# +#5.6 Ensure time is not enabled +[CIS - Debian Linux 7/8 - 5.6 Ensure time is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/inetd.conf -> !r:^# && r:time; +# +# +#6.2 Ensure Avahi Server is not enabled +[CIS - Debian Linux 7/8 - 6.2 Ensure Avahi Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:avahi-daemon; +# +# +#6.3 Ensure print server is not enabled +[CIS - Debian Linux 7/8 - 6.3 Ensure print server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:cups; +d:$rc_dirs -> S -> r:cups-browsed; +# +# +#6.4 Ensure DHCP Server is not enabled +[CIS - Debian Linux 7/8 - 6.4 Ensure DHCP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:disc-dhcp-server; +# +# +#6.5 Configure Network Time Protocol (NTP) +[CIS - Debian Linux 7/8 - 6.5 Configure Network Time Protocol (NTP)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ntp.conf -> !r:^restrict -4 default kod nomodify notrap nopeer noquery; +f:/etc/ntp.conf -> !r:^restrict -6 default kod nomodify notrap nopeer noquery; +f:/etc/ntp.conf -> !r:^server\s\.+; +# +# +#6.6 Ensure LDAP is not ennabled +[CIS - Debian Linux 7/8 - 6.6 Ensure LDAP is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:/etc/init.d -> r:ldap; +# +# +#6.7 Ensure NFS and RPC are not enabled +[CIS - Debian Linux 7/8 - 6.7 Ensure NFS and RPC are not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:rpcbind; +d:$rc_dirs -> S -> r:nfs-kernel-server; +# +# +#6.8 Ensure DNS Server is not enabled +[CIS - Debian Linux 7/8 - 6.8 Ensure DNS Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:bind9; +# +# +#6.9 Ensure FTP Server is not enabled +[CIS - Debian Linux 7/8 - 6.9 Ensure FTP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:vsftpd; +# +# +#6.10 Ensure HTTP Server is not enabled +[CIS - Debian Linux 7/8 - 6.10 Ensure HTTP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:apache2; +# +# +#6.11 Ensure IMAP and POP server is not enabled +[CIS - Debian Linux 7/8 - 6.11 Ensure IMAP and POP server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:dovecot; +# +# +#6.12 Ensure Samba is not enabled +[CIS - Debian Linux 7/8 - 6.12 Ensure Samba is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:samba; +# +# +#6.13 Ensure HTTP Proxy Server is not enabled +[CIS - Debian Linux 7/8 - 6.13 Ensure HTTP Proxy Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:squid3; +# +# +#6.14 Ensure SNMP Server is not enabled +[CIS - Debian Linux 7/8 - 6.14 Ensure SNMP Server is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$rc_dirs -> S -> r:snmpd; +# +# +#6.15 Configure Mail Transfer Agent for Local-Only Mode +[CIS - Debian Linux 7/8 - 6.15 Configure Mail Transfer Agent for Local Only Mode] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/exim4/update-exim4.conf.conf -> r:^dc_local_interfaces= && !r:'127.0.0.1\s*\p\s*::1'$|'::1\s*\p\s*127.0.0.1'$|'127.0.0.1'$|'::1'$; +# +# +#6.16 Ensure rsync service is not enabled +[CIS - Debian Linux 7/8 - 6.16 Ensure rsync service is not enabled] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/rsync -> !r:^# && r:RSYNC_ENABLE=true|inetd; +f:/etc/default/rsync -> !r:^RSYNC_ENABLE=false; +# +# +#7.1.1 Disable IP Forwarding +[CIS - Debian Linux 7/8 - 7.1.1 Disable IP Forwarding] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.ip_forward=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.ip_forward=0; +# +# +#7.1.2 Disable Send Packet Redirects +[CIS - Debian Linux 7/8 - 7.1.2 Disable Send Packet Redirects] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.send_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.send_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.send_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.send_redirects=0; +# +# +#7.2.1 Disable Source Routed Packet Acceptance +[CIS - Debian Linux 7/8 - 7.2.1 Disable Source Routed Packet Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.accept_source_route=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.accept_source_route=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.accept_source_route=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.accept_source_route=0; +# +# +#7.2.2 Disable ICMP Redirect Acceptance +[CIS - Debian Linux 7/8 - 7.2.2 Disable ICMP Redirect Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.accept_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.accept_redirects=0; +# +# +#7.2.3 Disable Secure ICMP Redirect Acceptance +[CIS - Debian Linux 7/8 - 7.2.3 Disable Secure ICMP Redirect Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.secure_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.secure_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.secure_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.secure_redirects=0; +# +# +#7.2.4 Log Suspicious Packets +[CIS - Debian Linux 7/8 - 7.2.4 Log Suspicious Packets] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.log_martians=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.log_martians=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.log_martians=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.log_martians=1; +# +# +#7.2.5 Enable Ignore Broadcast Requests +[CIS - Debian Linux 7/8 - 7.2.5 Enable Ignore Broadcast Requests] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.icmp_echo_ignore_broadcasts=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.icmp_echo_ignore_broadcasts=1; +# +# +#7.2.6 Enable Bad Error Message Protection +[CIS - Debian Linux 7/8 - 7.2.6 Enable Bad Error Message Protection] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.icmp_ignore_bogus_error_responses=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.icmp_ignore_bogus_error_responses=1; +# +# +#7.2.7 Enable RFC-recommended Source Route Validation +[CIS - Debian Linux 7/8 - 7.2.7 Enable RFC-recommended Source Route Validation] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.all.rp_filter=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.all.rp_filter=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.conf.default.rp_filter=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.conf.default.rp_filter=1; +# +# +#7.2.8 Enable TCP SYN Cookies +[CIS - Debian Linux 7/8 - 7.2.8 Enable TCP SYN Cookies] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv4.tcp_syncookies=0; +f:/etc/sysctl.conf -> !r:^net.ipv4.tcp_syncookies=1; +# +# +#7.3.1 Disable IPv6 Router Advertisements +[CIS - Debian Linux 7/8 - 7.3.1 Disable IPv6 Router Advertisements] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.all.accept_ra=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.all.accept_ra=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.default.accept_ra=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.default.accept_ra=0; +# +# +#7.3.2 Disable IPv6 Redirect Acceptance +[CIS - Debian Linux 7/8 - 7.3.2 Disable IPv6 Redirect Acceptance] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.all.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.all.accept_redirects=0; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.default.accept_redirects=1; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.default.accept_redirects=0; +# +# +#7.3.3 Disable IPv6 +[CIS - Debian Linux 7/8 - 7.3.3 Disable IPv6] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.all.disable_ipv6=0; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.all.disable_ipv6=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.default.disable_ipv6=0; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.default.disable_ipv6=1; +f:/etc/sysctl.conf -> !r:^# && r:net.ipv6.conf.lo.disable_ipv6=0; +f:/etc/sysctl.conf -> !r:^net.ipv6.conf.lo.disable_ipv6=1; +# +# +#7.4.2 Create /etc/hosts.allow +[CIS - Debian Linux 7/8 - 7.4.2 Create /etc/hosts.allow] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/hosts.allow; +f:/etc/hosts.allow -> !r:^ALL:\.*; +# +# +#7.4.4 Create /etc/hosts.deny +[CIS - Debian Linux 7/8 - 7.4.4 Create /etc/hosts.deny] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/hosts.deny; +f:/etc/hosts.deny -> !r:^ALL:\s*ALL; +# +# +#7.5.1 Disable DCCP +[CIS - Debian Linux 7/8 - 7.5.1 Disable DCCP] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install dccp /bin/true; +# +# +#7.5.2 Disable SCTP +[CIS - Debian Linux 7/8 - 7.5.2 Disable SCTP] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install sctp /bin/true; +# +# +#7.5.3 Disable RDS +[CIS - Debian Linux 7/8 - 7.5.3 Disable RDS] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install rds /bin/true; +# +# +#7.5.4 Disable TIPC +[CIS - Debian Linux 7/8 - 7.5.4 Disable TIPC] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install tipc /bin/true; +# +# +#7.7 Ensure Firewall is active (RunLevel 2, 3, 4, 5; Priority 01) +[CIS - Debian Linux 7/8 - 7.7 Ensure Firewall is active (RunLevel 2, 3, 4, 5; Priority 01)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/rc2.d/S01iptables-persistent; +f:!/etc/rc3.d/S01iptables-persistent; +f:!/etc/rc4.d/S01iptables-persistent; +f:!/etc/rc5.d/S01iptables-persistent; +# +# +#8.2.2 Ensure the rsyslog Service is activated (RunLevel 2, 3, 4, 5; Priority 01) +[CIS - Debian Linux 7/8 - 8.2.2 Ensure the rsyslog Service is activated (RunLevel 2, 3, 4, 5; Priority 01)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/rc2.d/S01rsyslog; +f:!/etc/rc3.d/S01rsyslog; +f:!/etc/rc4.d/S01rsyslog; +f:!/etc/rc5.d/S01rsyslog; +# +# +#8.2.3 Configure /etc/rsyslog.conf +[CIS - Debian Linux 7/8 - 8.2.3 Configure /etc/rsyslog.conf] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:$rsyslog_files -> !r:^*.emerg\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.info\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.warning\s*\t*\s*\S; +f:$rsyslog_files -> !r:^mail.err\s*\t*\s*\S; +f:$rsyslog_files -> !r:^news.crit\s*\t*\s*\S; +f:$rsyslog_files -> !r:^news.err\s*\t*\s*\S; +f:$rsyslog_files -> !r:^news.notice\s*\t*\s*\S; +f:$rsyslog_files -> !r:^*.=warning;*.=err\s*\t*\s*\S; +f:$rsyslog_files -> !r:^*.crit\s*\t*\s*\S; +f:$rsyslog_files -> !r:^*.*;mail.none;news.none\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local0,local1.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local2,local3.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local4,local5.*\s*\t*\s*\S; +f:$rsyslog_files -> !r:^local6,local7.*\s*\t*\s*\S; +# +# +#8.2.5 Configure rsyslog to Send Logs to a Remote Log Host +[CIS - Debian Linux 7/8 - 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/rsyslog.conf -> !r:^*.* @@\w+.\w+.\w+; +# +# +#8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts +[CIS - Debian Linux 7/8 - 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:$rsyslog_files -> !r:^\$ModLoad imtcp.so; +f:$rsyslog_files -> !r:^\$InputTCPServerRun 514; +# +# +#8.4 Configure logrotate +[CIS - Debian Linux 7/8 - 8.4 Configure logrotate] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/logrotate.d/rsyslog; +f:/etc/logrotate.d/rsyslog -> !r:\S+; +# +# +#9.1.1 Enable cron Daemon (RunLevel 2, 3, 4, 5; Priority 15) +[CIS - Debian Linux 7/8 - 9.1.1 Enable cron Daemon (RunLevel 2, 3, 4, 5; Priority 15)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/rc2.d/S15anacron; +f:!/etc/rc2.d/S15cron; +f:!/etc/rc3.d/S15anacron; +f:!/etc/rc3.d/S15cron; +f:!/etc/rc4.d/S15anacron; +f:!/etc/rc4.d/S15cron; +f:!/etc/rc5.d/S15anacron; +f:!/etc/rc5.d/S15cron; +# +# +#9.1.8 Restrict at/cron to Authorized Users +[CIS - Debian Linux 7/8 - 9.1.8 Restrict at/cron to Authorized Users] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/cron.allow; +f:!/etc/at.allow; +# +# +#9.2.1 Set Password Creation Requirement Parameters Using pam_cracklib +[CIS - Debian Linux 7/8 - 9.2.1 Set Password Creation Requirement Parameters Using pam_cracklib] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/common-password -> !r:password required pam_cracklib.so retry=\d minlen=\d\d+ dcredit=-\d+ ucredit=-\d+ ocredit=-\d+ lcredit=-\d+; +# +# +#9.2.2 Set Lockout for Failed Password Attempts +[CIS - Debian Linux 7/8 - 9.2.2 Set Lockout for Failed Password Attempts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/login -> !r:auth required pam_tally2.so onerr=fail audit silent deny=\d unlock_time=\d\d\d+; +# +# +#9.2.3 Limit Password Reuse +[CIS - Debian Linux 7/8 - 9.2.3 Limit Password Reuse] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/common-password -> !r:password [success=1 default=ignore] pam_unix.so obscure sha512 remember=\d; +# +# +#9.3.1 Set SSH Protocol to 2 +[CIS - Debian Linux 7/8 - 9.3.1 Set SSH Protocol to 2] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:protocol 1; +f:/etc/ssh/sshd_config -> !r:^protocol 2$; +# +# +#9.3.2 Set LogLevel to INFO +[CIS - Debian Linux 7/8 - 9.3.2 Set LogLevel to INFO] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^LogLevel\s+INFO; +# +# +#9.3.4 Disable SSH X11 Forwarding +[CIS - Debian Linux 7/8 - 9.3.4 Disable SSH X11 Forwarding] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^X11Forwarding\s+no; +# +# +#9.3.5 Set SSH MaxAuthTries to 4 or Less +[CIS - Debian Linux 7/8 - 9.3.5 Set SSH MaxAuthTries to 4 or Less] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^MaxAuthTries\s+\d; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+\d\d+; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+5; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+6; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+7; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+8; +f:/etc/ssh/sshd_config -> r:^MaxAuthTries\s+9; +# +# +#9.3.6 Set SSH IgnoreRhosts to Yes +[CIS - Debian Linux 7/8 - 9.3.6 Set SSH IgnoreRhosts to Yes] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^IgnoreRhosts\s+yes; +# +# +#9.3.7 Set SSH HostbasedAuthentication to No +[CIS - Debian Linux 7/8 - 9.3.7 Set SSH HostbasedAuthentication to No] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^HostbasedAuthentication\s+no; +# +# +#9.3.8 Disable SSH Root Login +[CIS - Debian Linux 7/8 - 9.3.8 Disable SSH Root Login] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\s+yes; +f:/etc/ssh/sshd_config -> !r:^PermitRootLogin\s+no; +# +# +#9.3.9 Set SSH PermitEmptyPasswords to No +[CIS - Debian Linux 7/8 - 9.3.9 Set SSH PermitEmptyPasswords to No] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitEmptyPasswords\s+yes; +f:/etc/ssh/sshd_config -> !r:^PermitEmptyPasswords\s+no; +# +# +#9.3.10 Do Not Allow Users to Set Environment Options +[CIS - Debian Linux 7/8 - 9.3.10 Do Not Allow Users to Set Environment Options] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitUserEnvironment\s+yes; +f:/etc/ssh/sshd_config -> !r:^PermitUserEnvironment\s+no; +# +# +#9.3.12 Set Idle Timeout Interval for User Login +[CIS - Debian Linux 7/8 - 9.3.12 Set Idle Timeout Interval for User Login] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^ClientAliveInterval\s+\d+; +f:/etc/ssh/sshd_config -> !r:^ClientAliveCountMax\s+\d; +# +# +#9.3.13 Limit Access via SSH +[CIS - Debian Linux 7/8 - 9.3.13 Limit Access via SSH] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^AllowUsers\s+\w+|^AllowGroups\s+\w+|^DenyUsers\s+\w+|^DenyGroups\s+\w+; +# +# +#9.3.14 Set SSH Banner +[CIS - Debian Linux 7/8 - 9.3.14 Set SSH Banner] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/ssh/sshd_config -> !r:^Banner\s+\S+; +# +# +#9.5 Restrict Access to the su Command +[CIS - Debian Linux 7/8 - 9.5 Restrict Access to the su Command] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/pam.d/su -> !r:auth required pam_wheel.so use_uid; +# +# +#10.1.1 Set Password Expiration Days +[CIS - Debian Linux 7/8 - 10.1.1 Set Password Expiration Days] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/login.defs -> !r:^PASS_MAX_DAYS\s+\d+; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+\d\d\d+; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+91; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+92; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+93; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+94; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+95; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+96; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+97; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+98; +f:/etc/login.defs -> !r:^# && r:PASS_MAX_DAYS\s+99; +# +# +#10.1.2 Set Password Change Minimum Number of Days +[CIS - Debian Linux 7/8 - 10.1.2 Set Password Change Minimum Number of Days] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/login.defs -> !r:^PASS_MIN_DAYS\s+\d+; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+1; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+2; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+3; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+4; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+5; +f:/etc/login.defs -> !r:^# && r:PASS_MIN_DAYS\s+6; +# +# +#10.1.3 Set Password Expiring Warning Days +[CIS - Debian Linux 7/8 - 10.1.3 Set Password Expiring Warning Days] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/login.defs -> !r:^PASS_WARN_DAYS\s+\d+; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+1; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+2; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+3; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+4; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+5; +f:/etc/login.defs -> !r:^# && r:PASS_WARN_DAYS\s+6; +# +# +#10.3 Set Default Group for root Account +[CIS - Debian Linux 7/8 - 10.3 Set Default Group for root Account] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/passwd -> !r:^root:\w+:\w+:0:; +# +# +#10.4 Set Default umask for Users +[CIS - Debian Linux 7/8 - 10.4 Set Default umask for Users] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:$profiledfiles -> !r:^umask 077; +f:/etc/bash.bashrc -> !r:^umask 077; +# +# +#10.5 Lock Inactive User Accounts +[CIS - Debian Linux 7/8 - 10.5 Lock Inactive User Accounts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/useradd -> !r:^INACTIVE=\d\d*; +# +# +#11.1 Set Warning Banner for Standard Login Services +[CIS - Debian Linux 7/8 - 11.1 Set Warning Banner for Standard Login Services] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/motd; +f:!/etc/issue; +f:!/etc/issue.net; +# +# +#11.2 Remove OS Information from Login Warning Banners +[CIS - Debian Linux 7/8 - 11.2 Remove OS Information from Login Warning Banners] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/motd -> r:debian|gnu|linux; +# +# +#13.1 Ensure Password Fields are Not Empty +[CIS - Debian Linux 7/8 - 13.1 Ensure Password Fields are Not Empty] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/shadow -> r:^\w+::; +# +# +#13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File +[CIS - Debian Linux 7/8 - 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/passwd -> !r:^# && r:^+:; +# +# +#13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File +[CIS - Debian Linux 7/8 - 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/shadow -> !r:^# && r:^+:; +# +# +#13.4 Verify No Legacy "+" Entries Exist in /etc/group File +[CIS - Debian Linux 7/8 - 13.4 Verify No Legacy "+" Entries Exist in /etc/group File] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/group -> !r:^# && r:^+:; +# +# +#13.5 Verify No UID 0 Accounts Exist Other Than root +[CIS - Debian Linux 7/8 - 13.5 Verify No UID 0 Accounts Exist Other Than root] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; +# +# +#13.10 Check for Presence of User .rhosts Files +[CIS - Debian Linux 7/8 - 13.10 Check for Presence of User .rhosts Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$home_dirs -> r:^.rhosts$; +# +# +#13.18 Check for Presence of User .netrc Files +[CIS - Debian Linux 7/8 - 13.18 Check for Presence of User .netrc Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$home_dirs -> r:^.netrc$; +# +# +#13.19 Check for Presence of User .forward Files +[CIS - Debian Linux 7/8 - 13.19 Check for Presence of User .forward Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +d:$home_dirs -> r:^.forward$; +# +# +#13.20 Ensure shadow group is empty +[CIS - Debian Linux 7/8 - 13.20 Ensure shadow group is empty] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/group -> !r:^# && r:shadow:\w*:\w*:\S+; diff --git a/src/rootcheck/db/cis_debianlinux7-8_L2_rcl.txt b/src/rootcheck/db/cis_debianlinux7-8_L2_rcl.txt new file mode 100644 index 000000000..b8eef0341 --- /dev/null +++ b/src/rootcheck/db/cis_debianlinux7-8_L2_rcl.txt @@ -0,0 +1,245 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# Level 2 CIS Checks for Debian Linux 7 and Debian Linux 8 +# Based on Center for Internet Security Benchmark v1.0.0 for Debian Linux 7 (https://workbench.cisecurity.org/benchmarks/80) and Benchmark v1.0.0 for Debian Linux 8 (https://workbench.cisecurity.org/benchmarks/81) +# +# +$rc_dirfiles=/etc/rc0.d/*,/etc/rc1.d/*,/etc/rc2.d/*,/etc/rc3.d/*,/etc/rc4.d/*,/etc/rc5.d/*,/etc/rc6.d/*,/etc/rc7.d/*,/etc/rc8.d/*,/etc/rc9.d/*,/etc/rca.d/*,/etc/rcb.d/*,/etc/rcc.d/*,/etc/rcs.d/*,/etc/rcS.d/*; +# +# +#2.18 Disable Mounting of cramfs Filesystems +[CIS - Debian Linux 7/8 - 2.18 Disable Mounting of cramfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install cramfs /bin/true; +# +# +#2.19 Disable Mounting of freevxfs Filesystems +[CIS - Debian Linux 7/8 - 2.19 Disable Mounting of freevxfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install freevxfs /bin/true; +# +# +#2.20 Disable Mounting of jffs2 Filesystems +[CIS - Debian Linux 7/8 - 2.20 Disable Mounting of jffs2 Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install jffs2 /bin/true; +# +# +#2.21 Disable Mounting of hfs Filesystems +[CIS - Debian Linux 7/8 - 2.21 Disable Mounting of hfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install hfs /bin/true; +# +# +#2.22 Disable Mounting of hfsplus Filesystems +[CIS - Debian Linux 7/8 - 2.22 Disable Mounting of hfsplus Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install hfsplus /bin/true; +# +# +#2.23 Disable Mounting of squashfs Filesystems +[CIS - Debian Linux 7/8 - 2.23 Disable Mounting of squashfs Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install squashfs /bin/true; +# +# +#2.24 Disable Mounting of udf Filesystems +[CIS - Debian Linux 7/8 - 2.24 Disable Mounting of udf Filesystems] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/modprobe.d/CIS.conf; +f:/etc/modprobe.d/CIS.conf -> !r:^install udf /bin/true; +# +# +#4.5 Activate AppArmor +[CIS - Debian Linux 7/8 - 4.5 Activate AppArmor] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/grub -> !r:apparmor=1 && !r:security=apparmor; +# +# +#8.1.1.1 Configure Audit Log Storage Size +[CIS - Debian Linux 7/8 - 8.1.1.1 Configure Audit Log Storage Size] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/auditd.conf; +f:/etc/audit/auditd.conf -> !r:max_log_file\s*=\s*\d+; +# +# +#8.1.1.2 Disable System on Audit Log Full +[CIS - Debian Linux 7/8 - 8.1.1.2 Disable System on Audit Log Full] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/auditd.conf; +f:/etc/audit/auditd.conf -> !r:^space_left_action\s*=\s*email; +f:/etc/audit/auditd.conf -> !r:^# && r:space_left_action\s*=\s*ignore|syslog|suspend|single|halt; +f:/etc/audit/auditd.conf -> !r:^action_mail_acct\s*=\s*root; +f:/etc/audit/auditd.conf -> !r:^admin_space_left_action\s*=\s*halt; +f:/etc/audit/auditd.conf -> !r:^# && r:admin_space_left_action\s*=\s*ignore|syslog|email|suspend|single; +# +# +#8.1.1.3 Keep All Auditing Information +[CIS - Debian Linux 7/8 - 8.1.1.3 Keep All Auditing Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/auditd.conf; +f:/etc/audit/auditd.conf -> !r:^max_log_file_action\s*=\s*keep_logs; +f:/etc/audit/auditd.conf -> !r:^# && r:max_log_file_action\s*=\s*ignore|syslog|suspend|rotate; +# +# +#8.1.3 Enable Auditing for Processes That Start Prior to auditd +[CIS - Debian Linux 7/8 - 8.1.3 Enable Auditing for Processes That Start Prior to auditd] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/default/grub -> !r:^GRUB_CMDLINE_LINUX\s*=\s*\.*audit\s*=\s*1\.*; +# +# +#8.1.4 Record Events That Modify Date and Time Information +[CIS - Debian Linux 7 - 8.1.4 Record Events That Modify Date and Time Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S clock_settime -k time-change; +f:/etc/audit/audit.rules -> !r:^-w /etc/localtime -p wa -k time-change; +# +# +#8.1.5 Record Events That Modify User/Group Information +[CIS - Debian Linux 7/8 - 8.1.5 Record Events That Modify User/Group Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /etc/group -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/passwd -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/gshadow -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/shadow -p wa -k identity; +f:/etc/audit/audit.rules -> !r:^-w /etc/security/opasswd -p wa -k identity; +# +# +#8.1.6 Record Events That Modify the System's Network Environment +[CIS - Debian Linux 7/8 - 8.1.6 Record Events That Modify the System's Network Environment] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/issue -p wa -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/issue.net -p wa -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/hosts -p wa -k system-locale; +f:/etc/audit/audit.rules -> !r:^-w /etc/network -p wa -k system-locale; +# +# +#8.1.7 Record Events That Modify the System's Mandatory Access Controls +[CIS - Debian Linux 7/8 - 8.1.7 Record Events That Modify the System's Mandatory Access Controls] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /etc/selinux/ -p wa -k MAC-policy; +# +# +#8.1.8 Collect Login and Logout Events +[CIS - Debian Linux 7/8 - 8.1.8 Collect Login and Logout Events] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /var/log/faillog -p wa -k logins; +f:/etc/audit/audit.rules -> !r:^-w /var/log/lastlog -p wa -k logins; +f:/etc/audit/audit.rules -> !r:^-w /var/log/tallylog -p wa -k logins; +# +# +#8.1.9 Collect Session Initiation Information +[CIS - Debian Linux 7/8 - 8.1.9 Collect Session Initiation Information] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /var/run/utmp -p wa -k session; +f:/etc/audit/audit.rules -> !r:^-w /var/log/wtmp -p wa -k session; +f:/etc/audit/audit.rules -> !r:^-w /var/log/btmp -p wa -k session; +# +# +#8.1.10 Collect Discretionary Access Control Permission Modification Events +[CIS - Debian Linux 7/8 - 8.1.10 Collect Discretionary Access Control Permission Modification Events] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 \\; +f:/etc/audit/audit.rules -> !r:^-F auid!=4294967295 -k perm_mod; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 \\; +f:/etc/audit/audit.rules -> !r:^-F auid!=4294967295 -k perm_mod; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S \\; +f:/etc/audit/audit.rules -> !r:^lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod; +# +# +#8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files +[CIS - Debian Linux 7/8 - 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate \\; +f:/etc/audit/audit.rules -> !r:^-F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate \\; +f:/etc/audit/audit.rules -> !r:^-F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access; +# +# +#8.1.13 Collect Successful File System Mounts +[CIS - Debian Linux 7/8 - 8.1.13 Collect Successful File System Mounts] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts; +# +# +#8.1.14 Collect File Deletion Events by User +[CIS - Debian Linux 7/8 - 8.1.14 Collect File Deletion Events by User] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 \\; +f:/etc/audit/audit.rules -> !r:^-F auid!=4294967295 -k delete; +# +# +#8.1.15 Collect Changes to System Administration Scope (sudoers) +[CIS - Debian Linux 7/8 - 8.1.15 Collect Changes to System Administration Scope (sudoers)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /etc/sudoers -p wa -k scope; +# +# +#8.1.16 Collect System Administrator Actions (sudolog) +[CIS - Debian Linux 7/8 - 8.1.16 Collect System Administrator Actions (sudolog)] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /var/log/sudo.log -p wa -k actions; +# +# +#8.1.17 Collect Kernel Module Loading and Unloading +[CIS - Debian Linux 7/8 - 8.1.17 Collect Kernel Module Loading and Unloading] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-w /sbin/insmod -p x -k modules; +f:/etc/audit/audit.rules -> !r:^-w /sbin/rmmod -p x -k modules; +f:/etc/audit/audit.rules -> !r:^-w /sbin/modprobe -p x -k modules; +f:/etc/audit/audit.rules -> !r:^-a always,exit -F arch=b32 -S init_module -S delete_module -k modules|-a always,exit -F arch=b64 -S init_module -S delete_module -k modules; +# +# +#8.1.18 Make the Audit Configuration Immutable +[CIS - Debian Linux 7/8 - 8.1.18 Make the Audit Configuration Immutable] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/etc/audit; +f:!/etc/audit/audit.rules; +f:/etc/audit/audit.rules -> !r:^-e 2$; +# +# +#8.3.1 Install AIDE +[CIS - Debian Linux 7/8 - 8.3.1 Install AIDE] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:!/usr/sbin/aideinit; +# +# +#8.3.2 Implement Periodic Execution of File Integrity +[CIS - Debian Linux 7/8 - 8.3.2 Implement Periodic Execution of File Integrity] [any] [https://workbench.cisecurity.org/benchmarks/80, https://workbench.cisecurity.org/benchmarks/81] +f:/etc/crontab -> !r:/usr/sbin/aide --check; +# diff --git a/src/rootcheck/db/cis_mysql5-6_community_rcl.txt b/src/rootcheck/db/cis_mysql5-6_community_rcl.txt new file mode 100644 index 000000000..22c91af0d --- /dev/null +++ b/src/rootcheck/db/cis_mysql5-6_community_rcl.txt @@ -0,0 +1,158 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for MYSQL +# Based on Center for Internet Security Benchmark for MYSQL v1.1.0 +# +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +$enviroment_files=/*/home/*/\.bashrc,/*/home/*/\.profile,/*/home/*/\.bash_profile,/home/*/\.bashrc,/home/*/\.profile,/home/*/\.bash_profile; +$mysql-cnfs=/etc/mysql/my.cnf,/etc/mysql/mariadb.cnf,/etc/mysql/conf.d/*.cnf,/etc/mysql/mariadb.conf.d/*.cnf,~/.my.cnf; +# +# +#1.3 Disable MySQL Command History +[CIS - MySQL Configuration - 1.3: Disable MySQL Command History] [any] [https://workbench.cisecurity.org/files/1310/download] +d:$home_dirs -> ^.mysql_history$; +# +# +#1.5 Disable Interactive Login +[CIS - MySQL Configuration - 1.5: Disable Interactive Login] [any] [https://workbench.cisecurity.org/files/1310/download] +f:/etc/passwd -> r:^mysql && !r:\.*/bin/false$|/sbin/nologin$; +# +# +#1.6 Verify That 'MYSQL_PWD' Is Not In Use +[CIS - MySQL Configuration - 1.6: 'MYSQL_PWD' Is in Use] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$enviroment_files -> r:\.*MYSQL_PWD\.*; +# +# +#4.3 Ensure 'allow-suspicious-udfs' Is Set to 'FALSE' +[CIS - MySQL Configuration - 4.3: 'allow-suspicious-udfs' Is Set in my.cnf'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:allow-suspicious-udfs\.+true; +f:$mysql-cnfs -> r:allow-suspicious-udfs\s*$; +# +# +#4.4 Ensure 'local_infile' Is Disabled +[CIS - MySQL Configuration - 4.4: local_infile is not forbidden in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:local-infile\s*=\s*1; +f:$mysql-cnfs -> r:local-infile\s*$; +# +# +#4.5 Ensure 'mysqld' Is Not Started with '--skip-grant-tables' +[CIS - MySQL Configuration - 4.5: skip-grant-tables is set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip-grant-tables\s*=\s*true; +f:$mysql-cnfs -> !r:skip-grant-tables\s*=\s*false; +f:$mysql-cnfs -> r:skip-grant-tables\s*$; +# +# +#4.6 Ensure '--skip-symbolic-links' Is Enabled +[CIS - MySQL Configuration - 4.6: skip_symbolic_links is not enabled in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip_symbolic_links\s*=\s*no; +f:$mysql-cnfs -> !r:skip_symbolic_links\s*=\s*yes; +f:$mysql-cnfs -> r:skip_symbolic_links\s*$; +# +# +#4.8 Ensure 'secure_file_priv' is not empty +[CIS - MySQL Configuration - 4.8: Ensure 'secure_file_priv' is not empty] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> !r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> r:secure_file_priv\s*$; +# +# +#4.9 Ensure 'sql_mode' Contains 'STRICT_ALL_TABLES' +[CIS - MySQL Configuration - 4.9: strict_all_tables is not set at sql_mode section of my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:strict_all_tables\s*$; +# +# +#6.1 Ensure 'log_error' is not empty +[CIS - MySQL Configuration - 6.1: log-error is not set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> !r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> r:log_error\s*$; +# +# +#6.2 Ensure Log Files are not Stored on a non-system partition +[CIS - MySQL Configuration - 6.2: log files are maybe stored on systempartition] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/var/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/usr/\S*\s*; +f:$mysql-cnfs -> r:log_bin\s*$; +# +# +#6.3 Ensure 'log_warning' is set to 2 at least +[CIS - MySQL Configuration - 6.3: log warnings is set low] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*0; +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*1; +f:$mysql-cnfs -> !r:log_warnings\s*=\s*\d+; +f:$mysql-cnfs -> r:log_warnings\s*$; +# +# +#6.5 Ensure 'log_raw' is set to 'off' +[CIS - MySQL Configuration - 6.5: log_raw is not set to off] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log-raw\s*=\s*on; +f:$mysql-cnfs -> r:log-raw\s*$; +# +# +#7.1 Ensure 'old_password' is not set to '1' or 'On' +[CIS - MySQL Configuration - 7.1:Ensure 'old_passwords' is not set to '1' or 'on'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*1; +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*on; +f:$mysql-cnfs -> !r:old_passwords\s*=\s*2; +f:$mysql-cnfs -> r:old_passwords\s*$; +# +# +#7.2 Ensure 'secure_auth' is set to 'ON' +[CIS - MySQL Configuration - 7.2: Ensure 'secure_auth' is set to 'ON'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:secure_auth\s*=\s*off; +f:$mysql-cnfs -> !r:secure_auth\s*=\s*on; +f:$mysql-cnfs -> r:secure_auth\s*$; +# +# +#7.3 Ensure Passwords Are Not Stored in the Global Configuration +[CIS - MySQL Configuration - 7.3: Passwords are stored in global configuration] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:^\s*password\.*; +# +# +#7.4 Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER' +[CIS - MySQL Configuration - 7.4: Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:no_auto_create_user\s*$; +f:$mysql-cnfs -> r:^# && r:\s*no_auto_create_user\s*$; +# +# +#7.6 Ensure Password Policy is in Place +[CIS - MySQL Configuration - 7.6: Ensure Password Policy is in Place ] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:plugin-load\s*=\s*validate_password.so\s*$; +f:$mysql-cnfs -> !r:validate-password\s*=\s*force_plus_permanent\s*$; +f:$mysql-cnfs -> !r:validate_password_length\s*=\s*14\s$; +f:$mysql-cnfs -> !r:validate_password_mixed_case_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_number_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_special_char_count\s*=\s*1; +f:$mysql-cnfs -> !r:validate_password_policy\s*=\s*medium\s*; +# +# +#9.2 Ensure 'master_info_repository' is set to 'Table' +[CIS - MySQL Configuration - 9.2: Ensure 'master_info_repositrory' is set to 'Table'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:master_info_repository\s*=\s*file; +f:$mysql-cnfs -> !r:master_info_repository\s*=\s*table; +f:$mysql-cnfs -> r:master_info_repository\s*$; diff --git a/src/rootcheck/db/cis_mysql5-6_enterprise_rcl.txt b/src/rootcheck/db/cis_mysql5-6_enterprise_rcl.txt new file mode 100644 index 000000000..e627e78cf --- /dev/null +++ b/src/rootcheck/db/cis_mysql5-6_enterprise_rcl.txt @@ -0,0 +1,208 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for MYSQL +# Based on Center for Internet Security Benchmark for MYSQL v1.1.0 +# +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +$enviroment_files=/*/home/*/\.bashrc,/*/home/*/\.profile,/*/home/*/\.bash_profile,/home/*/\.bashrc,/home/*/\.profile,/home/*/\.bash_profile; +$mysql-cnfs=/etc/mysql/my.cnf,/etc/mysql/mariadb.cnf,/etc/mysql/conf.d/*.cnf,/etc/mysql/mariadb.conf.d/*.cnf,~/.my.cnf; +# +# +#1.3 Disable MySQL Command History +[CIS - MySQL Configuration - 1.3: Disable MySQL Command History] [any] [https://workbench.cisecurity.org/files/1310/download] +d:$home_dirs -> ^.mysql_history$; +# +# +#1.5 Disable Interactive Login +[CIS - MySQL Configuration - 1.5: Disable Interactive Login] [any] [https://workbench.cisecurity.org/files/1310/download] +f:/etc/passwd -> r:^mysql && !r:\.*/bin/false$|/sbin/nologin$; +# +# +#1.6 Verify That 'MYSQL_PWD' Is Not In Use +[CIS - MySQL Configuration - 1.6: 'MYSQL_PWD' Is in Use] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$enviroment_files -> r:\.*MYSQL_PWD\.*; +# +# +#4.3 Ensure 'allow-suspicious-udfs' Is Set to 'FALSE' +[CIS - MySQL Configuration - 4.3: 'allow-suspicious-udfs' Is Set in my.cnf'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:allow-suspicious-udfs\.+true; +f:$mysql-cnfs -> r:allow-suspicious-udfs\s*$; +# +# +#4.4 Ensure 'local_infile' Is Disabled +[CIS - MySQL Configuration - 4.4: local_infile is not forbidden in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:local-infile\s*=\s*1; +f:$mysql-cnfs -> r:local-infile\s*$; +# +# +#4.5 Ensure 'mysqld' Is Not Started with '--skip-grant-tables' +[CIS - MySQL Configuration - 4.5: skip-grant-tables is set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip-grant-tables\s*=\s*true; +f:$mysql-cnfs -> !r:skip-grant-tables\s*=\s*false; +f:$mysql-cnfs -> r:skip-grant-tables\s*$; +# +# +#4.6 Ensure '--skip-symbolic-links' Is Enabled +[CIS - MySQL Configuration - 4.6: skip_symbolic_links is not enabled in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:skip_symbolic_links\s*=\s*no; +f:$mysql-cnfs -> !r:skip_symbolic_links\s*=\s*yes; +f:$mysql-cnfs -> r:skip_symbolic_links\s*$; +# +# +#4.8 Ensure 'secure_file_priv' is not empty +[CIS - MySQL Configuration - 4.8: Ensure 'secure_file_priv' is not empty] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> !r:secure_file_priv=\s*\S+\s*; +f:$mysql-cnfs -> r:secure_file_priv\s*$; +# +# +#4.9 Ensure 'sql_mode' Contains 'STRICT_ALL_TABLES' +[CIS - MySQL Configuration - 4.9: strict_all_tables is not set at sql_mode section of my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:strict_all_tables\s*$; +# +# +#6.1 Ensure 'log_error' is not empty +[CIS - MySQL Configuration - 6.1: log-error is not set in my.cnf] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> r:^# && r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> !r:log_error\s*=\s*\S+\s*; +f:$mysql-cnfs -> r:log_error\s*$; +# +# +#6.2 Ensure Log Files are not Stored on a non-system partition +[CIS - MySQL Configuration - 6.2: log files are maybe stored on systempartition] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/var/\S*\s*; +f:$mysql-cnfs -> !r:^# && r:log_bin= && !r:\s*/usr/\S*\s*; +f:$mysql-cnfs -> r:log_bin\s*$; +# +# +#6.3 Ensure 'log_warning' is set to 2 at least +[CIS - MySQL Configuration - 6.3: log warnings is set low] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*0; +f:$mysql-cnfs -> !r:^# && r:log_warnings\s*=\s*1; +f:$mysql-cnfs -> !r:log_warnings\s*=\s*\d+; +f:$mysql-cnfs -> r:log_warnings\s*$; +# +# +#6.4 Ensure 'log_raw' is set to 'off' +[CIS - MySQL Configuration - 6.4: log_raw is not set to off] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:log-raw\s*=\s*on; +f:$mysql-cnfs -> r:log-raw\s*$; +# +# +#6.5 Ensure audit_log_connection_policy is not set to 'none' +[CIS - MySQL Configuration - 6.5: audit_log_connection_policy is set to 'none' change it to all or erros] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r^# && r::audit_log_connection_policy\s*=\s*none; +f:$mysql-cnfs -> r:audit_log_connection_policy\s*$; +# +# +#6.6 Ensure audit_log_exclude_account is set to Null +[CIS - MySQL Configuration - 6.6:audit_log_exclude_accounts is not set to Null] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_exclude_accounts\s*=\s* && !r:null\s*$; +f:$mysql-cnfs -> r:audit_log_exclude_accounts\s*$; +# +# +#6.7 Ensure audit_log_include_accounts is set to Null +[CIS - MySQL Configuration - 6.7:audit_log_include_accounts is not set to Null] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_include_accounts\s*=\s* && !r:null\s*$; +f:$mysql-cnfs -> r:audit_log_include_accounts\s*$; +# +# +#6.9 Ensure audit_log_policy is not set to all +[CIS - MySQL Configuration - 6.9: audit_log_policy is not set to all] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_policy\s*=\s*queries; +f:$mysql-cnfs -> !r:^# && r:audit_log_policy\s*=\s*none; +f:$mysql-cnfs -> !r:^# && r:audit_log_policy\s*=\s*logins; +f:$mysql-cnfs -> r:audit_log_policy\s*$; +# +# +#6.10 Ensure audit_log_statement_policy is set to all +[CIS - MySQL Configuration - 6.10: Ensure audit_log_statement_policy is set to all] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_statement_policy\.+errors; +f:$mysql-cnfs -> !r:^# && r:audit_log_statement_policy\.+none; +f:$mysql-cnfs -> r:audit_log_statement_policy\s*$; +# +# +#6.11 Ensure audit_log_strategy is set to synchronous or semisynchronous +[CIS - MySQL Configuration - 6.11: Ensure audit_log_strategy is set to all] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:audit_log_strategy\.+asynchronous; +f:$mysql-cnfs -> !r:^# && r:audit_log_strategy\.+performance; +f:$mysql-cnfs -> !r:audit_log_strategy\s*=\s* && r:semisynchronous|synchronous; +f:$mysql-cnfs -> r:audit_log_strategy\s*$; +# +# +#6.12 Make sure the audit plugin can't be unloaded +[CIS - MySQL Configuration - 6.12: Audit plugin can be unloaded] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:^audit_log\s*=\s*on\s*; +f:$mysql-cnfs -> !r:^# && r:^audit_log\s*=\s*off\s*; +f:$mysql-cnfs -> !r:^# && r:^audit_log\s*=\s*force\s*; +f:$mysql-cnfs -> !r:^audit_log\s*=\s*force_plus_permanent\s*; +f:$mysql-cnfs -> r:^audit_log\s$; +# +# +#7.1 Ensure 'old_password' is not set to '1' or 'On' +[CIS - MySQL Configuration - 7.1:Ensure 'old_passwords' is not set to '1' or 'on'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*1; +f:$mysql-cnfs -> !r:^# && r:old_passwords\s*=\s*on; +f:$mysql-cnfs -> !r:old_passwords\s*=\s*2; +f:$mysql-cnfs -> r:old_passwords\s*$; +# +# +#7.2 Ensure 'secure_auth' is set to 'ON' +[CIS - MySQL Configuration - 7.2: Ensure 'secure_auth' is set to 'ON'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:secure_auth\s*=\s*off; +f:$mysql-cnfs -> !r:secure_auth\s*=\s*on; +f:$mysql-cnfs -> r:secure_auth\s*$; +# +# +#7.3 Ensure Passwords Are Not Stored in the Global Configuration +[CIS - MySQL Configuration - 7.3: Passwords are stored in global configuration] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:^\s*password\.*; +# +# +#7.4 Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER' +[CIS - MySQL Configuration - 7.4: Ensure 'sql_mode' Contains 'NO_AUTO_CREATE_USER'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:no_auto_create_user\s*$; +f:$mysql-cnfs -> r:^# && r:\s*no_auto_create_user\s*$; +# +# +#7.6 Ensure Password Policy is in Place +[CIS - MySQL Configuration - 7.6: Ensure Password Policy is in Place ] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:plugin-load\s*=\s*validate_password.so\s*$; +f:$mysql-cnfs -> !r:validate-password\s*=\s*force_plus_permanent\s*$; +f:$mysql-cnfs -> !r:validate_password_length\s*=\s*14\s$; +f:$mysql-cnfs -> !r:validate_password_mixed_case_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_number_count\s*=\s*1\s*$; +f:$mysql-cnfs -> !r:validate_password_special_char_count\s*=\s*1; +f:$mysql-cnfs -> !r:validate_password_policy\s*=\s*medium\s*; +# +# +#9.2 Ensure 'master_info_repository' is set to 'Table' +[CIS - MySQL Configuration - 9.2: Ensure 'master_info_repositrory' is set to 'Table'] [any] [https://workbench.cisecurity.org/files/1310/download] +f:$mysql-cnfs -> !r:^# && r:master_info_repository\s*=\s*file; +f:$mysql-cnfs -> !r:master_info_repository\s*=\s*table; +f:$mysql-cnfs -> r:master_info_repository\s*$; diff --git a/src/rootcheck/db/cis_rhel5_linux_rcl.txt b/src/rootcheck/db/cis_rhel5_linux_rcl.txt new file mode 100644 index 000000000..8ebf43b4d --- /dev/null +++ b/src/rootcheck/db/cis_rhel5_linux_rcl.txt @@ -0,0 +1,845 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat / CentOS 5 +# Based on CIS Benchmark for Red Hat Enterprise Linux 5 v2.1.0 + +# TODO: URL is invalid currently + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS Red Hat Enterprise Linux 5 Benchmark v2.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 5; +f:/etc/redhat-release -> r:^CentOS && r:release 5; +f:/etc/redhat-release -> r:^Cloud && r:release 5; +f:/etc/redhat-release -> r:^Oracle && r:release 5; +f:/etc/redhat-release -> r:^Better && r:release 5; + + +# 1.1.1 /tmp: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /tmp is not on its own partition {CIS: 1.1.1 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 1.1.2 /tmp: nodev +[CIS - RHEL5 - 1.1.2 - Partition /tmp without 'nodev' set {CIS: 1.1.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.3 /tmp: nosuid +[CIS - RHEL5 - 1.1.3 - Partition /tmp without 'nosuid' set {CIS: 1.1.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 1.1.4 /tmp: noexec +[CIS - RHEL5 - 1.1.4 - Partition /tmp without 'noexec' set {CIS: 1.1.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.5 Build considerations - Partition scheme. +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 1.1.5 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 1.1.6 bind mount /var/tmp to /tmp +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 1.1.6 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 1.1.7 /var/log: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 1.1.7 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 1.1.8 /var/log/audit: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 1.1.8 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 1.1.9 /home: partition +[CIS - RHEL5 - - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 1.1.9 Debian RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 1.1.10 /home: nodev +[CIS - RHEL5 - 1.1.10 - Partition /home without 'nodev' set {CIS: 1.1.10 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 1.1.11 nodev on removable media partitions (not scored) +[CIS - RHEL5 - 1.1.11 - Removable partition /media without 'nodev' set {CIS: 1.1.11 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 1.1.12 noexec on removable media partitions (not scored) +[CIS - RHEL5 - 1.1.12 - Removable partition /media without 'noexec' set {CIS: 1.1.12 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 1.1.13 nosuid on removable media partitions (not scored) +[CIS - RHEL5 - 1.1.13 - Removable partition /media without 'nosuid' set {CIS: 1.1.13 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 1.1.14 /dev/shm: nodev +[CIS - RHEL5 - 1.1.11 - /dev/shm without 'nodev' set {CIS: 1.1.14 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 1.1.15 /dev/shm: nosuid +[CIS - RHEL5 - 1.1.11 - /dev/shm without 'nosuid' set {CIS: 1.1.15 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 1.1.16 /dev/shm: noexec +[CIS - RHEL5 - 1.1.11 - /dev/shm without 'noexec' set {CIS: 1.1.16 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 1.1.17 sticky bit on world writable directories (Scored) +# TODO + +# 1.1.18 disable cramfs (not scored) + +# 1.1.19 disable freevxfs (not scored) + +# 1.1.20 disable jffs2 (not scored) + +# 1.1.21 disable hfs (not scored) + +# 1.1.22 disable hfsplus (not scored) + +# 1.1.23 disable squashfs (not scored) + +# 1.1.24 disable udf (not scored) + + +########################################## +# 1.2 Software Updates +########################################## + +# 1.2.1 Configure rhn updates (not scored) + +# 1.2.2 verify RPM gpg keys (Scored) +# TODO + +# 1.2.3 verify gpgcheck enabled (Scored) +# TODO + +# 1.2.4 Disable rhnsd (not scored) + +# 1.2.5 Disable yum-updatesd (Scored) +[CIS - RHEL5 - 1.2.5 - yum-updatesd not Disabled {CIS: 1.2.5 RHEL5} {PCI_DSS: 6.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; +p:yum-updatesd; + +# 1.2.6 Obtain updates with yum (not scored) + +# 1.2.7 Verify package integrity (not scored) + + +############################################### +# 1.3 Advanced Intrusion Detection Environment +############################################### +# +# Skipped, this control is obsoleted by openarmor +# + + +############################################### +# 1.4 Configure SELinux +############################################### + +# 1.4.1 enable selinux in /etc/grub.conf +[CIS - RHEL5 - 1.4.1 - SELinux Disabled in /etc/grub.conf {CIS: 1.4.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/grub.conf -> !r:selinux=0; + +# 1.4.2 Set selinux state +[CIS - RHEL5 - 1.4.2 - SELinux not set to enforcing {CIS: 1.4.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/selinux/config -> r:SELINUX=enforcing; + +# 1.4.3 Set seliux policy +[CIS - RHEL5 - 1.4.3 - SELinux policy not set to targeted {CIS: 1.4.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/selinux/config -> r:SELINUXTYPE=targeted; + +# 1.4.4 Remove SETroubleshoot +[CIS - RHEL5 - 1.4.4 - SELinux setroubleshoot enabled {CIS: 1.4.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsetroubleshoot$; + +# 1.4.5 Disable MCS Translation service mcstrans +[CIS - RHEL5 - 1.4.5 - SELinux mctrans enabled {CIS: 1.4.5 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dmctrans$; + +# 1.4.6 Check for unconfined daemons +# TODO + + +############################################### +# 1.5 Secure Boot Settings +############################################### + +# 1.5.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) + +# 1.5.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) + +# 1.5.3 Set Boot Loader Password (Scored) +[CIS - RHEL5 - 1.5.3 - GRUB Password not set {CIS: 1.5.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +# 1.5.4 Require Authentication for Single-User Mode (Scored) +[CIS - RHEL5 - 1.5.4 - Authentication for single user mode not enabled {CIS: 1.5.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/inittab -> !r:^# && r:S:wait; + +# 1.5.5 Disable Interactive Boot (Scored) +[CIS - RHEL5 - 1.5.5 - Interactive Boot not disabled {CIS: 1.5.5 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/sysconfig/init -> !r:^# && r:PROMPT=no; + + + +############################################### +# 1.6 Additional Process Hardening +############################################### + +# 1.6.1 Restrict Core Dumps (Scored) +[CIS - RHEL5 - 1.6.1 - Interactive Boot not disabled {CIS: 1.6.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 1.6.2 Configure ExecShield (Scored) +[CIS - RHEL5 - 1.6.2 - ExecShield not enabled {CIS: 1.6.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/kernel/exec-shield -> 0; + +# 1.6.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - RHEL5 - 1.6.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 1.6.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 0; + +# 1.6.4 Enable XD/NX Support on 32-bit x86 Systems (Scored) +# TODO + +# 1.6.5 Disable Prelink (Scored) +[CIS - RHEL5 - 1.6.5 - Prelink not disabled {CIS: 1.6.5 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/sysconfig/prelink -> !r:PRELINKING=no; + + +############################################### +# 1.7 Use the Latest OS Release +############################################### + + +############################################### +# 2 OS Services +############################################### + +############################################### +# 2.1 Remove Legacy Services +############################################### + +# 2.1.1 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - RHEL5 - 2.1.1 - Telnet enabled on xinetd {CIS: 2.1.1 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; + + +# 2.1.2 Remove telnet Clients (Scored) +# TODO + +# 2.1.3 Remove rsh-server (Scored) +[CIS - RHEL5 - 2.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.1.3 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; + +# 2.1.4 Remove rsh (Scored) +# TODO + +# 2.1.5 Remove NIS Client (Scored) +[CIS - RHEL5 - 2.1.5 - Disable standard boot services - NIS (client) Enabled {CIS: 2.1.5 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; + +# 2.1.6 Remove NIS Server (Scored) +[CIS - RHEL5 - 2.1.5 - Disable standard boot services - NIS (server) Enabled {CIS: 2.1.6 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; + +# 2.1.7 Remove tftp (Scored) +# TODO + +# 2.1.8 Remove tftp-server (Scored) +[CIS - RHEL5 - 2.1.8 - tftpd enabled on xinetd {CIS: 2.1.8 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; + +# 2.1.9 Remove talk (Scored) +# TODO + +# 2.1.10 Remove talk-server (Scored) +[CIS - RHEL5 - 2.1.10 - talk enabled on xinetd {CIS: 2.1.10 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; + +# 2.1.11 Remove xinetd (Scored) +# TODO + +# 2.1.12 Disable chargen-dgram (Scored) +# TODO + +# 2.1.13 Disable chargen-stream (Scored) +# TODO + +# 2.1.14 Disable daytime-dgram (Scored) +# TODO + +# 2.1.15 Disable daytime-stream (Scored) +# TODO + +# 2.1.16 Disable echo-dgram (Scored) +# TODO + +# 2.1.17 Disable echo-stream (Scored) +# TODO + +# 2.1.18 Disable tcpmux-server (Scored) +# TODO + + +############################################### +# 3 Special Purpose Services +############################################### + +############################################### +# 3.1 Disable Avahi Server +############################################### + +# 3.1.1 Disable Avahi Server (Scored) +[CIS - RHEL5 - 3.1.1 - Avahi daemon not disabled {CIS: 3.1.1 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +p:avahi-daemon; + +# 3.1.2 Service Only via Required Protocol (Not Scored) +# TODO + +# 3.1.3 Check Responses TTL Field (Scored) +# TODO + +# 3.1.4 Prevent Other Programs from Using Avahi’s Port (Not Scored) +# TODO + +# 3.1.5 Disable Publishing (Not Scored) + +# 3.1.6 Restrict Published Information (if publishing is required) (Not scored) + +# 3.2 Set Daemon umask (Scored) +[CIS - RHEL5 - 3.2 - Set daemon umask - Default umask is higher than 027 {CIS: 3.2 RHEL5}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/init.d/functions -> !r:^# && r:^umask && <:umask 027; + +# 3.3 Remove X Windows (Scored) +[CIS - RHEL5 - 3.3 - X11 not disabled {CIS: 3.3 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +# 3.4 Disable Print Server - CUPS (Not Scored) + +# 3.5 Remove DHCP Server (Not Scored) +# TODO + +# 3.6 Configure Network Time Protocol (NTP) (Scored) +#[CIS - RHEL5 - 3.6 - NTPD not disabled {CIS: 3.6 RHEL5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +# TODO. + +# 3.7 Remove LDAP (Not Scored) + +# 3.8 Disable NFS and RPC (Not Scored) +[CIS - RHEL5 - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 3.9 Remove DNS Server (Not Scored) +# TODO + +# 3.10 Remove FTP Server (Not Scored) +[CIS - RHEL5 - 3.10 - VSFTP enabled on xinetd {CIS: 3.10 RHEL5} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 3.11 Remove HTTP Server (Not Scored) +[CIS - RHEL5 - 3.11 - Disable standard boot services - Apache web server Enabled {CIS: 3.11 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dhttpd$; + +# 3.12 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - RHEL5 - 3.12 - imap enabled on xinetd {CIS: 3.12 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - RHEL5 - 3.12 - pop3 enabled on xinetd {CIS: 3.12 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 3.13 Remove Samba (Not Scored) +[CIS - RHEL5 - 3.13 - Disable standard boot services - Samba Enabled {CIS: 3.13 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 3.14 Remove HTTP Proxy Server (Not Scored) +[CIS - RHEL5 - 3.14 - Disable standard boot services - Squid Enabled {CIS: 3.14 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 3.15 Remove SNMP Server (Not Scored) +[CIS - RHEL5 - 3.15 - Disable standard boot services - SNMPD process Enabled {CIS: 3.15 RHEL5} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 3.16 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + + +############################################### +# 4 Network Configuration and Firewalls +############################################### + +############################################### +# 4.1 Modify Network Parameters (Host Only) +############################################### + +# 4.1.1 Disable IP Forwarding (Scored) +[CIS - RHEL5 - 4.1.1 - Network parameters - IP Forwarding enabled {CIS: 4.1.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 4.1.2 Disable Send Packet Redirects (Scored) +[CIS - RHEL5 - 4.1.2 - Network parameters - IP send redirects enabled {CIS: 4.1.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + + +############################################### +# 4.2 Modify Network Parameters (Host and Router) +############################################### + +# 4.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - RHEL5 - 4.2.1 - Network parameters - Source routing accepted {CIS: 4.2.1 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 4.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - RHEL5 - 4.2.2 - Network parameters - ICMP redirects accepted {CIS: 4.2.2 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 4.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - RHEL5 - 4.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 4.2.3 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 4.2.4 Log Suspicious Packets (Scored) +[CIS - RHEL5 - 4.2.4 - Network parameters - martians not logged {CIS: 4.2.4 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 4.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - RHEL5 - 4.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 4.2.5 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 4.2.6 Enable Bad Error Message Protection (Scored) +[CIS - RHEL5 - 4.2.6 - Network parameters - Bad error message protection not enabled {CIS: 4.2.6 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 4.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - RHEL5 - 4.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 4.2.7 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 4.2.8 Enable TCP SYN Cookies (Scored) +[CIS - RHEL5 - 4.2.8 - Network parameters - SYN Cookies not enabled {CIS: 4.2.8 RHEL5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + + +############################################### +# 4.3 Wireless Networking +############################################### + +# 4.3.1 Deactivate Wireless Interfaces (Not Scored) + + +############################################### +# 4.4 Disable ipv6 +############################################### + +############################################### +# 4.4.1 Configure IPv6 +############################################### + +# 4.4.1.1 Disable IPv6 Router Advertisements (Not Scored) + +# 4.4.1.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 4.4.2 Disable IPv6 (Not Scored) + + +############################################### +# 4.5 Install TCP Wrappers +############################################### + +# 4.5.1 Install TCP Wrappers (Not Scored) + +# 4.5.2 Create /etc/hosts.allow (Not Scored) + +# 4.5.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 4.5.4 Create /etc/hosts.deny (Not Scored) + +# 4.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + + +############################################### +# 4.6 Uncommon Network Protocols +############################################### + +# 4.6.1 Disable DCCP (Not Scored) + +# 4.6.2 Disable SCTP (Not Scored) + +# 4.6.3 Disable RDS (Not Scored) + +# 4.6.4 Disable TIPC (Not Scored) + +# 4.7 Enable IPtables (Scored) +# TODO + +# 4.8 Enable IP6tables (Not Scored) + + +############################################### +# 5 Logging and Auditing +############################################### + +############################################### +# 5.1 Configure Syslog +############################################### + +# 5.1.1 Configure /etc/syslog.conf (Not Scored) + +# 5.1.2 Create and Set Permissions on syslog Log Files (Scored) + +# 5.1.3 Configure syslog to Send Logs to a Remote Log Host (Scored) + +# 5.1.4 Accept Remote syslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.2 Configure rsyslog +############################################### + +# 5.2.1 Install the rsyslog package (Not Scored) + +# 5.2.2 Activate the rsyslog Service (Not Scored) + +# 5.2.3 Configure /etc/rsyslog.conf (Not Scored) + +# 5.2.4 Create and Set Permissions on rsyslog Log Files (Not Scored) + +# 5.2.5 Configure rsyslog to Send Logs to a Remote Log Host (Not Scored) + +# 5.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.3 Configure System Accounting (auditd) +############################################### + +############################################### +# 5.3.1 Configure Data Retention +############################################### + +# 5.3.1.1 Configure Audit Log Storage Size (Not Scored) + +# 5.3.1.2 Disable System on Audit Log Full (Not Scored) + +# 5.3.1.3 Keep All Auditing Information (Scored) + +# 5.3.2 Enable auditd Service (Scored) + +# 5.3.3 Configure Audit Log Storage Size (Not Scored) + +# 5.3.4 Disable System on Audit Log Full (Not Scored) + +# 5.3.5 Keep All Auditing Information (Scored) + +# 5.3.6 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 5.3.7 Record Events That Modify Date and Time Information (Scored) + +# 5.3.8 Record Events That Modify User/Group Information (Scored) + +# 5.3.9 Record Events That Modify the System’s Network Environment (Scored) + +# 5.3.10 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 5.3.11 Collect Login and Logout Events (Scored) + +# 5.3.12 Collect Session Initiation Information (Scored) + +# 5.3.13 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 5.3.14 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 5.3.15 Collect Use of Privileged Commands (Scored) + +# 5.3.16 Collect Successful File System Mounts (Scored) + +# 5.3.17 Collect File Deletion Events by User (Scored) + +# 5.3.18 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 5.3.19 Collect System Administrator Actions (sudolog) (Scored) + +# 5.3.20 Collect Kernel Module Loading and Unloading (Scored) + +# 5.3.21 Make the Audit Configuration Immutable (Scored) + +# 5.4 Configure logrotate (Not Scored) + + +############################################### +# 6 System Access, Authentication and Authorization +############################################### + +############################################### +# 6.1 Configure cron and anacron +############################################### + +# 6.1.1 Enable anacron Daemon (Scored) + +# 6.1.2 Enable cron Daemon (Scored) + +# 6.1.3 Set User/Group Owner and Permission on /etc/anacrontab (Scored) + +# 6.1.4 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 6.1.5 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 6.1.6 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 6.1.7 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 6.1.8 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 6.1.9 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 6.1.10 Restrict at Daemon (Scored) + +# 6.1.11 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 6.1 Configure SSH +############################################### + +# 6.2.1 Set SSH Protocol to 2 (Scored) +[CIS - RHEL5 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 6.2.2 Set LogLevel to INFO (Scored) + +# 6.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) + +# 6.2.4 Disable SSH X11 Forwarding (Scored) + +# 6.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) + +# 6.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - RHEL5 - 6.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 6.2.6 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 6.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - RHEL5 - 6.2.7 - SSH Configuration - Host based authentication enabled {CIS: 6.2.7 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 6.2.8 Disable SSH Root Login (Scored) +[CIS - RHEL5 - 6.2.8 - SSH Configuration - Root login allowed {CIS: 6.2.8 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + +# 6.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - RHEL5 - 6.2.9 - SSH Configuration - Empty passwords permitted {CIS: 6.2.9 RHEL5} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +# 6.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 6.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 6.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 6.2.13 Limit Access via SSH (Scored) + +# 6.2.14 Set SSH Banner (Scored) + +# 6.2.15 Enable SSH UsePrivilegeSeparation (Scored) + + +############################################### +# 6.3 Configure PAM +############################################### + +# 6.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 6.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 6.3.3 Use pam_deny.so to Deny Services (Not Scored) + +# 6.3.4 Upgrade Password Hashing Algorithm to SHA-512 (Scored) + +# 6.3.5 Limit Password Reuse (Scored) + +# 6.3.6 Remove the pam_ccreds Package (Scored) + +# 6.4 Restrict root Login to System Console (Not Scored) + +# 6.5 Restrict Access to the su Command (Scored) + + +############################################### +# 7 User Accounts and Environment +############################################### + +############################################### +# 7.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 7.1.1 Set Password Expiration Days (Scored) + +# 7.1.2 Set Password Change Minimum Number of Days (Scored) + +# 7.1.3 Set Password Expiring Warning Days (Scored) + +# 7.2 Disable System Accounts (Scored) + +# 7.3 Set Default Group for root Account (Scored) + +# 7.4 Set Default umask for Users (Scored) + +# 7.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 8 Warning Banners +############################################### + +############################################### +# 8.1 Warning Banners for Standard Login Services +############################################### + +# 8.1.1 Set Warning Banner for Standard Login Services (Scored) + +# 8.1.2 Remove OS Information from Login Warning Banners (Scored) + +# 8.2 Set GNOME Warning Banner (Not Scored) + + +############################################### +# 9 System Maintenance +############################################### + +############################################### +# 9.1 Verify System File Permissions +############################################### + +# 9.1.1 Verify System File Permissions (Not Scored) + +# 9.1.2 Verify Permissions on /etc/passwd (Scored) + +# 9.1.3 Verify Permissions on /etc/shadow (Scored) + +# 9.1.4 Verify Permissions on /etc/gshadow (Scored) + +# 9.1.5 Verify Permissions on /etc/group (Scored) + +# 9.1.6 Verify User/Group Ownership on /etc/passwd (Scored) + +# 9.1.7 Verify User/Group Ownership on /etc/shadow (Scored) + +# 9.1.8 Verify User/Group Ownership on /etc/gshadow (Scored) + +# 9.1.9 Verify User/Group Ownership on /etc/group (Scored) + +# 9.1.10 Find World Writable Files (Not Scored) + +# 9.1.11 Find Un-owned Files and Directories (Scored) + +# 9.1.12 Find Un-grouped Files and Directories (Scored) + +# 9.1.13 Find SUID System Executables (Not Scored) + +# 9.1.14 Find SGID System Executables (Not Scored) + + +############################################### +# 9.2 Review User and Group Settings +############################################### + +# 9.2.1 Ensure Password Fields are Not Empty (Scored) + +# 9.2.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 9.2.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 9.2.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 9.2.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - RHEL5 - 9.2.5 - Non-root account with uid 0 {CIS: 9.2.5 RHEL5} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 9.2.6 Ensure root PATH Integrity (Scored) + +# 9.2.7 Check Permissions on User Home Directories (Scored) + +# 9.2.8 Check User Dot File Permissions (Scored) + +# 9.2.9 Check Permissions on User .netrc Files (Scored) + +# 9.2.10 Check for Presence of User .rhosts Files (Scored) + +# 9.2.11 Check Groups in /etc/passwd (Scored) + +# 9.2.12 Check That Users Are Assigned Home Directories (Scored) + +# 9.2.13 Check That Defined Home Directories Exist (Scored) + +# 9.2.14 Check User Home Directory Ownership (Scored) + +# 9.2.15 Check for Duplicate UIDs (Scored) + +# 9.2.16 Check for Duplicate GIDs (Scored) + +# 9.2.17 Check That Reserved UIDs Are Assigned to System Accounts + +# 9.2.18 Check for Duplicate User Names (Scored) + +# 9.2.19 Check for Duplicate Group Names (Scored) + +# 9.2.20 Check for Presence of User .netrc Files (Scored) + +# 9.2.21 Check for Presence of User .forward Files (Scored) + +# Other/Legacy Tests +[CIS - RHEL5 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - RHEL5 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - RHEL5 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_5_Benchmark_v2.1.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/src/rootcheck/db/cis_rhel6_linux_rcl.txt b/src/rootcheck/db/cis_rhel6_linux_rcl.txt new file mode 100644 index 000000000..2bf56eda5 --- /dev/null +++ b/src/rootcheck/db/cis_rhel6_linux_rcl.txt @@ -0,0 +1,787 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat / CentOS 6 +# Based on CIS Benchmark for Red Hat Enterprise Linux 6 v1.3.0 + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS Red Hat Enterprise Linux 5 Benchmark v2.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 6; +f:/etc/redhat-release -> r:^CentOS && r:release 6; +f:/etc/redhat-release -> r:^Cloud && r:release 6; +f:/etc/redhat-release -> r:^Oracle && r:release 6; +f:/etc/redhat-release -> r:^Better && r:release 6; + +# 1.1.1 /tmp: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /tmp is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 1.1.2 /tmp: nodev +[CIS - RHEL6 - 1.1.2 - Partition /tmp without 'nodev' set {CIS: 1.1.2 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.3 /tmp: nosuid +[CIS - RHEL6 - 1.1.3 - Partition /tmp without 'nosuid' set {CIS: 1.1.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 1.1.4 /tmp: noexec +[CIS - RHEL6 - 1.1.4 - Partition /tmp without 'noexec' set {CIS: 1.1.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.5 Build considerations - Partition scheme. +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 1.1.5 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 1.1.6 bind mount /var/tmp to /tmp +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 1.1.6 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 1.1.7 /var/log: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 1.1.7 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 1.1.8 /var/log/audit: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 1.1.8 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 1.1.9 /home: partition +[CIS - RHEL6 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 1.1.9 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 1.1.10 /home: nodev +[CIS - RHEL6 - 1.1.10 - Partition /home without 'nodev' set {CIS: 1.1.10 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 1.1.11 nodev on removable media partitions (not scored) +[CIS - RHEL6 - 1.1.11 - Removable partition /media without 'nodev' set {CIS: 1.1.11 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 1.1.12 noexec on removable media partitions (not scored) +[CIS - RHEL6 - 1.1.12 - Removable partition /media without 'noexec' set {CIS: 1.1.12 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 1.1.13 nosuid on removable media partitions (not scored) +[CIS - RHEL6 - 1.1.13 - Removable partition /media without 'nosuid' set {CIS: 1.1.13 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 1.1.14 /dev/shm: nodev +[CIS - RHEL6 - 1.1.14 - /dev/shm without 'nodev' set {CIS: 1.1.14 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 1.1.15 /dev/shm: nosuid +[CIS - RHEL6 - 1.1.15 - /dev/shm without 'nosuid' set {CIS: 1.1.15 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 1.1.16 /dev/shm: noexec +[CIS - RHEL6 - 1.1.16 - /dev/shm without 'noexec' set {CIS: 1.1.16 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 1.1.17 sticky bit on world writable directories (Scored) +# TODO + +# 1.1.18 disable cramfs (not scored) + +# 1.1.19 disable freevxfs (not scored) + +# 1.1.20 disable jffs2 (not scored) + +# 1.1.21 disable hfs (not scored) + +# 1.1.22 disable hfsplus (not scored) + +# 1.1.23 disable squashfs (not scored) + +# 1.1.24 disable udf (not scored) + + +########################################## +# 1.2 Software Updates +########################################## + +# 1.2.1 Configure rhn updates (not scored) + +# 1.2.2 verify RPM gpg keys (Scored) +# TODO + +# 1.2.3 verify gpgcheck enabled (Scored) +# TODO + +# 1.2.4 Disable rhnsd (not scored) + +# 1.2.5 Obtain Software Package Updates with yum (Not Scored) + +# 1.2.6 Obtain updates with yum (not scored) + + +############################################### +# 1.3 Advanced Intrusion Detection Environment +############################################### +# +# Skipped, this control is obsoleted by openarmor +# + +############################################### +# 1.4 Configure SELinux +############################################### + +# 1.4.1 enable selinux in /etc/grub.conf +[CIS - RHEL6 - 1.4.1 - SELinux Disabled in /etc/grub.conf {CIS: 1.4.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/grub.conf -> !r:selinux=0; + +# 1.4.2 Set selinux state +[CIS - RHEL6 - 1.4.2 - SELinux not set to enforcing {CIS: 1.4.2 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/selinux/config -> r:SELINUX=enforcing; + +# 1.4.3 Set seliux policy +[CIS - RHEL6 - 1.4.3 - SELinux policy not set to targeted {CIS: 1.4.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/selinux/config -> r:SELINUXTYPE=targeted; + +# 1.4.4 Remove SETroubleshoot +[CIS - RHEL6 - 1.4.4 - SELinux setroubleshoot enabled {CIS: 1.4.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsetroubleshoot$; + +# 1.4.5 Disable MCS Translation service mcstrans +[CIS - RHEL6 - 1.4.5 - SELinux mctrans enabled {CIS: 1.4.5 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dmctrans$; + +# 1.4.6 Check for unconfined daemons +# TODO + + +############################################### +# 1.5 Secure Boot Settings +############################################### + +# 1.5.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) + +# 1.5.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) + +# 1.5.3 Set Boot Loader Password (Scored) +[CIS - RHEL6 - 1.5.3 - GRUB Password not set {CIS: 1.5.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +# 1.5.4 Require Authentication for Single-User Mode (Scored) +[CIS - RHEL6 - 1.5.4 - Authentication for single user mode not enabled {CIS: 1.5.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/inittab -> !r:^# && r:S:wait; + +# 1.5.5 Disable Interactive Boot (Scored) +[CIS - RHEL6 - 1.5.5 - Interactive Boot not disabled {CIS: 1.5.5 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/sysconfig/init -> !r:^# && r:PROMPT=no; + + +############################################### +# 1.6 Additional Process Hardening +############################################### + +# 1.6.1 Restrict Core Dumps (Scored) +[CIS - RHEL6 - 1.6.1 - Interactive Boot not disabled {CIS: 1.6.1 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 1.6.2 Configure ExecShield (Scored) +[CIS - RHEL6 - 1.6.2 - ExecShield not enabled {CIS: 1.6.2 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/kernel/exec-shield -> 0; + +# 1.6.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - RHEL6 - 1.6.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 1.6.3 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 0; + + +############################################### +# 1.7 Use the Latest OS Release (Not Scored) +############################################### + + +############################################### +# 2 OS Services +############################################### + +############################################### +# 2.1 Remove Legacy Services +############################################### + +# 2.1.1 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - RHEL6 - 2.1.1 - Telnet enabled on xinetd {CIS: 2.1.1 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; + + +# 2.1.2 Remove telnet Clients (Scored) +# TODO + +# 2.1.3 Remove rsh-server (Scored) +[CIS - RHEL6 - 2.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.1.3 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; + +# 2.1.4 Remove rsh (Scored) +# TODO + +# 2.1.5 Remove NIS Client (Scored) +[CIS - RHEL6 - 2.1.5 - Disable standard boot services - NIS (client) Enabled {CIS: 2.1.5 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; + +# 2.1.6 Remove NIS Server (Scored) +[CIS - RHEL6 - 2.1.6 - Disable standard boot services - NIS (server) Enabled {CIS: 2.1.6 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; + +# 2.1.7 Remove tftp (Scored) +# TODO + +# 2.1.8 Remove tftp-server (Scored) +[CIS - RHEL6 - 2.1.8 - tftpd enabled on xinetd {CIS: 2.1.8 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; + +# 2.1.9 Remove talk (Scored) +# TODO + +# 2.1.10 Remove talk-server (Scored) +[CIS - RHEL6 - 2.1.10 - talk enabled on xinetd {CIS: 2.1.10 RHEL6} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; + +# 2.1.11 Remove xinetd (Scored) +# TODO + +# 2.1.12 Disable chargen-dgram (Scored) +# TODO + +# 2.1.13 Disable chargen-stream (Scored) +# TODO + +# 2.1.14 Disable daytime-dgram (Scored) +# TODO + +# 2.1.15 Disable daytime-stream (Scored) +# TODO + +# 2.1.16 Disable echo-dgram (Scored) +# TODO + +# 2.1.17 Disable echo-stream (Scored) +# TODO + +# 2.1.18 Disable tcpmux-server (Scored) +# TODO + + +############################################### +# 3 Special Purpose Services +############################################### + +# 3.1 Set Daemon umask (Scored) +[CIS - RHEL6 - 3.1 - Set daemon umask - Default umask is higher than 027 {CIS: 3.1 RHEL6} {PCI_DSS: 2.2.2}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/init.d/functions -> !r:^# && r:^umask && <:umask 027; + +# 3.2 Remove X Windows (Scored) +[CIS - RHEL6 - 3.2 - X11 not disabled {CIS: 3.2 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +# 3.3 Disable Avahi Server (Scored) +[CIS - RHEL6 - 3.2 - Avahi daemon not disabled {CIS: 3.3 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +p:avahi-daemon; + +# 3.4 Disable Print Server - CUPS (Not Scored) + +# 3.5 Remove DHCP Server (Not Scored) +# TODO + +# 3.6 Configure Network Time Protocol (NTP) (Scored) +#[CIS - RHEL6 - 3.6 - NTPD not disabled {CIS: 1.1.1 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +# TODO. + +# 3.7 Remove LDAP (Not Scored) + +# 3.8 Disable NFS and RPC (Not Scored) +[CIS - RHEL6 - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 3.9 Remove DNS Server (Not Scored) +# TODO + +# 3.10 Remove FTP Server (Not Scored) +[CIS - RHEL6 - 3.10 - VSFTP enabled on xinetd {CIS: 3.10 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 3.11 Remove HTTP Server (Not Scored) +[CIS - RHEL6 - 3.11 - Disable standard boot services - Apache web server Enabled {CIS: 3.11 RHEL6}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dhttpd$; + +# 3.12 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - RHEL6 - 3.12 - imap enabled on xinetd {CIS: 3.12 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - RHEL6 - 3.12 - pop3 enabled on xinetd {CIS: 3.12 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 3.13 Remove Samba (Not Scored) +[CIS - RHEL6 - 3.13 - Disable standard boot services - Samba Enabled {CIS: 3.13 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 3.14 Remove HTTP Proxy Server (Not Scored) +[CIS - RHEL6 - 3.14 - Disable standard boot services - Squid Enabled {CIS: 3.14 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 3.15 Remove SNMP Server (Not Scored) +[CIS - RHEL6 - 3.15 - Disable standard boot services - SNMPD process Enabled {CIS: 3.15 RHEL6} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 3.16 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + + +############################################### +# 4 Network Configuration and Firewalls +############################################### + +############################################### +# 4.1 Modify Network Parameters (Host Only) +############################################### + +# 4.1.1 Disable IP Forwarding (Scored) +[CIS - RHEL6 - 4.1.1 - Network parameters - IP Forwarding enabled {CIS: 4.1.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 4.1.2 Disable Send Packet Redirects (Scored) +[CIS - RHEL6 - 4.1.2 - Network parameters - IP send redirects enabled {CIS: 4.1.2 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + + +############################################### +# 4.2 Modify Network Parameters (Host and Router) +############################################### + +# 4.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - RHEL6 - 4.2.1 - Network parameters - Source routing accepted {CIS: 4.2.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 4.2.2 Disable ICMP Redirect Acceptance (Scored) +#[CIS - RHEL6 - 4.2.2 - Network parameters - ICMP redirects accepted {CIS: 1.1.1 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +#f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +#f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 4.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - RHEL6 - 4.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 4.2.3 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 4.2.4 Log Suspicious Packets (Scored) +[CIS - RHEL6 - 4.2.4 - Network parameters - martians not logged {CIS: 4.2.4 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 4.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - RHEL6 - 4.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 4.2.5 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 4.2.6 Enable Bad Error Message Protection (Scored) +[CIS - RHEL6 - 4.2.6 - Network parameters - Bad error message protection not enabled {CIS: 4.2.6 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 4.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - RHEL6 - 4.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 4.2.7 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 4.2.8 Enable TCP SYN Cookies (Scored) +[CIS - RHEL6 - 4.2.8 - Network parameters - SYN Cookies not enabled {CIS: 4.2.8 RHEL6} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + + +############################################### +# 4.3 Wireless Networking +############################################### + +# 4.3.1 Deactivate Wireless Interfaces (Not Scored) + + +############################################### +# 4.4 Disable ipv6 +############################################### + +############################################### +# 4.4.1 Configure IPv6 +############################################### + +# 4.4.1.1 Disable IPv6 Router Advertisements (Not Scored) + +# 4.4.1.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 4.4.2 Disable IPv6 (Not Scored) + + +############################################### +# 4.5 Install TCP Wrappers +############################################### + +# 4.5.1 Install TCP Wrappers (Not Scored) + +# 4.5.2 Create /etc/hosts.allow (Not Scored) + +# 4.5.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 4.5.4 Create /etc/hosts.deny (Not Scored) + +# 4.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + + +############################################### +# 4.6 Uncommon Network Protocols +############################################### + +# 4.6.1 Disable DCCP (Not Scored) + +# 4.6.2 Disable SCTP (Not Scored) + +# 4.6.3 Disable RDS (Not Scored) + +# 4.6.4 Disable TIPC (Not Scored) + +# 4.7 Enable IPtables (Scored) +# TODO + +# 4.8 Enable IP6tables (Not Scored) + + +############################################### +# 5 Logging and Auditing +############################################### + +############################################### +# 5.1 Configure Syslog +############################################### + +# 5.1.1 Install the rsyslog package (Scored) +# TODO + +# 5.1.2 Activate the rsyslog Service (Scored) +# TODO + +# 5.1.3 Configure /etc/rsyslog.conf (Not Scored) + +# 5.1.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 5.1.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 5.1.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.2 Configure System Accounting (auditd) +############################################### + +############################################### +# 5.2.1 Configure Data Retention +############################################### + +# 5.2.1.1 Configure Audit Log Storage Size (Not Scored) + +# 5.2.1.2 Disable System on Audit Log Full (Not Scored) + +# 5.2.1.3 Keep All Auditing Information (Scored) + +# 5.2.2 Enable auditd Service (Scored) + +# 5.2.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 5.2.4 Record Events That Modify Date and Time Information (Scored) + +# 5.2.5 Record Events That Modify User/Group Information (Scored) + +# 5.2.6 Record Events That Modify the System’s Network Environment (Scored) + +# 5.2.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 5.2.8 Collect Login and Logout Events (Scored) + +# 5.2.9 Collect Session Initiation Information (Scored) + +# 5.2.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 5.2.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 5.2.12 Collect Use of Privileged Commands (Scored) + +# 5.2.13 Collect Successful File System Mounts (Scored) + +# 5.2.14 Collect File Deletion Events by User (Scored) + +# 5.2.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 5.2.16 Collect System Administrator Actions (sudolog) (Scored) + +# 5.2.17 Collect Kernel Module Loading and Unloading (Scored) + +# 5.2.18 Make the Audit Configuration Immutable (Scored) + +# 5.3 Configure logrotate (Not Scored) + + +############################################### +# 6 System Access, Authentication and Authorization +############################################### + +############################################### +# 6.1 Configure cron and anacron +############################################### + +# 6.1.1 Enable anacron Daemon (Scored) + +# 6.1.2 Enable cron Daemon (Scored) + +# 6.1.3 Set User/Group Owner and Permission on /etc/anacrontab (Scored) + +# 6.1.4 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 6.1.5 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 6.1.6 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 6.1.7 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 6.1.8 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 6.1.9 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 6.1.10 Restrict at Daemon (Scored) + +# 6.1.11 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 6.1 Configure SSH +############################################### + +# 6.2.1 Set SSH Protocol to 2 (Scored) +[CIS - RHEL6 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 6.2.2 Set LogLevel to INFO (Scored) + +# 6.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) + +# 6.2.4 Disable SSH X11 Forwarding (Scored) + +# 6.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) + +# 6.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - RHEL6 - 6.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 6.2.6 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 6.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - RHEL6 - 6.2.7 - SSH Configuration - Host based authentication enabled {CIS: 6.2.7 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 6.2.8 Disable SSH Root Login (Scored) +[CIS - RHEL6 - 6.2.8 - SSH Configuration - Root login allowed {CIS: 6.2.8 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + +# 6.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - RHEL6 - 6.2.9 - SSH Configuration - Empty passwords permitted {CIS: 6.2.9 RHEL6} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +# 6.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 6.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 6.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 6.2.13 Limit Access via SSH (Scored) + +# 6.2.14 Set SSH Banner (Scored) + + +############################################### +# 6.3 Configure PAM +############################################### + +# 6.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 6.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 6.3.3 Use pam_deny.so to Deny Services (Not Scored) + +# 6.3.4 Upgrade Password Hashing Algorithm to SHA-512 (Scored) + +# 6.3.5 Limit Password Reuse (Scored) + +# 6.4 Restrict root Login to System Console (Not Scored) + +# 6.5 Restrict Access to the su Command (Scored) + + +############################################### +# 7 User Accounts and Environment +############################################### + +############################################### +# 7.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 7.1.1 Set Password Expiration Days (Scored) + +# 7.1.2 Set Password Change Minimum Number of Days (Scored) + +# 7.1.3 Set Password Expiring Warning Days (Scored) + +# 7.2 Disable System Accounts (Scored) + +# 7.3 Set Default Group for root Account (Scored) + +# 7.4 Set Default umask for Users (Scored) + +# 7.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 8 Warning Banners +############################################### + +############################################### +# 8.1 Warning Banners for Standard Login Services +############################################### + +# 8.1 Set Warning Banner for Standard Login Services (Scored) + +# 8.2 Remove OS Information from Login Warning Banners (Scored) + +# 8.3 Set GNOME Warning Banner (Not Scored) + + +############################################### +# 9 System Maintenance +############################################### + +############################################### +# 9.1 Verify System File Permissions +############################################### + +# 9.1.1 Verify System File Permissions (Not Scored) + +# 9.1.2 Verify Permissions on /etc/passwd (Scored) + +# 9.1.3 Verify Permissions on /etc/shadow (Scored) + +# 9.1.4 Verify Permissions on /etc/gshadow (Scored) + +# 9.1.5 Verify Permissions on /etc/group (Scored) + +# 9.1.6 Verify User/Group Ownership on /etc/passwd (Scored) + +# 9.1.7 Verify User/Group Ownership on /etc/shadow (Scored) + +# 9.1.8 Verify User/Group Ownership on /etc/gshadow (Scored) + +# 9.1.9 Verify User/Group Ownership on /etc/group (Scored) + +# 9.1.10 Find World Writable Files (Not Scored) + +# 9.1.11 Find Un-owned Files and Directories (Scored) + +# 9.1.12 Find Un-grouped Files and Directories (Scored) + +# 9.1.13 Find SUID System Executables (Not Scored) + +# 9.1.14 Find SGID System Executables (Not Scored) + + +############################################### +# 9.2 Review User and Group Settings +############################################### + +# 9.2.1 Ensure Password Fields are Not Empty (Scored) + +# 9.2.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 9.2.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 9.2.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 9.2.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - RHEL6 - 9.2.5 - Non-root account with uid 0 {CIS: 9.2.5 RHEL6} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 9.2.6 Ensure root PATH Integrity (Scored) + +# 9.2.7 Check Permissions on User Home Directories (Scored) + +# 9.2.8 Check User Dot File Permissions (Scored) + +# 9.2.9 Check Permissions on User .netrc Files (Scored) + +# 9.2.10 Check for Presence of User .rhosts Files (Scored) + +# 9.2.11 Check Groups in /etc/passwd (Scored) + +# 9.2.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 9.2.13 Check User Home Directory Ownership (Scored) + +# 9.2.14 Check for Duplicate UIDs (Scored) + +# 9.2.15 Check for Duplicate GIDs (Scored) + +# 9.2.16 Check for Duplicate User Names (Scored) + +# 9.2.17 Check for Duplicate Group Names (Scored) + +# 9.2.18 Check for Presence of User .netrc Files (Scored) + +# 9.2.19 Check for Presence of User .forward Files (Scored) + + +# Other/Legacy Tests +[CIS - RHEL6 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - RHEL6 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - RHEL6 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.3.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/src/rootcheck/db/cis_rhel7_linux_rcl.txt b/src/rootcheck/db/cis_rhel7_linux_rcl.txt new file mode 100644 index 000000000..cf8a297b2 --- /dev/null +++ b/src/rootcheck/db/cis_rhel7_linux_rcl.txt @@ -0,0 +1,818 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat / CentOS 7 +# Based on CIS Benchmark for Red Hat Enterprise Linux 7 v1.1.0 + +# Vars +$sshd_file=/etc/ssh/sshd_config; + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS Red Hat Enterprise Linux 7 Benchmark v1.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 7; +f:/etc/redhat-release -> r:^CentOS && r:release 7; +f:/etc/redhat-release -> r:^Cloud && r:release 7; +f:/etc/redhat-release -> r:^Oracle && r:release 7; +f:/etc/redhat-release -> r:^Better && r:release 7; +f:/etc/redhat-release -> r:^OpenVZ && r:release 7; + +# 1.1.1 /tmp: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /tmp is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 1.1.2 /tmp: nodev +[CIS - RHEL7 - 1.1.2 - Partition /tmp without 'nodev' set {CIS: 1.1.2 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 1.1.3 /tmp: nosuid +[CIS - RHEL7 - 1.1.3 - Partition /tmp without 'nosuid' set {CIS: 1.1.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 1.1.4 /tmp: noexec +[CIS - RHEL7 - 1.1.4 - Partition /tmp without 'noexec' set {CIS: 1.1.4 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:noexec; + +# 1.1.5 Build considerations - Partition scheme. +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 1.1.5 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 1.1.6 bind mount /var/tmp to /tmp +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 1.1.6 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 1.1.7 /var/log: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 1.1.7 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 1.1.8 /var/log/audit: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 1.1.8 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 1.1.9 /home: partition +[CIS - RHEL7 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 1.1.9 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 1.1.10 /home: nodev +[CIS - RHEL7 - 1.1.10 - Partition /home without 'nodev' set {CIS: 1.1.10 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 1.1.11 nodev on removable media partitions (not scored) +[CIS - RHEL7 - 1.1.11 - Removable partition /media without 'nodev' set {CIS: 1.1.11 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 1.1.12 noexec on removable media partitions (not scored) +[CIS - RHEL7 - 1.1.12 - Removable partition /media without 'noexec' set {CIS: 1.1.12 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 1.1.13 nosuid on removable media partitions (not scored) +[CIS - RHEL7 - 1.1.13 - Removable partition /media without 'nosuid' set {CIS: 1.1.13 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 1.1.14 /dev/shm: nodev +[CIS - RHEL7 - 1.1.14 - /dev/shm without 'nodev' set {CIS: 1.1.14 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 1.1.15 /dev/shm: nosuid +[CIS - RHEL7 - 1.1.15 - /dev/shm without 'nosuid' set {CIS: 1.1.15 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 1.1.16 /dev/shm: noexec +[CIS - RHEL7 - 1.1.16 - /dev/shm without 'noexec' set {CIS: 1.1.16 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 1.1.17 sticky bit on world writable directories (Scored) +# TODO + +# 1.1.18 disable cramfs (not scored) + +# 1.1.19 disable freevxfs (not scored) + +# 1.1.20 disable jffs2 (not scored) + +# 1.1.21 disable hfs (not scored) + +# 1.1.22 disable hfsplus (not scored) + +# 1.1.23 disable squashfs (not scored) + +# 1.1.24 disable udf (not scored) + + +########################################## +# 1.2 Software Updates +########################################## + +# 1.2.1 Configure rhn updates (not scored) + +# 1.2.2 verify RPM gpg keys (Scored) +# TODO + +# 1.2.3 verify gpgcheck enabled (Scored) +# TODO + +# 1.2.4 Disable rhnsd (not scored) + +# 1.2.5 Obtain Software Package Updates with yum (Not Scored) + +# 1.2.6 Obtain updates with yum (not scored) + + +############################################### +# 1.3 Advanced Intrusion Detection Environment +############################################### +# +# Skipped, this control is obsoleted by openarmor +# + +############################################### +# 1.4 Configure SELinux +############################################### + +# 1.4.1 enable selinux in /etc/grub.conf +[CIS - RHEL7 - 1.4.1 - SELinux Disabled in /etc/grub.conf {CIS: 1.4.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/grub.conf -> r:selinux=0; +f:/etc/grub2.cfg -> r:selinux=0; + +# 1.4.2 Set selinux state +[CIS - RHEL7 - 1.4.2 - SELinux not set to enforcing {CIS: 1.4.2 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/selinux/config -> !r:SELINUX=enforcing; + +# 1.4.3 Set seliux policy +[CIS - RHEL7 - 1.4.3 - SELinux policy not set to targeted {CIS: 1.4.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/selinux/config -> !r:SELINUXTYPE=targeted; + +# 1.4.4 Remove SETroubleshoot +[CIS - RHEL7 - 1.4.4 - SELinux setroubleshoot enabled {CIS: 1.4.4 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsetroubleshoot$; +f:/usr/share/dbus-1/services/sealert.service -> r:Exec=/usr/bin/sealert; + +# 1.4.5 Disable MCS Translation service mcstrans +[CIS - RHEL7 - 1.4.5 - SELinux mctrans enabled {CIS: 1.4.5 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dmctrans$; +f:/usr/lib/systemd/system/mcstransd.service -> r:ExecStart=/usr/sbin/mcstransd; + +# 1.4.6 Check for unconfined daemons +# TODO + + +############################################### +# 1.5 Secure Boot Settings +############################################### + +# 1.5.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) +# stat -L -c "%u %g" /boot/grub2/grub.cfg | egrep "0 0" + +# 1.5.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) +# stat -L -c "%a" /boot/grub2/grub.cfg | egrep ".00" + +# 1.5.3 Set Boot Loader Password (Scored) +[CIS - RHEL7 - 1.5.3 - GRUB Password not set {CIS: 1.5.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/boot/grub2/grub.cfg -> !r:^# && !r:password; + + + +############################################### +# 1.6 Additional Process Hardening +############################################### + +# 1.6.1 Restrict Core Dumps (Scored) +[CIS - RHEL7 - 1.6.1 - Interactive Boot not disabled {CIS: 1.6.1 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 1.6.1 Enable Randomized Virtual Memory Region Placement (Scored) +# Note this is also labeled 1.6.1 in the CIS benchmark. +[CIS - RHEL7 - 1.6.1 - Randomized Virtual Memory Region Placement not enabled {CIS: 1.6.3 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> !r:^2$; + + +############################################### +# 1.7 Use the Latest OS Release (Not Scored) +############################################### + + +############################################### +# 2 OS Services +############################################### + +############################################### +# 2.1 Remove Legacy Services +############################################### + +# 2.1.1 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - RHEL7 - 2.1.1 - Telnet enabled on xinetd {CIS: 2.1.1 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/telnet@.service -> r:ExecStart=-/usr/sbin/in.telnetd; + + +# 2.1.2 Remove telnet Clients (Scored) +# TODO + +# 2.1.3 Remove rsh-server (Scored) +[CIS - RHEL7 - 2.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.1.3 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; +# TODO (finish this) +f:/usr/lib/systemd/system/rexec@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rlogin@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rsh@.service -> r:ExecStart; + +# 2.1.4 Remove rsh (Scored) +# TODO + +# 2.1.5 Remove NIS Client (Scored) +[CIS - RHEL7 - 2.1.5 - Disable standard boot services - NIS (client) Enabled {CIS: 2.1.5 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; +f:/usr/lib/systemd/system/ypbind.service -> r:Exec; + +# 2.1.6 Remove NIS Server (Scored) +[CIS - RHEL7 - 2.1.6 - Disable standard boot services - NIS (server) Enabled {CIS: 2.1.6 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; +f:/usr/lib/systemd/system/ypserv.service -> r:Exec; + +# 2.1.7 Remove tftp (Scored) +# TODO + +# 2.1.8 Remove tftp-server (Scored) +[CIS - RHEL7 - 2.1.8 - tftpd enabled on xinetd {CIS: 2.1.8 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/tftp.service -> r:Exec; + +# 2.1.9 Remove talk (Scored) +# TODO + +# 2.1.10 Remove talk-server (Scored) +[CIS - RHEL7 - 2.1.10 - talk enabled on xinetd {CIS: 2.1.10 RHEL7} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/ntalk.service -> r:Exec; + +# 2.1.11 Remove xinetd (Scored) +[CIS - RHEL7 - 2.1.11 - xinetd detected {CIS: 2.1.11 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/usr/lib/systemd/system/xinetd.service -> r:Exec; + +# 2.1.12 Disable chargen-dgram (Scored) +[CIS - RHEL7 - 2.1.12 - chargen-dgram enabled on xinetd {CIS: 2.1.12 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen-dgram -> !r:^# && r:disable && r:no; + +# 2.1.13 Disable chargen-stream (Scored) +[CIS - RHEL7 - 2.1.13 - chargen-stream enabled on xinetd {CIS: 2.1.13 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen-stream -> !r:^# && r:disable && r:no; + +# 2.1.14 Disable daytime-dgram (Scored) +[CIS - RHEL7 - 2.1.14 - daytime-dgram enabled on xinetd {CIS: 2.1.14 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime-dgram -> !r:^# && r:disable && r:no; + +# 2.1.15 Disable daytime-stream (Scored) +[CIS - RHEL7 - 2.1.15 - daytime-stream enabled on xinetd {CIS: 2.1.15 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime-stream -> !r:^# && r:disable && r:no; + + +# 2.1.16 Disable echo-dgram (Scored) +[CIS - RHEL7 - 2.1.16 - echo-dgram enabled on xinetd {CIS: 2.1.16 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo-dgram -> !r:^# && r:disable && r:no; + +# 2.1.17 Disable echo-stream (Scored) +[CIS - RHEL7 - 2.1.17 - echo-stream enabled on xinetd {CIS: 2.1.17 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo-stream -> !r:^# && r:disable && r:no; + +# 2.1.18 Disable tcpmux-server (Scored) +[CIS - RHEL7 - 2.1.18 - tcpmux-server enabled on xinetd {CIS: 2.1.18 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/tcpmux-server -> !r:^# && r:disable && r:no; + + +############################################### +# 3 Special Purpose Services +############################################### + +# 3.1 Set Daemon umask (Scored) +[CIS - RHEL7 - 3.1 - Set daemon umask - Default umask is higher than 027 {CIS: 3.1 RHEL7} {PCI_DSS: 2.2.2}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/sysconfig/init -> !r:^# && r:^umask && <:umask 027; + +# 3.2 Remove X Windows (Scored) +[CIS - RHEL7 - 3.2 - X11 not disabled {CIS: 3.2 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/usr/lib/systemd/system/default.target -> r:Graphical; +p:gdm-x-session; + +# 3.3 Disable Avahi Server (Scored) +[CIS - RHEL7 - 3.2 - Avahi daemon not disabled {CIS: 3.3 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +p:avahi-daemon; + +# 3.4 Disable Print Server - CUPS (Not Scored) + +# 3.5 Remove DHCP Server (Scored) +[CIS - RHEL7 - 3.5 - DHCPnot disabled {CIS: 3.5 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/usr/lib/systemd/system/dhcpd.service -> r:Exec; + +# 3.6 Configure Network Time Protocol (NTP) (Scored) +[CIS - RHEL7 - 3.6 - NTPD not Configured {CIS: 3.6 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ntp.conf -> r:restrict default kod nomodify notrap nopeer noquery && r:^server; +f:/etc/sysconfig/ntpd -> r:OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"; + +# 3.7 Remove LDAP (Not Scored) + +# 3.8 Disable NFS and RPC (Not Scored) +[CIS - RHEL7 - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 3.9 Remove DNS Server (Not Scored) +# TODO + +# 3.10 Remove FTP Server (Not Scored) +[CIS - RHEL7 - 3.10 - VSFTP enabled on xinetd {CIS: 3.10 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 3.11 Remove HTTP Server (Not Scored) +[CIS - RHEL7 - 3.11 - Disable standard boot services - Apache web server Enabled {CIS: 3.11 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dhttpd$; + +# 3.12 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - RHEL7 - 3.12 - imap enabled on xinetd {CIS: 3.12 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - RHEL7 - 3.12 - pop3 enabled on xinetd {CIS: 3.12 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 3.13 Remove Samba (Not Scored) +[CIS - RHEL7 - 3.13 - Disable standard boot services - Samba Enabled {CIS: 3.13 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 3.14 Remove HTTP Proxy Server (Not Scored) +[CIS - RHEL7 - 3.14 - Disable standard boot services - Squid Enabled {CIS: 3.14 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 3.15 Remove SNMP Server (Not Scored) +[CIS - RHEL7 - 3.15 - Disable standard boot services - SNMPD process Enabled {CIS: 3.15 RHEL7} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 3.16 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + + +############################################### +# 4 Network Configuration and Firewalls +############################################### + +############################################### +# 4.1 Modify Network Parameters (Host Only) +############################################### + +# 4.1.1 Disable IP Forwarding (Scored) +[CIS - RHEL7 - 4.1.1 - Network parameters - IP Forwarding enabled {CIS: 4.1.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 4.1.2 Disable Send Packet Redirects (Scored) +[CIS - RHEL7 - 4.1.2 - Network parameters - IP send redirects enabled {CIS: 4.1.2 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + + +############################################### +# 4.2 Modify Network Parameters (Host and Router) +############################################### + +# 4.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - RHEL7 - 4.2.1 - Network parameters - Source routing accepted {CIS: 4.2.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 4.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - RHEL7 - 4.2.2 - Network parameters - ICMP redirects accepted {CIS: 1.1.1 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 4.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - RHEL7 - 4.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 4.2.3 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 4.2.4 Log Suspicious Packets (Scored) +[CIS - RHEL7 - 4.2.4 - Network parameters - martians not logged {CIS: 4.2.4 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 4.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - RHEL7 - 4.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 4.2.5 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 4.2.6 Enable Bad Error Message Protection (Scored) +[CIS - RHEL7 - 4.2.6 - Network parameters - Bad error message protection not enabled {CIS: 4.2.6 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 4.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - RHEL7 - 4.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 4.2.7 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 4.2.8 Enable TCP SYN Cookies (Scored) +[CIS - RHEL7 - 4.2.8 - Network parameters - SYN Cookies not enabled {CIS: 4.2.8 RHEL7} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + + +############################################### +# 4.3 Wireless Networking +############################################### + +# 4.3.1 Deactivate Wireless Interfaces (Not Scored) + + +############################################### +# 4.4 Disable ipv6 +############################################### + +############################################### +# 4.4.1 Configure IPv6 +############################################### + +# 4.4.1.1 Disable IPv6 Router Advertisements (Not Scored) + +# 4.4.1.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 4.4.2 Disable IPv6 (Not Scored) + + +############################################### +# 4.5 Install TCP Wrappers +############################################### + +# 4.5.1 Install TCP Wrappers (Not Scored) + +# 4.5.2 Create /etc/hosts.allow (Not Scored) + +# 4.5.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 4.5.4 Create /etc/hosts.deny (Not Scored) + +# 4.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + + +############################################### +# 4.6 Uncommon Network Protocols +############################################### + +# 4.6.1 Disable DCCP (Not Scored) + +# 4.6.2 Disable SCTP (Not Scored) + +# 4.6.3 Disable RDS (Not Scored) + +# 4.6.4 Disable TIPC (Not Scored) + +# 4.7 Enable IPtables (Scored) +#[CIS - RHEL7 - 4.7 - Uncommon Network Protocols - Firewalld not enabled {CIS: 4.7 RHEL7}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +#f:/usr/lib/systemd/system/firewalld.service -> TODO; + + +############################################### +# 5 Logging and Auditing +############################################### + +############################################### +# 5.1 Configure Syslog +############################################### + +# 5.1.1 Install the rsyslog package (Scored) +# TODO + +# 5.1.2 Activate the rsyslog Service (Scored) +# TODO + +# 5.1.3 Configure /etc/rsyslog.conf (Not Scored) + +# 5.1.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 5.1.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 5.1.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + + +############################################### +# 5.2 Configure System Accounting (auditd) +############################################### + +############################################### +# 5.2.1 Configure Data Retention +############################################### + +# 5.2.1.1 Configure Audit Log Storage Size (Not Scored) + +# 5.2.1.2 Disable System on Audit Log Full (Not Scored) + +# 5.2.1.3 Keep All Auditing Information (Scored) + +# 5.2.2 Enable auditd Service (Scored) + +# 5.2.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 5.2.4 Record Events That Modify Date and Time Information (Scored) + +# 5.2.5 Record Events That Modify User/Group Information (Scored) + +# 5.2.6 Record Events That Modify the System’s Network Environment (Scored) + +# 5.2.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 5.2.8 Collect Login and Logout Events (Scored) + +# 5.2.9 Collect Session Initiation Information (Scored) + +# 5.2.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 5.2.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 5.2.12 Collect Use of Privileged Commands (Scored) + +# 5.2.13 Collect Successful File System Mounts (Scored) + +# 5.2.14 Collect File Deletion Events by User (Scored) + +# 5.2.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 5.2.16 Collect System Administrator Actions (sudolog) (Scored) + +# 5.2.17 Collect Kernel Module Loading and Unloading (Scored) + +# 5.2.18 Make the Audit Configuration Immutable (Scored) + +# 5.3 Configure logrotate (Not Scored) + + +############################################### +# 6 System Access, Authentication and Authorization +############################################### + +############################################### +# 6.1 Configure cron and anacron +############################################### + +# 6.1.1 Enable anacron Daemon (Scored) + +# 6.1.2 Enable cron Daemon (Scored) + +# 6.1.3 Set User/Group Owner and Permission on /etc/anacrontab (Scored) + +# 6.1.4 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 6.1.5 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 6.1.6 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 6.1.7 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 6.1.8 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 6.1.9 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 6.1.10 Restrict at Daemon (Scored) + +# 6.1.11 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 6.1 Configure SSH +############################################### + +# 6.2.1 Set SSH Protocol to 2 (Scored) +[CIS - RHEL7 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 6.2.2 Set LogLevel to INFO (Scored) +[CIS - RHEL7 - 6.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 6.2.1 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && !r:LogLevel\.+INFO; + +# 6.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) +# TODO + +# 6.2.4 Disable SSH X11 Forwarding (Scored) +# TODO + +# 6.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) +[ CIS - RHEL7 - 6.2.5 - SSH Configuration - Set SSH MaxAuthTries to 4 or Less {CIS - RHEL7 - 6.2.5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:$sshd_file -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:$sshd_file -> r:^#\s*MaxAuthTries; +f:$sshd_file -> !r:MaxAuthTries; + +# 6.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - RHEL7 - 6.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 6.2.6 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 6.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - RHEL7 - 6.2.7 - SSH Configuration - Host based authentication enabled {CIS: 6.2.7 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 6.2.8 Disable SSH Root Login (Scored) +[CIS - RHEL7 - 6.2.8 - SSH Configuration - Root login allowed {CIS: 6.2.8 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitRootLogin; + +# 6.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - RHEL7 - 6.2.9 - SSH Configuration - Empty passwords permitted {CIS: 6.2.9 RHEL7} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitEmptyPasswords; + +# 6.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 6.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 6.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 6.2.13 Limit Access via SSH (Scored) + +# 6.2.14 Set SSH Banner (Scored) + + +############################################### +# 6.3 Configure PAM +############################################### + +# 6.3.1 Upgrade Password Hashing Algorithm to SHA-512 (Scored) +# authconfig --test | grep hashing | grep sha512 + +# 6.3.2 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 6.3.3 Set Lockout for Failed Password Attempts (Not Scored) + +# 6.3.4 Limit Password Reuse (Scored) + + +# 6.4 Restrict root Login to System Console (Not Scored) + +# 6.5 Restrict Access to the su Command (Scored) + + +############################################### +# 7 User Accounts and Environment +############################################### + +############################################### +# 7.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 7.1.1 Set Password Expiration Days (Scored) + +# 7.1.2 Set Password Change Minimum Number of Days (Scored) + +# 7.1.3 Set Password Expiring Warning Days (Scored) + +# 7.2 Disable System Accounts (Scored) + +# 7.3 Set Default Group for root Account (Scored) + +# 7.4 Set Default umask for Users (Scored) + +# 7.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 8 Warning Banners +############################################### + +############################################### +# 8.1 Warning Banners for Standard Login Services +############################################### + +# 8.1 Set Warning Banner for Standard Login Services (Scored) + +# 8.2 Remove OS Information from Login Warning Banners (Scored) + +# 8.3 Set GNOME Warning Banner (Not Scored) + + +############################################### +# 9 System Maintenance +############################################### + +############################################### +# 9.1 Verify System File Permissions +############################################### + +# 9.1.1 Verify System File Permissions (Not Scored) + +# 9.1.2 Verify Permissions on /etc/passwd (Scored) + +# 9.1.3 Verify Permissions on /etc/shadow (Scored) + +# 9.1.4 Verify Permissions on /etc/gshadow (Scored) + +# 9.1.5 Verify Permissions on /etc/group (Scored) + +# 9.1.6 Verify User/Group Ownership on /etc/passwd (Scored) + +# 9.1.7 Verify User/Group Ownership on /etc/shadow (Scored) + +# 9.1.8 Verify User/Group Ownership on /etc/gshadow (Scored) + +# 9.1.9 Verify User/Group Ownership on /etc/group (Scored) + +# 9.1.10 Find World Writable Files (Not Scored) + +# 9.1.11 Find Un-owned Files and Directories (Scored) + +# 9.1.12 Find Un-grouped Files and Directories (Scored) + +# 9.1.13 Find SUID System Executables (Not Scored) + +# 9.1.14 Find SGID System Executables (Not Scored) + + +############################################### +# 9.2 Review User and Group Settings +############################################### + +# 9.2.1 Ensure Password Fields are Not Empty (Scored) + +# 9.2.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 9.2.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 9.2.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 9.2.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - RHEL7 - 9.2.5 - Non-root account with uid 0 {CIS: 9.2.5 RHEL7} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 9.2.6 Ensure root PATH Integrity (Scored) + +# 9.2.7 Check Permissions on User Home Directories (Scored) + +# 9.2.8 Check User Dot File Permissions (Scored) + +# 9.2.9 Check Permissions on User .netrc Files (Scored) + +# 9.2.10 Check for Presence of User .rhosts Files (Scored) + +# 9.2.11 Check Groups in /etc/passwd (Scored) + +# 9.2.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 9.2.13 Check User Home Directory Ownership (Scored) + +# 9.2.14 Check for Duplicate UIDs (Scored) + +# 9.2.15 Check for Duplicate GIDs (Scored) + +# 9.2.16 Check That Reserved UIDs Are Assigned to System Accounts (Scored) + +# 9.2.17 Check for Duplicate User Names (Scored) + +# 9.2.18 Check for Duplicate Group Names (Scored) + +# 9.2.19 Check for Presence of User .netrc Files (Scored) + +# 9.2.20 Check for Presence of User .forward Files (Scored) + + +# Other/Legacy Tests +[CIS - RHEL7 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - RHEL7 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - RHEL7 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_Red_Hat_Enterprise_Linux_7_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/src/rootcheck/db/cis_rhel_linux_rcl.txt b/src/rootcheck/db/cis_rhel_linux_rcl.txt new file mode 100644 index 000000000..3c686f6aa --- /dev/null +++ b/src/rootcheck/db/cis_rhel_linux_rcl.txt @@ -0,0 +1,281 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for Red Hat (RHEL 2.1, 3.0, 4.0 and Fedora Core 1,2,3,4 and 5). +# Based on CIS Benchmark for Red Hat Enterprise Linux v1.0.5 + + + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + + +# Main one. Only valid for Red Hat/Fedora. +[CIS - Testing against the CIS Red Hat Enterprise Linux Benchmark v1.0.5] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 4; +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 3; +f:/etc/redhat-release -> r:^Red Hat Enterprise Linux \S+ release 2.1; +f:/etc/fedora-release -> r:^Fedora && r:release 1; +f:/etc/fedora-release -> r:^Fedora && r:release 2; +f:/etc/fedora-release -> r:^Fedora && r:release 3; +f:/etc/fedora-release -> r:^Fedora && r:release 4; +f:/etc/fedora-release -> r:^Fedora && r:release 5; + + +# Build considerations - Partition scheme. +[CIS - Red Hat Linux - - Build considerations - Robust partition scheme - /var is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:/var; + +[CIS - Red Hat Linux - - Build considerations - Robust partition scheme - /home is not on its own partition] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:/home; + + +# Section 1.3 - SSH configuration +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Protocol version 1 enabled {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - IgnoreRHosts disabled {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Empty passwords permitted {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Host based authentication enabled {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +[CIS - Red Hat Linux - 1.3 - SSH Configuration - Root login allowed {CIS: 1.3 Red Hat Linux} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; + + +# Section 1.4 Enable system accounting +#[CIS - Red Hat Linux - 1.4 - System Accounting - Sysstat not installed] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +#f:!/var/log/sa; + + +# Section 2.5 Install and run Bastille +#[CIS - Red Hat Linux - 1.5 - System harderning - Bastille is not installed] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +#f:!/etc/Bastille; + + +# Section 2 - Minimize xinetd services +[CIS - Red Hat Linux - 2.3 - Telnet enabled on xinetd {CIS: 2.3 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/telnet -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.4 - VSFTP enabled on xinetd {CIS: 2.4 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/vsftpd -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.4 - WU-FTP enabled on xinetd {CIS: 2.4 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/wu-ftpd -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.5 - rsh/rlogin/rcp enabled on xinetd {CIS: 2.5 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/shell -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.6 - tftpd enabled on xinetd {CIS: 2.6 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/tftpd -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.7 - imap enabled on xinetd {CIS: 2.7 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/imap -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/imaps -> !r:^# && r:disable && r:no; + +[CIS - Red Hat Linux - 2.8 - pop3 enabled on xinetd {CIS: 2.8 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/xinetd.c/ipop3 -> !r:^# && r:disable && r:no; +f:/etc/xinetd.c/pop3s -> !r:^# && r:disable && r:no; + + +# Section 3 - Minimize boot services +[CIS - Red Hat Linux - 3.1 - Set daemon umask - Default umask is higher than 027 {CIS: 3.1 Red Hat Linux}] [all] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/init.d/functions -> !r:^# && r:^umask && >:umask 027; + +[CIS - Red Hat Linux - 3.4 - GUI login enabled {CIS: 3.4 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +[CIS - Red Hat Linux - 3.7 - Disable standard boot services - Samba Enabled {CIS: 3.7 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +[CIS - Red Hat Linux - 3.8 - Disable standard boot services - NFS Enabled {CIS: 3.8 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +[CIS - Red Hat Linux - 3.10 - Disable standard boot services - NIS Enabled {CIS: 3.10 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dypbind$; +d:$rc_dirs -> ^S\d\dypserv$; + +[CIS - Red Hat Linux - 3.13 - Disable standard boot services - NetFS Enabled {CIS: 3.13 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; + +[CIS - Red Hat Linux - 3.15 - Disable standard boot services - Apache web server Enabled {CIS: 3.15 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dapache$; +d:$rc_dirs -> ^S\d\dhttpd$; + +[CIS - Red Hat Linux - 3.15 - Disable standard boot services - TUX web server Enabled {CIS: 3.15 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dtux$; + +[CIS - Red Hat Linux - 3.16 - Disable standard boot services - SNMPD process Enabled {CIS: 3.16 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +[CIS - Red Hat Linux - 3.17 - Disable standard boot services - DNS server Enabled {CIS: 3.17 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - Red Hat Linux - 3.18 - Disable standard boot services - MySQL server Enabled {CIS: 3.18 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - Red Hat Linux - 3.18 - Disable standard boot services - PostgreSQL server Enabled {CIS: 3.18 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - Red Hat Linux - 3.19 - Disable standard boot services - Webmin Enabled {CIS: 3.19 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dwebmin$; + +[CIS - Red Hat Linux - 3.20 - Disable standard boot services - Squid Enabled {CIS: 3.20 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +[CIS - Red Hat Linux - 3.21 - Disable standard boot services - Kudzu hardware detection Enabled {CIS: 3.21 Red Hat Linux} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + + +# Section 4 - Kernel tuning +[CIS - Red Hat Linux - 4.1 - Network parameters - Source routing accepted {CIS: 4.1 Red Hat Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +[CIS - Red Hat Linux - 4.1 - Network parameters - ICMP broadcasts accepted {CIS: 4.1 Red Hat Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +[CIS - Red Hat Linux - 4.2 - Network parameters - IP Forwarding enabled {CIS: 4.2 Red Hat Linux}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + + +# Section 6 - Permissions +[CIS - Red Hat Linux - 6.1 - Partition /var without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/var && !r:nodev; + +[CIS - Red Hat Linux - 6.1 - Partition /tmp without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/tmp && !r:nodev; + +[CIS - Red Hat Linux - 6.1 - Partition /opt without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/opt && !r:nodev; + +[CIS - Red Hat Linux - 6.1 - Partition /home without 'nodev' set {CIS: 6.1 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:ext2|ext3 && r:/home && !r:nodev ; + +[CIS - Red Hat Linux - 6.2 - Removable partition /media without 'nodev' set {CIS: 6.2 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +[CIS - Red Hat Linux - 6.2 - Removable partition /media without 'nosuid' set {CIS: 6.2 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +[CIS - Red Hat Linux - 6.3 - User-mounted removable partition allowed on the console {CIS: 6.3 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + + +# Section 7 - Access and authentication +[CIS - Red Hat Linux - 7.8 - LILO Password not set {CIS: 7.8 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/lilo.conf -> !r:^# && !r:restricted; +f:/etc/lilo.conf -> !r:^# && !r:password=; + +[CIS - Red Hat Linux - 7.8 - GRUB Password not set {CIS: 7.8 Red Hat Linux} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/boot/grub/menu.lst -> !r:^# && !r:password; + +[CIS - Red Hat Linux - 8.2 - Account with empty password present {CIS: 8.2 Red Hat Linux} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - Red Hat Linux - SN.11 - Non-root account with uid 0 {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_RHLinux_Benchmark_v1.0.5.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + + +# Tests specific for VMware ESX - Runs on Red Hat Linux - +# Will not be tested anywhere else. +[VMware ESX - Testing against the Security Harderning benchmark VI3 for ESX 3.5] [any required] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +f:/etc/vmware-release -> r:^VMware ESX; + + +# Virtual Machine Files and Settings - 1 +# 1.1 +[VMware ESX - VM settings - Copy operation between guest and console enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.copy.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.copy.disable && r:false; + +# 1.2 +[VMware ESX - VM settings - Paste operation between guest and console enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.paste.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.paste.disable && r:false; + +# 1.3 +[VMware ESX - VM settings - GUI Options enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.setGUIOptions.enable && r:true; + +# 1.4 +[VMware ESX - VM settings - Data Flow from the Virtual Machine to the Datastore not limited - Rotate size not 100KB] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^log.rotateSize; +d:/vmfs/volumes -> .vmx$ -> r:^log.rotateSize && !r:"100000"; + +# 1.5 +[VMware ESX - VM settings - Data Flow from the Virtual Machine to the Datastore not limited - Maximum number of logs not 10] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^log.keepOld; +d:/vmfs/volumes -> .vmx$ -> r:^log.keepOld && r:"10"; + +# 1.6 +[VMware ESX - VM settings - Data Flow from the Virtual Machine to the Datastore not limited - Guests allowed to write SetInfo data to config] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.setinfo.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.setinfo.disable && r:false; + +# 1.7 +[VMware ESX - VM settings - Nonpersistent Disks being used] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^scsi\d:\d.mode && r:!independent-nonpersistent; + +# 1.8 +[VMware ESX - VM settings - Floppy drive present] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^floppy\d+.present && r:!false; + +[VMware ESX - VM settings - Serial port present] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^serial\d+.present && r:!false; + +[VMware ESX - VM settings - Parallel port present] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> r:^parallel\d+.present && r:!false; + +# 1.9 +[VMware ESX - VM settings - Unauthorized Removal or Connection of Devices allowed] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^Isolation.tools.connectable.disable; +d:/vmfs/volumes -> .vmx$ -> r:^Isolation.tools.connectable.disable && r:false; + +# 1.10 +[VMware ESX - VM settings - Avoid Denial of Service Caused by Virtual Disk Modification Operations - diskWiper enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.diskWiper.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.diskWiper.disable && r:false; + +[VMware ESX - VM settings - Avoid Denial of Service Caused by Virtual Disk Modification Operations - diskShrink enabled] [any] [http://www.vmware.com/pdf/vi3_security_hardening_wp.pdf] +d:/vmfs/volumes -> .vmx$ -> !r:^isolation.tools.diskShrink.disable; +d:/vmfs/volumes -> .vmx$ -> r:^isolation.tools.diskShrink.disable && r:false; + + +# Configuring the Service Console in ESX 3.5 - 2 +# 2.1 diff --git a/src/rootcheck/db/cis_sles11_linux_rcl.txt b/src/rootcheck/db/cis_sles11_linux_rcl.txt new file mode 100644 index 000000000..1eb8270cd --- /dev/null +++ b/src/rootcheck/db/cis_sles11_linux_rcl.txt @@ -0,0 +1,728 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for SUSE SLES 11 +# Based on CIS Benchmark for SUSE Linux Enterprise Server 11 v1.1.0 + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS SUSE Linux Enterprise Server 11 Benchmark v1.1.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP1"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP2"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP3"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 11 SP4"; + +# 2.1 /tmp: partition +[CIS - SLES11 - 2.1 - Build considerations - Robust partition scheme - /tmp is not on its own partition {CIS: 2.2 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 2.2 /tmp: nodev +[CIS - SLES11 - 2.2 - Partition /tmp without 'nodev' set {CIS: 2.2 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.3 /tmp: nosuid +[CIS - SLES11 - 2.3 - Partition /tmp without 'nosuid' set {CIS: 2.3 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 2.4 /tmp: noexec +[CIS - SLES11 - 2.4 - Partition /tmp without 'noexec' set {CIS: 2.4 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.5 Build considerations - Partition scheme. +[CIS - SLES11 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 2.5 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 2.6 bind mount /var/tmp to /tmp +[CIS - SLES11 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 2.6 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 2.7 /var/log: partition +[CIS - SLES11 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 2.7 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 2.8 /var/log/audit: partition +[CIS - SLES11 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 2.8 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 2.9 /home: partition +[CIS - SLES11 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 2.9 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 2.10 /home: nodev +[CIS - SLES11 - 2.10 - Partition /home without 'nodev' set {CIS: 2.10 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 2.11 nodev on removable media partitions (not scored) +[CIS - SLES11 - 2.11 - Removable partition /media without 'nodev' set {CIS: 2.11 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 2.12 noexec on removable media partitions (not scored) +[CIS - SLES11 - 2.12 - Removable partition /media without 'noexec' set {CIS: 2.12 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 2.13 nosuid on removable media partitions (not scored) +[CIS - SLES11 - 2.13 - Removable partition /media without 'nosuid' set {CIS: 2.13 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 2.14 /dev/shm: nodev +[CIS - SLES11 - 2.14 - /dev/shm without 'nodev' set {CIS: 2.14 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 2.15 /dev/shm: nosuid +[CIS - SLES11 - 2.15 - /dev/shm without 'nosuid' set {CIS: 2.15 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 2.16 /dev/shm: noexec +[CIS - SLES11 - 2.16 - /dev/shm without 'noexec' set {CIS: 2.16 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 2.17 sticky bit on world writable directories (Scored) +# TODO + +# 2.18 disable cramfs (not scored) + +# 2.19 disable freevxfs (not scored) + +# 2.20 disable jffs2 (not scored) + +# 2.21 disable hfs (not scored) + +# 2.22 disable hfsplus (not scored) + +# 2.23 disable squashfs (not scored) + +# 2.24 disable udf (not scored) + +# 2.25 disable automounting (Scored) +# TODO + +############################################### +# 3 Secure Boot Settings +############################################### + +# 3.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) +# stat -L -c "%u %g" /boot/grub2/grub.cfg | egrep "0 0" + +# 3.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) +# stat -L -c "%a" /boot/grub2/grub.cfg | egrep ".00" + +# 3.3 Set Boot Loader Password (Scored) +[CIS - SLES11 - 3.3 - GRUB Password not set {CIS: 3.3 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/boot/grub2/grub.cfg -> !r:^# && !r:password; + +# 3.4 Require Authentication for Single-User Mode (Scored) + +# 3.5 Disable Interactive Boot (Scored) + +############################################### +# 4 Additional Process Hardening +############################################### + +# 4.1 Restrict Core Dumps (Scored) +[CIS - SLES11 - 4.1 - Interactive Boot not disabled {CIS: 4.1 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 4.2 Enable XD/NX Support on 32-bit x86 Systems (Not Scored) +# TODO + +# 4.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - SLES11 - 4.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 4.3 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 2; + +# 4.4 Disable Prelink (Scored) +# TODO + +# 4.5 Activate AppArmor (Scored) +# TODO + +############################################### +# 5 OS Services +############################################### + +############################################### +# 5.1 Remove Legacy Services +############################################### + +# 5.1.1 Remove NIS Server (Scored) +[CIS - SLES11 - 5.1.1 - Disable standard boot services - NIS (server) Enabled {CIS: 5.1.1 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; + +# 5.1.2 Remove NIS Client (Scored) +[CIS - SLES11 - 5.1.2 - Disable standard boot services - NIS (client) Enabled {CIS: 51.2 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; + +# 5.1.3 Remove rsh-server (Scored) +[CIS - SLES11 - 5.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 5.1.3 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; + +# 5.1.4 Remove rsh client (Scored) +# TODO + +# 5.1.5 Remove talk-server (Scored) +[CIS - SLES11 - 5.1.5 - talk enabled on xinetd {CIS: 5.1.5 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; + +# 5.1.6 Remove talk client (Scored) +# TODO + +# 5.1.7 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - SLES11 - 5.1.7 - Telnet enabled on xinetd {CIS: 5.1.7 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; + +# 5.1.8 Remove tftp-server (Scored) +[CIS - SLES11 - 5.1.8 - tftpd enabled on xinetd {CIS: 5.1.8 SLES11} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; + +# 5.1.9 Remove xinetd (Scored) +[CIS - SLES11 - 5.1.9 - xinetd detected {CIS: 5.1.9 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] + +# 5.2 Disable chargen-udp (Scored) +[CIS - SLES11 - 5.2 - chargen-udp enabled on xinetd {CIS: 5.2 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen-udp -> !r:^# && r:disable && r:no; + +# 5.3 Disable chargen (Scored) +[CIS - SLES11 - 5.3 - chargen enabled on xinetd {CIS: 5.3 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/chargen -> !r:^# && r:disable && r:no; + +# 5.4 Disable daytime-udp (Scored) +[CIS - SLES11 - 5.4 - daytime-udp enabled on xinetd {CIS: 5.4 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime-udp -> !r:^# && r:disable && r:no; + +# 5.5 Disable daytime (Scored) +[CIS - SLES11 - 5.5 - daytime enabled on xinetd {CIS: 5.5 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/daytime -> !r:^# && r:disable && r:no; + + +# 5.6 Disable echo-udp (Scored) +[CIS - SLES11 - 5.6 - echo-udp enabled on xinetd {CIS: 5.6 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo-udp -> !r:^# && r:disable && r:no; + +# 5.7 Disable echo (Scored) +[CIS - SLES11 - 5.7 - echo enabled on xinetd {CIS: 5.7 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/echo -> !r:^# && r:disable && r:no; + +# 5.8 Disable discard-udp (Scored) +[CIS - SLES11 - 5.8 - discard-udp enabled on xinetd {CIS: 5.8 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/discard-udp -> !r:^# && r:disable && r:no; + +# 5.9 Disable discard (Scored) +[CIS - SLES11 - 5.9 - discard enabled on xinetd {CIS: 5.9 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/discard -> !r:^# && r:disable && r:no; + +# 5.10 Disable time-udp (Scored) +[CIS - SLES11 - 5.10 - time-udp enabled on xinetd {CIS: 5.10 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/time-udp -> !r:^# && r:disable && r:no; + +# 5.11 Disable time (Scored) +[CIS - SLES11 - 5.11 - time enabled on xinetd {CIS: 5.11 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/time -> !r:^# && r:disable && r:no; + +############################################### +# 6 Special Purpose Services +############################################### + +# 6.1 Remove X Windows (Scored) +[CIS - SLES11 - 6.1 - X11 not disabled {CIS: 6.1 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/inittab -> !r:^# && r:id:5; + +# 6.2 Disable Avahi Server (Scored) +[CIS - SLES11 - 6.2 - Avahi daemon not disabled {CIS: 6.2 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +p:avahi-daemon; + +# 6.3 Disable Print Server - CUPS (Not Scored) +#TODO + +# 6.4 Remove DHCP Server (Scored) +#[CIS - SLES11 - 6.4 - DHCPnot disabled {CIS: 6.4 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dhcpd$; +d:$rc_dirs -> ^S\d\dhcpd6$; + +# 6.5 Configure Network Time Protocol (NTP) (Scored) +#TODO Chrony +[CIS - SLES11 - 6.5 - NTPD not Configured {CIS: 6.5 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ntp.conf -> r:restrict default kod nomodify notrap nopeer noquery && r:^server; +f:/etc/sysconfig/ntpd -> r:OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"; + +# 6.6 Remove LDAP (Not Scored) +#TODO + +# 6.7 Disable NFS and RPC (Not Scored) +[CIS - SLES11 - 6.7 - Disable standard boot services - NFS Enabled {CIS: 6.7 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 6.8 Remove DNS Server (Not Scored) +# TODO + +# 6.9 Remove FTP Server (Not Scored) +[CIS - SLES11 - 6.9 - VSFTP enabled on xinetd {CIS: 6.9 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 6.10 Remove HTTP Server (Not Scored) +[CIS - SLES11 - 6.10 - Disable standard boot services - Apache web server Enabled {CIS: 6.10 SLES11}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dapache2$; + +# 6.11 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - SLES11 - 6.11 - imap enabled on xinetd {CIS: 6.11 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - SLES11 - 6.11 - pop3 enabled on xinetd {CIS: 6.11 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 6.12 Remove Samba (Not Scored) +[CIS - SLES11 - 6.12 - Disable standard boot services - Samba Enabled {CIS: 6.12 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 6.13 Remove HTTP Proxy Server (Not Scored) +[CIS - SLES11 - 6.13 - Disable standard boot services - Squid Enabled {CIS: 6.13 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 6.14 Remove SNMP Server (Not Scored) +[CIS - SLES11 - 6.14 - Disable standard boot services - SNMPD process Enabled {CIS: 6.14 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 6.15 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + +# 6.16 Ensure rsync service is not enabled (Scored) +[CIS - SLES11 - 6.16 - Disable standard boot services - rsyncd process Enabled {CIS: 6.16 SLES11} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\drsyncd$; + +# 6.17 Ensure Biosdevname is not enabled (Scored) +# TODO + +############################################### +# 7 Network Configuration and Firewalls +############################################### + +############################################### +# 7.1 Modify Network Parameters (Host Only) +############################################### + +# 7.1.1 Disable IP Forwarding (Scored) +[CIS - SLES11 - 7.1.1 - Network parameters - IP Forwarding enabled {CIS: 7.1.1 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 7.1.2 Disable Send Packet Redirects (Scored) +[CIS - SLES11 - 7.1.2 - Network parameters - IP send redirects enabled {CIS: 7.1.2 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + +############################################### +# 7.2 Modify Network Parameters (Host and Router) +############################################### + +# 7.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - SLES11 - 7.2.1 - Network parameters - Source routing accepted {CIS: 7.2.1 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 7.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - SLES11 - 7.2.2 - Network parameters - ICMP redirects accepted {CIS: 7.2.2 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 7.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - SLES11 - 7.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 7.2.3 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 7.2.4 Log Suspicious Packets (Scored) +[CIS - SLES11 - 7.2.4 - Network parameters - martians not logged {CIS: 7.2.4 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 7.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - SLES11 - 7.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 7.2.5 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 7.2.6 Enable Bad Error Message Protection (Scored) +[CIS - SLES11 - 7.2.6 - Network parameters - Bad error message protection not enabled {CIS: 7.2.6 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 7.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - SLES11 - 7.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 7.2.7 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 7.2.8 Enable TCP SYN Cookies (Scored) +[CIS - SLES11 - 7.2.8 - Network parameters - SYN Cookies not enabled {CIS: 7.2.8 SLES11} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + +############################################### +# 7.3 Configure IPv6 +############################################### + +# 7.3.1 Disable IPv6 Router Advertisements (Not Scored) + +# 7.3.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 7.3.3 Disable IPv6 (Not Scored) + +############################################### +# 7.4 Install TCP Wrappers +############################################### + +# 7.4.1 Install TCP Wrappers (Not Scored) + +# 7.4.2 Create /etc/hosts.allow (Not Scored) + +# 7.4.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 7.4.4 Create /etc/hosts.deny (Not Scored) + +# 7.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + +############################################### +# 7.5 Uncommon Network Protocols +############################################### + +# 7.5.1 Disable DCCP (Not Scored) + +# 7.5.2 Disable SCTP (Not Scored) + +# 7.5.3 Disable RDS (Not Scored) + +# 7.5.4 Disable TIPC (Not Scored) + +# 7.6 Deactivate Wireless Interfaces (Not Scored) + +# 7.7 Enable SuSEfirewall2 (Scored) + +# 7.8 Limit access to trusted networks (Not Scored) + +############################################### +# 8 Logging and Auditing +############################################### + +############################################### +# 8.1 Configure System Accounting (auditd) +############################################### + +############################################### +# 8.1.1 Configure Data Retention +############################################### + +# 8.1.1.1 Configure Audit Log Storage Size (Not Scored) + +# 8.1.1.2 Disable System on Audit Log Full (Not Scored) + +# 8.1.1.3 Keep All Auditing Information (Scored) + +# 8.1.2 Enable auditd Service (Scored) + +# 8.1.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 8.1.4 Record Events That Modify Date and Time Information (Scored) + +# 8.1.5 Record Events That Modify User/Group Information (Scored) + +# 8.1.6 Record Events That Modify the System’s Network Environment (Scored) + +# 8.1.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 8.1.8 Collect Login and Logout Events (Scored) + +# 8.1.9 Collect Session Initiation Information (Scored) + +# 8.1.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 8.1.12 Collect Use of Privileged Commands (Scored) + +# 8.1.13 Collect Successful File System Mounts (Scored) + +# 8.1.14 Collect File Deletion Events by User (Scored) + +# 8.1.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 8.1.16 Collect System Administrator Actions (sudolog) (Scored) + +# 8.1.17 Collect Kernel Module Loading and Unloading (Scored) + +# 8.1.18 Make the Audit Configuration Immutable (Scored) + +############################################### +# 8.2 Configure rsyslog +############################################### + +# 8.2.1 Install the rsyslog package (Scored) +# TODO + +# 8.2.2 Activate the rsyslog Service (Scored) +# TODO + +# 8.2.3 Configure /etc/rsyslog.conf (Not Scored) + +# 8.2.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + +############################################### +# 8.3 Advanced Intrusion Detection Environment (AIDE) +############################################### + +# 8.3.1 Install AIDE (Scored) + +# 8.3.2 Implement Periodic Execution of File Integrity (Scored) + +# 8.4 Configure logrotate (Not Scored) + +############################################### +# 9 System Access, Authentication and Authorization +############################################### + +############################################### +# 9.1 Configure cron and anacron +############################################### + +# 9.1.1 Enable cron Daemon (Scored) + +# 9.1.2 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 9.1.3 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 9.1.4 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 9.1.5 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 9.1.6 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 9.1.7 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 9.1.8 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 9.2 Configure SSH +############################################### + +# 9.2.1 Set SSH Protocol to 2 (Scored) +[CIS - SLES11 - 9.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 9.2.1 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 9.2.2 Set LogLevel to INFO (Scored) +[CIS - SLES11 - 9.2.1 - SSH Configuration - Loglevel not INFO {CIS: 9.2.1 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && !r:LogLevel\.+INFO; + +# 9.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) +# TODO + +# 9.2.4 Disable SSH X11 Forwarding (Scored) +# TODO + +# 9.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) +[ CIS - SLES11 - 9.2.5 - SSH Configuration - Set SSH MaxAuthTries to 4 or Less {CIS - SLES11 - 9.2.5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:/etc/ssh/sshd_config -> r:^#\s*MaxAuthTries; +f:/etc/ssh/sshd_config -> !r:MaxAuthTries; + +# 9.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - SLES11 - 9.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 9.2.6 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 9.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - SLES11 - 9.2.7 - SSH Configuration - Host based authentication enabled {CIS: 9.2.7 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 9.2.8 Disable SSH Root Login (Scored) +[CIS - SLES11 - 9.2.8 - SSH Configuration - Root login allowed {CIS: 9.2.8 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitRootLogin; + +# 9.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - SLES11 - 9.2.9 - SSH Configuration - Empty passwords permitted {CIS: 9.2.9 SLES11} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitEmptyPasswords; + +# 9.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 9.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 9.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 9.2.13 Limit Access via SSH (Scored) + +# 9.2.14 Set SSH Banner (Scored) + +############################################### +# 9.3 Configure PAM +############################################### + +# 9.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 9.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 9.3.3 Limit Password Reuse (Scored) + +# 9.4 Restrict root Login to System Console (Not Scored) + +# 9.5 Restrict Access to the su Command (Scored) + +############################################### +# 10 User Accounts and Environment +############################################### + +############################################### +# 10.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 10.1.1 Set Password Expiration Days (Scored) + +# 10.1.2 Set Password Change Minimum Number of Days (Scored) + +# 10.1.3 Set Password Expiring Warning Days (Scored) + +# 10.2 Disable System Accounts (Scored) + +# 10.3 Set Default Group for root Account (Scored) + +# 10.4 Set Default umask for Users (Scored) + +# 10.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 11 Warning Banners +############################################### + +# 11.1 Set Warning Banner for Standard Login Services (Scored) + +# 11.2 Remove OS Information from Login Warning Banners (Scored) + +# 11.3 Set Graphical Warning Banner (Not Scored) + +############################################### +# 12 Verify System File Permissions +############################################### + +# 12.1 Verify System File Permissions (Not Scored) + +# 12.2 Verify Permissions on /etc/passwd (Scored) + +# 12.3 Verify Permissions on /etc/shadow (Scored) + +# 12.4 Verify Permissions on /etc/group (Scored) + +# 12.5 Verify User/Group Ownership on /etc/passwd (Scored) + +# 12.6 Verify User/Group Ownership on /etc/shadow (Scored) + +# 12.7 Verify User/Group Ownership on /etc/group (Scored) + +# 12.8 Find World Writable Files (Not Scored) + +# 12.9 Find Un-owned Files and Directories (Scored) + +# 12.10 Find Un-grouped Files and Directories (Scored) + +# 12.11 Find SUID System Executables (Not Scored) + +# 12.12 Find SGID System Executables (Not Scored) + +############################################### +# 13 Review User and Group Settings +############################################### + +# 13.1 Ensure Password Fields are Not Empty (Scored) + +# 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 13.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 13.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - SLES11 - 13.5 - Non-root account with uid 0 {CIS: 13.5 SLES11} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 13.6 Ensure root PATH Integrity (Scored) + +# 13.7 Check Permissions on User Home Directories (Scored) + +# 13.8 Check User Dot File Permissions (Scored) + +# 13.9 Check Permissions on User .netrc Files (Scored) + +# 13.10 Check for Presence of User .rhosts Files (Scored) + +# 13.11 Check Groups in /etc/passwd (Scored) + +# 13.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 13.13 Check User Home Directory Ownership (Scored) + +# 13.14 Check for Duplicate UIDs (Scored) + +# 13.15 Check for Duplicate GIDs (Scored) + +# 13.16 Check for Duplicate User Names (Scored) + +# 13.17 Check for Duplicate Group Names (Scored) + +# 13.18 Check for Presence of User .netrc Files (Scored) + +# 13.19 Check for Presence of User .forward Files (Scored) + +# 13.20 Ensure shadow group is empty (Scored) + + +# Other/Legacy Tests +[CIS - SLES11 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - SLES11 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - SLES11 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - SLES11 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_11_Benchmark_v1.1.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/src/rootcheck/db/cis_sles12_linux_rcl.txt b/src/rootcheck/db/cis_sles12_linux_rcl.txt new file mode 100644 index 000000000..1241ab6c6 --- /dev/null +++ b/src/rootcheck/db/cis_sles12_linux_rcl.txt @@ -0,0 +1,734 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + + +# CIS Checks for SUSE SLES 12 +# Based on CIS Benchmark for SUSE Linux Enterprise Server 12 v1.0.0 + +# RC scripts location +$rc_dirs=/etc/rc.d/rc2.d,/etc/rc.d/rc3.d,/etc/rc.d/rc4.d,/etc/rc.d/rc5.d; + + +[CIS - Testing against the CIS SUSE Linux Enterprise Server 12 Benchmark v1.0.0] [any required] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP1"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP2"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"; +f:/etc/os-release -> r:^PRETTY_NAME="SUSE Linux Enterprise Server 12 SP4"; + +# 2.1 /tmp: partition +[CIS - SLES12 - 2.1 - Build considerations - Robust partition scheme - /tmp is not on its own partition {CIS: 2.2 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:/tmp; + +# 2.2 /tmp: nodev +[CIS - SLES12 - 2.2 - Partition /tmp without 'nodev' set {CIS: 2.2 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.3 /tmp: nosuid +[CIS - SLES12 - 2.3 - Partition /tmp without 'nosuid' set {CIS: 2.3 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nosuid; + +# 2.4 /tmp: noexec +[CIS - SLES12 - 2.4 - Partition /tmp without 'noexec' set {CIS: 2.4 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/tmp && !r:nodev; + +# 2.5 Build considerations - Partition scheme. +[CIS - SLES12 - Build considerations - Robust partition scheme - /var is not on its own partition {CIS: 2.5 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r^# && !r:/var; + +# 2.6 bind mount /var/tmp to /tmp +[CIS - SLES12 - Build considerations - Robust partition scheme - /var/tmp is bound to /tmp {CIS: 2.6 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> r:^# && !r:/var/tmp && !r:bind; + +# 2.7 /var/log: partition +[CIS - SLES12 - Build considerations - Robust partition scheme - /var/log is not on its own partition {CIS: 2.7 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log; + +# 2.8 /var/log/audit: partition +[CIS - SLES12 - Build considerations - Robust partition scheme - /var/log/audit is not on its own partition {CIS: 2.8 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> ^# && !r:/var/log/audit; + +# 2.9 /home: partition +[CIS - SLES12 - Build considerations - Robust partition scheme - /home is not on its own partition {CIS: 2.9 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> ^# && !r:/home; + +# 2.10 /home: nodev +[CIS - SLES12 - 2.10 - Partition /home without 'nodev' set {CIS: 2.10 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/home && !r:nodev; + +# 2.11 nodev on removable media partitions (not scored) +[CIS - SLES12 - 2.11 - Removable partition /media without 'nodev' set {CIS: 2.11 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nodev; + +# 2.12 noexec on removable media partitions (not scored) +[CIS - SLES12 - 2.12 - Removable partition /media without 'noexec' set {CIS: 2.12 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:noexec; + +# 2.13 nosuid on removable media partitions (not scored) +[CIS - SLES12 - 2.13 - Removable partition /media without 'nosuid' set {CIS: 2.13 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/media && !r:nosuid; + +# 2.14 /dev/shm: nodev +[CIS - SLES12 - 2.14 - /dev/shm without 'nodev' set {CIS: 2.14 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nodev; + +# 2.15 /dev/shm: nosuid +[CIS - SLES12 - 2.15 - /dev/shm without 'nosuid' set {CIS: 2.15 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:nosuid; + +# 2.16 /dev/shm: noexec +[CIS - SLES12 - 2.16 - /dev/shm without 'noexec' set {CIS: 2.16 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/fstab -> !r:^# && r:/dev/shm && !r:noexec; + +# 2.17 sticky bit on world writable directories (Scored) +# TODO + +# 2.18 disable cramfs (not scored) + +# 2.19 disable freevxfs (not scored) + +# 2.20 disable jffs2 (not scored) + +# 2.21 disable hfs (not scored) + +# 2.22 disable hfsplus (not scored) + +# 2.23 disable squashfs (not scored) + +# 2.24 disable udf (not scored) + +# 2.25 disable automounting (Scored) +# TODO + +############################################### +# 3 Secure Boot Settings +############################################### + +# 3.1 Set User/Group Owner on /etc/grub.conf +# TODO (no mode tests) +# stat -L -c "%u %g" /boot/grub2/grub.cfg | egrep "0 0" + +# 3.2 Set Permissions on /etc/grub.conf (Scored) +# TODO (no mode tests) +# stat -L -c "%a" /boot/grub2/grub.cfg | egrep ".00" + +# 3.3 Set Boot Loader Password (Scored) +[CIS - SLES12 - 3.3 - GRUB Password not set {CIS: 3.3 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/boot/grub2/grub.cfg -> !r:^# && !r:password; + +############################################### +# 4 Additional Process Hardening +############################################### + +# 4.1 Restrict Core Dumps (Scored) +[CIS - SLES12 - 4.1 - Interactive Boot not disabled {CIS: 4.1 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/security/limits.conf -> !r:^# && !r:hard\.+core\.+0; + +# 4.2 Enable XD/NX Support on 32-bit x86 Systems (Not Scored) +# TODO + +# 4.3 Enable Randomized Virtual Memory Region Placement (Scored) +[CIS - SLES12 - 4.3 - Randomized Virtual Memory Region Placement not enabled {CIS: 4.3 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/kernel/randomize_va_space -> 2; + +# 4.4 Disable Prelink (Scored) +# TODO + +# 4.5 Activate AppArmor (Scored) +# TODO + +############################################### +# 5 OS Services +############################################### + +############################################### +# 5.1 Remove Legacy Services +############################################### + +# 5.1.1 Remove NIS Server (Scored) +[CIS - SLES12 - 5.1.1 - Disable standard boot services - NIS (server) Enabled {CIS: 5.1.1 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dypserv$; +f:/usr/lib/systemd/system/ypserv.service -> r:Exec; + +# 5.1.2 Remove NIS Client (Scored) +[CIS - SLES12 - 5.1.2 - Disable standard boot services - NIS (client) Enabled {CIS: 51.2 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dypbind$; +f:/usr/lib/systemd/system/ypbind.service -> r:Exec; + +# 5.1.3 Remove rsh-server (Scored) +[CIS - SLES12 - 5.1.3 - rsh/rlogin/rcp enabled on xinetd {CIS: 5.1.3 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/rlogin -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/rsh -> !r:^# && r:disable && r:no; +f:/etc/xinetd.d/shell -> !r:^# && r:disable && r:no; +# TODO (finish this) +f:/usr/lib/systemd/system/rexec@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rlogin@.service -> r:ExecStart; +f:/usr/lib/systemd/system/rsh@.service -> r:ExecStart; + +# 5.1.4 Remove rsh client (Scored) +# TODO + +# 5.1.5 Remove talk-server (Scored) +[CIS - SLES12 - 5.1.5 - talk enabled on xinetd {CIS: 5.1.5 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/talk -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/ntalk.service -> r:Exec; + +# 5.1.6 Remove talk client (Scored) +# TODO + +# 5.1.7 Remove telnet-server (Scored) +# TODO: detect it is installed at all +[CIS - SLES12 - 5.1.7 - Telnet enabled on xinetd {CIS: 5.1.7 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/telnet -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/telnet@.service -> r:ExecStart=-/usr/sbin/in.telnetd; + +# 5.1.8 Remove tftp-server (Scored) +[CIS - SLES12 - 5.1.8 - tftpd enabled on xinetd {CIS: 5.1.8 SLES12} {PCI_DSS: 2.2.3}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/tftpd -> !r:^# && r:disable && r:no; +f:/usr/lib/systemd/system/tftp.service -> r:Exec; + +# 5.1.9 Remove xinetd (Scored) +[CIS - SLES12 - 5.1.9 - xinetd detected {CIS: 5.1.9 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/usr/lib/systemd/system/xinetd.service -> r:Exec; + +# 5.2 Disable chargen-udp (Scored) +[CIS - SLES12 - 5.2 - chargen-udp enabled on xinetd {CIS: 5.2 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/chargen-udp -> !r:^# && r:disable && r:no; + +# 5.3 Disable chargen (Scored) +[CIS - SLES12 - 5.3 - chargen enabled on xinetd {CIS: 5.3 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/chargen -> !r:^# && r:disable && r:no; + +# 5.4 Disable daytime-udp (Scored) +[CIS - SLES12 - 5.4 - daytime-udp enabled on xinetd {CIS: 5.4 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/daytime-udp -> !r:^# && r:disable && r:no; + +# 5.5 Disable daytime (Scored) +[CIS - SLES12 - 5.5 - daytime enabled on xinetd {CIS: 5.5 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/daytime -> !r:^# && r:disable && r:no; + + +# 5.6 Disable echo-udp (Scored) +[CIS - SLES12 - 5.6 - echo-udp enabled on xinetd {CIS: 5.6 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/echo-udp -> !r:^# && r:disable && r:no; + +# 5.7 Disable echo (Scored) +[CIS - SLES12 - 5.7 - echo enabled on xinetd {CIS: 5.7 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/echo -> !r:^# && r:disable && r:no; + +# 5.8 Disable discard-udp (Scored) +[CIS - SLES12 - 5.8 - discard-udp enabled on xinetd {CIS: 5.8 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/discard-udp -> !r:^# && r:disable && r:no; + +# 5.9 Disable discard (Scored) +[CIS - SLES12 - 5.9 - discard enabled on xinetd {CIS: 5.9 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/discard -> !r:^# && r:disable && r:no; + +# 5.10 Disable time-udp (Scored) +[CIS - SLES12 - 5.10 - time-udp enabled on xinetd {CIS: 5.10 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/time-udp -> !r:^# && r:disable && r:no; + +# 5.11 Disable time (Scored) +[CIS - SLES12 - 5.11 - time enabled on xinetd {CIS: 5.11 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/time -> !r:^# && r:disable && r:no; + +############################################### +# 6 Special Purpose Services +############################################### + +# 6.1 Remove X Windows (Scored) +[CIS - SLES12 - 6.1 - X11 not disabled {CIS: 6.1 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/usr/lib/systemd/system/default.target -> r:Graphical; +p:gdm-x-session; + +# 6.2 Disable Avahi Server (Scored) +[CIS - SLES12 - 6.2 - Avahi daemon not disabled {CIS: 6.2 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +p:avahi-daemon; + +# 6.3 Disable Print Server - CUPS (Not Scored) +#TODO + +# 6.4 Remove DHCP Server (Scored) +[CIS - SLES12 - 6.4 - DHCPnot disabled {CIS: 6.4 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/usr/lib/systemd/system/dhcpd.service -> r:Exec; + +# 6.5 Configure Network Time Protocol (NTP) (Scored) +#TODO Chrony +[CIS - SLES12 - 6.5 - NTPD not Configured {CIS: 6.5 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ntp.conf -> r:restrict default kod nomodify notrap nopeer noquery && r:^server; +f:/etc/sysconfig/ntpd -> r:OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"; + +# 6.6 Remove LDAP (Not Scored) +#TODO + +# 6.7 Disable NFS and RPC (Not Scored) +[CIS - SLES12 - 6.7 - Disable standard boot services - NFS Enabled {CIS: 6.7 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dnfs$; +d:$rc_dirs -> ^S\d\dnfslock$; + +# 6.8 Remove DNS Server (Not Scored) +# TODO + +# 6.9 Remove FTP Server (Not Scored) +[CIS - SLES12 - 6.9 - VSFTP enabled on xinetd {CIS: 6.9 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/vsftpd -> !r:^# && r:disable && r:no; + +# 6.10 Remove HTTP Server (Not Scored) +[CIS - SLES12 - 6.10 - Disable standard boot services - Apache web server Enabled {CIS: 6.10 SLES12}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dapache2$; + +# 6.11 Remove Dovecot (IMAP and POP3 services) (Not Scored) +[CIS - SLES12 - 6.11 - imap enabled on xinetd {CIS: 6.11 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/cyrus-imapd -> !r:^# && r:disable && r:no; + +[CIS - SLES12 - 6.11 - pop3 enabled on xinetd {CIS: 6.11 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/xinetd.d/dovecot -> !r:^# && r:disable && r:no; + +# 6.12 Remove Samba (Not Scored) +[CIS - SLES12 - 6.12 - Disable standard boot services - Samba Enabled {CIS: 6.12 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dsamba$; +d:$rc_dirs -> ^S\d\dsmb$; + +# 6.13 Remove HTTP Proxy Server (Not Scored) +[CIS - SLES12 - 6.13 - Disable standard boot services - Squid Enabled {CIS: 6.13 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dsquid$; + +# 6.14 Remove SNMP Server (Not Scored) +[CIS - SLES12 - 6.14 - Disable standard boot services - SNMPD process Enabled {CIS: 6.14 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dsnmpd$; + +# 6.15 Configure Mail Transfer Agent for Local-Only Mode (Scored) +# TODO + +# 6.16 Ensure rsync service is not enabled (Scored) +[CIS - SLES12 - 6.16 - Disable standard boot services - rsyncd process Enabled {CIS: 6.16 SLES12} {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\drsyncd$; + +# 6.17 Ensure Biosdevname is not enabled (Scored) +# TODO + +############################################### +# 7 Network Configuration and Firewalls +############################################### + +############################################### +# 7.1 Modify Network Parameters (Host Only) +############################################### + +# 7.1.1 Disable IP Forwarding (Scored) +[CIS - SLES12 - 7.1.1 - Network parameters - IP Forwarding enabled {CIS: 7.1.1 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/ip_forward -> 1; +f:/proc/sys/net/ipv6/ip_forward -> 1; + +# 7.1.2 Disable Send Packet Redirects (Scored) +[CIS - SLES12 - 7.1.2 - Network parameters - IP send redirects enabled {CIS: 7.1.2 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/send_redirects -> 0; +f:/proc/sys/net/ipv4/conf/default/send_redirects -> 0; + +############################################### +# 7.2 Modify Network Parameters (Host and Router) +############################################### + +# 7.2.1 Disable Source Routed Packet Acceptance (Scored) +[CIS - SLES12 - 7.2.1 - Network parameters - Source routing accepted {CIS: 7.2.1 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_source_route -> 1; + +# 7.2.2 Disable ICMP Redirect Acceptance (Scored) +[CIS - SLES12 - 7.2.2 - Network parameters - ICMP redirects accepted {CIS: 7.2.2 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/accept_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/accept_redirects -> 1; + +# 7.2.3 Disable Secure ICMP Redirect Acceptance (Scored) +[CIS - SLES12 - 7.2.3 - Network parameters - ICMP secure redirects accepted {CIS: 7.2.3 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/secure_redirects -> 1; +f:/proc/sys/net/ipv4/conf/default/secure_redirects -> 1; + +# 7.2.4 Log Suspicious Packets (Scored) +[CIS - SLES12 - 7.2.4 - Network parameters - martians not logged {CIS: 7.2.4 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/log_martians -> 0; + +# 7.2.5 Enable Ignore Broadcast Requests (Scored) +[CIS - SLES12 - 7.2.5 - Network parameters - ICMP broadcasts accepted {CIS: 7.2.5 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts -> 0; + +# 7.2.6 Enable Bad Error Message Protection (Scored) +[CIS - SLES12 - 7.2.6 - Network parameters - Bad error message protection not enabled {CIS: 7.2.6 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses -> 0; + +# 7.2.7 Enable RFC-recommended Source Route Validation (Scored) +[CIS - SLES12 - 7.2.7 - Network parameters - RFC Source route validation not enabled {CIS: 7.2.7 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/conf/all/rp_filter -> 0; +f:/proc/sys/net/ipv4/conf/default/rp_filter -> 0; + +# 7.2.8 Enable TCP SYN Cookies (Scored) +[CIS - SLES12 - 7.2.8 - Network parameters - SYN Cookies not enabled {CIS: 7.2.8 SLES12} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/proc/sys/net/ipv4/tcp_syncookies -> 0; + +############################################### +# 7.3 Configure IPv6 +############################################### + +# 7.3.1 Disable IPv6 Router Advertisements (Not Scored) + +# 7.3.2 Disable IPv6 Redirect Acceptance (Not Scored) + +# 7.3.3 Disable IPv6 (Not Scored) + +############################################### +# 7.4 Install TCP Wrappers +############################################### + +# 7.4.1 Install TCP Wrappers (Not Scored) + +# 7.4.2 Create /etc/hosts.allow (Not Scored) + +# 7.4.3 Verify Permissions on /etc/hosts.allow (Scored) +# TODO + +# 7.4.4 Create /etc/hosts.deny (Not Scored) + +# 7.5.5 Verify Permissions on /etc/hosts.deny (Scored) +# TODO + +############################################### +# 7.5 Uncommon Network Protocols +############################################### + +# 7.5.1 Disable DCCP (Not Scored) + +# 7.5.2 Disable SCTP (Not Scored) + +# 7.5.3 Disable RDS (Not Scored) + +# 7.5.4 Disable TIPC (Not Scored) + +# 7.6 Deactivate Wireless Interfaces (Not Scored) + +# 7.7 Enable SuSEfirewall2 (Scored) + +# 7.8 Limit access to trusted networks (Not Scored) + +############################################### +# 8 Logging and Auditing +############################################### + +############################################### +# 8.1 Configure System Accounting (auditd) +############################################### + +############################################### +# 8.1.1 Configure Data Retention +############################################### + +# 8.1.1.1 Configure Audit Log Storage Size (Not Scored) + +# 8.1.1.2 Disable System on Audit Log Full (Not Scored) + +# 8.1.1.3 Keep All Auditing Information (Scored) + +# 8.1.2 Enable auditd Service (Scored) + +# 8.1.3 Enable Auditing for Processes That Start Prior to auditd (Scored) + +# 8.1.4 Record Events That Modify Date and Time Information (Scored) + +# 8.1.5 Record Events That Modify User/Group Information (Scored) + +# 8.1.6 Record Events That Modify the System’s Network Environment (Scored) + +# 8.1.7 Record Events That Modify the System’s Mandatory Access Controls (Scored) + +# 8.1.8 Collect Login and Logout Events (Scored) + +# 8.1.9 Collect Session Initiation Information (Scored) + +# 8.1.10 Collect Discretionary Access Control Permission Modification Events (Scored) + +# 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files (Scored) + +# 8.1.12 Collect Use of Privileged Commands (Scored) + +# 8.1.13 Collect Successful File System Mounts (Scored) + +# 8.1.14 Collect File Deletion Events by User (Scored) + +# 8.1.15 Collect Changes to System Administration Scope (sudoers) (Scored) + +# 8.1.16 Collect System Administrator Actions (sudolog) (Scored) + +# 8.1.17 Collect Kernel Module Loading and Unloading (Scored) + +# 8.1.18 Make the Audit Configuration Immutable (Scored) + +############################################### +# 8.2 Configure rsyslog +############################################### + +# 8.2.1 Install the rsyslog package (Scored) +# TODO + +# 8.2.2 Activate the rsyslog Service (Scored) +# TODO + +# 8.2.3 Configure /etc/rsyslog.conf (Not Scored) + +# 8.2.4 Create and Set Permissions on rsyslog Log Files (Scored) + +# 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host (Scored) + +# 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) + +############################################### +# 8.3 Advanced Intrusion Detection Environment (AIDE) +############################################### + +# 8.3.1 Install AIDE (Scored) + +# 8.3.2 Implement Periodic Execution of File Integrity (Scored) + +# 8.4 Configure logrotate (Not Scored) + +############################################### +# 9 System Access, Authentication and Authorization +############################################### + +############################################### +# 9.1 Configure cron and anacron +############################################### + +# 9.1.1 Enable cron Daemon (Scored) + +# 9.1.2 Set User/Group Owner and Permission on /etc/crontab (Scored) + +# 9.1.3 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) + +# 9.1.4 Set User/Group Owner and Permission on /etc/cron.daily (Scored) + +# 9.1.5 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) + +# 9.1.6 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) + +# 9.1.7 Set User/Group Owner and Permission on /etc/cron.d (Scored) + +# 9.1.8 Restrict at/cron to Authorized Users (Scored) + +############################################### +# 9.2 Configure SSH +############################################### + +# 9.2.1 Set SSH Protocol to 2 (Scored) +[CIS - SLES12 - 9.2.1 - SSH Configuration - Protocol version 1 enabled {CIS: 9.2.1 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:Protocol\.+1; + +# 9.2.2 Set LogLevel to INFO (Scored) +[CIS - SLES12 - 9.2.1 - SSH Configuration - Loglevel not INFO {CIS: 9.2.1 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && !r:LogLevel\.+INFO; + +# 9.2.3 Set Permissions on /etc/ssh/sshd_config (Scored) +# TODO + +# 9.2.4 Disable SSH X11 Forwarding (Scored) +# TODO + +# 9.2.5 Set SSH MaxAuthTries to 4 or Less (Scored) +[ CIS - SLES12 - 9.2.5 - SSH Configuration - Set SSH MaxAuthTries to 4 or Less {CIS - SLES12 - 9.2.5} {PCI_DSS: 2.2.4}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:/etc/ssh/sshd_config -> r:^#\s*MaxAuthTries; +f:/etc/ssh/sshd_config -> !r:MaxAuthTries; + +# 9.2.6 Set SSH IgnoreRhosts to Yes (Scored) +[CIS - SLES12 - 9.2.6 - SSH Configuration - IgnoreRHosts disabled {CIS: 9.2.6 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\.+no; + +# 9.2.7 Set SSH HostbasedAuthentication to No (Scored) +[CIS - SLES12 - 9.2.7 - SSH Configuration - Host based authentication enabled {CIS: 9.2.7 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:HostbasedAuthentication\.+yes; + +# 9.2.8 Disable SSH Root Login (Scored) +[CIS - SLES12 - 9.2.8 - SSH Configuration - Root login allowed {CIS: 9.2.8 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitRootLogin; + +# 9.2.9 Set SSH PermitEmptyPasswords to No (Scored) +[CIS - SLES12 - 9.2.9 - SSH Configuration - Empty passwords permitted {CIS: 9.2.9 SLES12} {PCI_DSS: 4.1}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/ssh/sshd_config -> !r:^# && r:^PermitEmptyPasswords\.+yes; +f:/etc/ssh/sshd_config -> r:^#\s*PermitEmptyPasswords; + +# 9.2.10 Do Not Allow Users to Set Environment Options (Scored) + +# 9.2.11 Use Only Approved Ciphers in Counter Mode (Scored) + +# 9.2.12 Set Idle Timeout Interval for User Login (Not Scored) + +# 9.2.13 Limit Access via SSH (Scored) + +# 9.2.14 Set SSH Banner (Scored) + +############################################### +# 9.3 Configure PAM +############################################### + +# 9.3.1 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) + +# 9.3.2 Set Lockout for Failed Password Attempts (Not Scored) + +# 9.3.3 Limit Password Reuse (Scored) + +# 9.4 Restrict root Login to System Console (Not Scored) + +# 9.5 Restrict Access to the su Command (Scored) + +############################################### +# 10 User Accounts and Environment +############################################### + +############################################### +# 10.1 Set Shadow Password Suite Parameters (/etc/login.defs) +############################################### + +# 10.1.1 Set Password Expiration Days (Scored) + +# 10.1.2 Set Password Change Minimum Number of Days (Scored) + +# 10.1.3 Set Password Expiring Warning Days (Scored) + +# 10.2 Disable System Accounts (Scored) + +# 10.3 Set Default Group for root Account (Scored) + +# 10.4 Set Default umask for Users (Scored) + +# 10.5 Lock Inactive User Accounts (Scored) + + +############################################### +# 11 Warning Banners +############################################### + +# 11.1 Set Warning Banner for Standard Login Services (Scored) + +# 11.2 Remove OS Information from Login Warning Banners (Scored) + +# 11.3 Set Graphical Warning Banner (Not Scored) + +############################################### +# 12 Verify System File Permissions +############################################### + +# 12.1 Verify System File Permissions (Not Scored) + +# 12.2 Verify Permissions on /etc/passwd (Scored) + +# 12.3 Verify Permissions on /etc/shadow (Scored) + +# 12.4 Verify Permissions on /etc/group (Scored) + +# 12.5 Verify User/Group Ownership on /etc/passwd (Scored) + +# 12.6 Verify User/Group Ownership on /etc/shadow (Scored) + +# 12.7 Verify User/Group Ownership on /etc/group (Scored) + +# 12.8 Find World Writable Files (Not Scored) + +# 12.9 Find Un-owned Files and Directories (Scored) + +# 12.10 Find Un-grouped Files and Directories (Scored) + +# 12.11 Find SUID System Executables (Not Scored) + +# 12.12 Find SGID System Executables (Not Scored) + +############################################### +# 13 Review User and Group Settings +############################################### + +# 13.1 Ensure Password Fields are Not Empty (Scored) + +# 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) + +# 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) + +# 13.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) + +# 13.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +[CIS - SLES12 - 13.5 - Non-root account with uid 0 {CIS: 13.5 SLES12} {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/passwd -> !r:^# && !r:^root: && r:^\w+:\w+:0:; + +# 13.6 Ensure root PATH Integrity (Scored) + +# 13.7 Check Permissions on User Home Directories (Scored) + +# 13.8 Check User Dot File Permissions (Scored) + +# 13.9 Check Permissions on User .netrc Files (Scored) + +# 13.10 Check for Presence of User .rhosts Files (Scored) + +# 13.11 Check Groups in /etc/passwd (Scored) + +# 13.12 Check That Users Are Assigned Valid Home Directories (Scored) + +# 13.13 Check User Home Directory Ownership (Scored) + +# 13.14 Check for Duplicate UIDs (Scored) + +# 13.15 Check for Duplicate GIDs (Scored) + +# 13.16 Check for Duplicate User Names (Scored) + +# 13.17 Check for Duplicate Group Names (Scored) + +# 13.18 Check for Presence of User .netrc Files (Scored) + +# 13.19 Check for Presence of User .forward Files (Scored) + +# 13.20 Ensure shadow group is empty (Scored) + + +# Other/Legacy Tests +[CIS - SLES12 - X.X.X - Account with empty password present {PCI_DSS: 10.2.5}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/shadow -> r:^\w+::; + +[CIS - SLES12 - X.X.X - User-mounted removable partition allowed on the console] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +f:/etc/security/console.perms -> r:^ \d+ ; +f:/etc/security/console.perms -> r:^ \d+ ; + +[CIS - SLES12 - X.X.X - Disable standard boot services - Kudzu hardware detection Enabled] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dkudzu$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - PostgreSQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dpostgresql$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - MySQL server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dmysqld$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - DNS server Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dnamed$; + +[CIS - SLES12 - X.X.X - Disable standard boot services - NetFS Enabled {PCI_DSS: 2.2.2}] [any] [https://benchmarks.cisecurity.org/tools2/linux/CIS_SUSE_Linux_Enterprise_Server_12_Benchmark_v1.0.0.pdf] +d:$rc_dirs -> ^S\d\dnetfs$; diff --git a/src/rootcheck/db/cis_solaris11_rcl.txt b/src/rootcheck/db/cis_solaris11_rcl.txt new file mode 100644 index 000000000..899eb1470 --- /dev/null +++ b/src/rootcheck/db/cis_solaris11_rcl.txt @@ -0,0 +1,475 @@ +# openarmor Linux Audit - (C) 2017 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Solaris 11 +# Based on Center for Internet Security Benchmark for Solaris 11 Benchmark v1.1.0 https://workbench.cisecurity.org/benchmarks/410 +# +$home_dirs=/usr2/home/*,/home/*,/home,/*/home/*,/*/home,/; +# +# +#2.1 Disable Local-only Graphical Login Environment +[CIS - Solaris 11 Configuration - 2.1 Disable Local-only Graphical Login Environment] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:gdm; +p:cde; +# +# +#2.2 Configure sendmail Service for Local-Only Mode +[CIS - Solaris 11 Configuration - 2.2 Configure sendmail Service for Local-Only Mode] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:!/etc/mail/local.cf; +# +# +#2.3 Disable RPC Encryption Key +[CIS - Solaris 11 Configuration - 2.3 Disable RPC Encryption Key] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:keyserv; +# +# +#2.4 Disable NIS Server Services +[CIS - Solaris 11 Configuration - 2.4 Disable NIS Server Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:ypserv; +p:ypbind; +p:ypxfr; +p:rpc.yppasswdd; +p:rpc.ypupdated; +f:/etc/init.d/nis; +# +# +#2.5 Disable NIS Client Services +[CIS - Solaris 11 Configuration - 2.5 Disable NIS Client Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:ypserv; +p:ypbind; +p:ypxfr; +p:rpc.yppasswdd; +p:rpc.ypupdated; +f:/etc/init.d/nis; +# +# +#2.6 Disable Kerberos TGT Expiration Warning +[CIS - Solaris 11 Configuration - 2.6 Disable Kerberos TGT Expiration Warning] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:ktkt_warnd; +# +# +#2.7 Disable Generic Security Services (GSS) +[CIS - Solaris 11 Configuration - 2.7 Disable Generic Security Services (GSS)] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:gssd; +# +# +#2.8 Disable Removable Volume Manager +[CIS - Solaris 11 Configuration - 2.8 Disable Removable Volume Manager] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:smserverd; +# +# +#2.9 Disable automount Service +[CIS - Solaris 11 Configuration - 2.9 Disable automount Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:automountd; +# +# +#2.10 Disable Apache Service +[CIS - Solaris 11 Configuration - 2.10 Disable Apache Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:apache; +p:httpd; +# +# +#2.11 Disable Local-only RPC Port Mapping Service +[CIS - Solaris 11 Configuration - 2.11 Disable Local-only RPC Port Mapping Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:rpcbind; +# +# +#2.12 Configure TCP Wrappers +[CIS - Solaris 11 Configuration - 2.12 Configure TCP Wrappers] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:!/etc/hosts.allow; +f:!/etc/hosts.deny; +# +# +#2.13 Disable Telnet Service +[CIS - Solaris 11 Configuration - 2.13 Disable Telnet Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +p:telnetd; +# +# +#3.1 Restrict Core Dumps to Protected Directory +[CIS - Solaris 11 Configuration - 3.1 Restrict Core Dumps to Protected Directory] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_PATTERN\p\.+; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_CONTENT\pdefault; +f:/etc/coreadm.conf -> !r:^COREADM_INIT_PATTERN\pcore; +f:/etc/coreadm.conf -> !r:^COREADM_INIT_CONTENT\pdefault; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_ENABLED\pyes|^COREADM_GLOB_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_PROC_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_SETID_ENABLED\pyes|^COREADM_GLOB_SETID_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_PROC_SETID_ENABLED\pno; +f:/etc/coreadm.conf -> !r:^COREADM_GLOB_LOG_ENABLED\pyes; +# +# +#3.2 Enable Stack Protection +[CIS - Solaris 11 Configuration - 3.2 Enable Stack Protection] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:!/etc/system; +f:/etc/system -> !r:^\s*\t*noexec_user_stack\p1; +f:/etc/system -> !r:^# && r:\s*\t*noexec_user_stack\p0; +f:/etc/system -> !r:^\s*\t*noexec_user_stack_log\p1; +f:/etc/system -> !r:^# && r:\s*\t*noexec_user_stack_log\p0; +# +# +#3.3 Enable Strong TCP Sequence Number Generation +[CIS - Solaris 11 Configuration - 3.3 Enable Strong TCP Sequence Number Generation] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/inetinit -> !r:^TCP_STRONG_ISS\p2; +f:/etc/default/inetinit -> !r:^# && r:TCP_STRONG_ISS\p1; +# +# +#4.1 Create CIS Audit Class +[CIS - Solaris 11 Configuration - 4.1 Create CIS Audit Class] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_class -> !r:0x\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d:cis:\.+; +# +# +#4.2 Enable Auditing of Incoming Network Connections +[CIS - Solaris 11 Configuration - 4.2 Enable Auditing of Incoming Network Connections] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_event -> !r:^\d+:AUE_ACCEPT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_CONNECT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SOCKACCEPT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SOCKCONNECT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_inetd_connect:\.+cis\.*; +# +# +#4.3 Enable Auditing of File Metadata Modification Events +[CIS - Solaris 11 Configuration - 4.3 Enable Auditing of File Metadata Modification Events] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_event -> !r:^\d+:AUE_CHMOD:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_CHOWN:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FCHOWN:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FCHMOD:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_LCHOWN:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_ACLSET:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FACLSET:\.+cis\.*; +# +# +#4.4 Enable Auditing of Process and Privilege Events +[CIS - Solaris 11 Configuration - 4.4 Enable Auditing of Process and Privilege Events] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/security/audit_event -> !r:^\d+:AUE_CHROOT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETREUID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETREGID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_FCHROOT:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_PFEXEC:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETUID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_NICE:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETGID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_PRIOCNTLSYS:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETEGID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETEUID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETPRIV:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETSID:\.+cis\.*; +f:/etc/security/audit_event -> !r:^\d+:AUE_SETPGID:\.+cis\.*; +# +# +#4.5 Configure Solaris Auditing +[CIS - Solaris 11 Configuration - 4.5 Configure Solaris Auditing] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:/var/spool/cron/crontabs -> !r:/usr/sbin/audit -n; +# +# +#5.1 Default Service File Creation Mask +[CIS - Solaris 11 Configuration - 5.1 Default Service File Creation Mask] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/profile -> !r:^umask\s*\d\d\d; +# +# +#6.2 Disable "nobody" Access for RPC Encryption Key Storage Service +[CIS - Solaris 11 Configuration - 6.2 Disable "nobody" Access for RPC Encryption Key Storage Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f!:/etc/default/keyserv; +f:/etc/default/keyserv -> !r:^ENABLE\.NOBODY\.KEYS\pNO; +f:/etc/default/keyserv -> !r:^# && r:ENABLE\.NOBODY\.KEYS\pYES; +# +# +#6.3 Disable X11 Forwarding for SSH +[CIS - Solaris 11 Configuration - 6.3 Disable X11 Forwarding for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^X11Forwarding\s*no; +f:/etc/ssh/sshd_config -> !r:^# && r:X11Forwarding\s*yes; +# +# +#6.4 Limit Consecutive Login Attempts for SSH +[CIS - Solaris 11 Configuration - 6.4 Limit Consecutive Login Attempts for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^MaxAuthTries\s*3; +f:/etc/ssh/sshd_config -> !r:^# && r:MaxAuthTries\s*3\d+; +# +# +#6.5 Disable Rhost-based Authentication for SSH +[CIS - Solaris 11 Configuration - 6.5 Disable Rhost-based Authentication for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^IgnoreRhosts\s*yes; +f:/etc/ssh/sshd_config -> !r:^# && r:IgnoreRhosts\s*no; +# +# +#6.6 Disable root login for SSH +[CIS - Solaris 11 Configuration - 6.6 Disable root login for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^PermitRootLogin\s*no; +f:/etc/ssh/sshd_config -> !r:^# && r:PermitRootLogin\s*yes; +# +# +#6.7 Blocking Authentication Using Empty/Null Passwords for SSH +[CIS - Solaris 11 Configuration - 6.7 Blocking Authentication Using Empty/Null Passwords for SSH] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^PermitEmptyPasswords\s*no; +f:/etc/ssh/sshd_config -> !r:^# && r:PermitEmptyPasswords\s*yes; +# +# +#6.8 Disable Host-based Authentication for Login-based Services +[CIS - Solaris 11 Configuration - 6.8 Disable Host-based Authentication for Login-based Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/pam.conf -> !r:^rlogin\s*\t*auth sufficient\s*\t*pam_rhosts_auth.so.1; +f:/etc/pam.conf -> !r:^rsh\s*\t*auth sufficient\s*\t*pam_rhosts_auth.so.1; +# +# +#6.9 Restrict FTP Use +[CIS - Solaris 11 Configuration - 6.9 Restrict FTP Use] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ftpd/ftpusers -> !r:^root; +f:/etc/ftpd/ftpusers -> !r:^daemon; +f:/etc/ftpd/ftpusers -> !r:^bin; +f:/etc/ftpd/ftpusers -> !r:^sys; +f:/etc/ftpd/ftpusers -> !r:^adm; +f:/etc/ftpd/ftpusers -> !r:^uucp; +f:/etc/ftpd/ftpusers -> !r:^nuucp; +f:/etc/ftpd/ftpusers -> !r:^smmsp; +f:/etc/ftpd/ftpusers -> !r:^listen; +f:/etc/ftpd/ftpusers -> !r:^gdm; +f:/etc/ftpd/ftpusers -> !r:^lp; +f:/etc/ftpd/ftpusers -> !r:^webservd; +f:/etc/ftpd/ftpusers -> !r:^postgres; +f:/etc/ftpd/ftpusers -> !r:^svctag; +f:/etc/ftpd/ftpusers -> !r:^openldap; +f:/etc/ftpd/ftpusers -> !r:^unknown; +f:/etc/ftpd/ftpusers -> !r:^aiuser; +f:/etc/ftpd/ftpusers -> !r:^nobody; +f:/etc/ftpd/ftpusers -> !r:^nobody4; +f:/etc/ftpd/ftpusers -> !r:^noaccess; +# +# +#6.10 Set Delay between Failed Login Attempts to 4 +[CIS - Solaris 11 Configuration - 6.10 Set Delay between Failed Login Attempts to 4] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^SLEEPTIME\p4; +f:/etc/default/login -> !r:^# && r:SLEEPTIME\p4\d; +# +# +#6.11 Remove Autologin Capabilities from the GNOME desktop +[CIS - Solaris 11 Configuration - 6.11 Remove Autologin Capabilities from the GNOME desktop] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/pam.conf -> !r:^# && r:gdm-autologin; +# +# +#6.12 Set Default Screen Lock for GNOME Users +[CIS - Solaris 11 Configuration - 6.12 Set Default Screen Lock for GNOME Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/usr/share/X11/app-defaults/XScreensaver -> !r:^*timeout:\s*\t*0:10:00; +f:/usr/share/X11/app-defaults/XScreensaver -> !r:^*locktimeout:\s*\t*0:00:00; +f:/usr/share/X11/app-defaults/XScreensaver -> !r:^*lock:\s*\t*true; +# +# +#6.13 Restrict at/cron to Authorized Users +[CIS - Solaris 11 Configuration - 6.13 Restrict at/cron to Authorized Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/cron.d/cron.deny; +f:/etc/cron.d/at.deny; +f:!/etc/cron.d/cron.allow; +f:/etc/cron.d/cron.allow -> !r:^root$; +f:!/etc/cron.d/at.allow; +f:/etc/cron.d/at.allow -> !r:^# && r:\w; +# +# +#6.14 Restrict root Login to System Console +[CIS - Solaris 11 Configuration - 6.14 Restrict root Login to System Console] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^CONSOLE\p/dev/console; +# +# +#6.15 Set Retry Limit for Account Lockout +[CIS - Solaris 11 Configuration - 6.14 Restrict root Login to System Console] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^RETRIES\p3; +f:/etc/default/login -> !r:^# && r:RETRIES\p3\d; +f:/etc/security/policy.conf -> !r:^LOCK_AFTER_RETRIES\pyes; +f:/etc/security/policy.conf -> !r:^# && r:LOCK_AFTER_RETRIES\pno; +# +# +#6.17 Secure the GRUB Menu (Intel) +[CIS - Solaris 11 Configuration - 6.17 Secure the GRUB Menu (Intel)] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/rpool/boot/grub/menu.lst -> !r:^password\s*--md5; +# +# +#7.1 Set Password Expiration Parameters on Active Accounts +[CIS - Solaris 11 Configuration - 7.1 Set Password Expiration Parameters on Active Accounts] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/passwd -> !r:^maxweeks\p13; +f:/etc/default/passwd -> !r:^# &&r:maxweeks\p13\d; +f:/etc/default/passwd -> !r:^minweeks\p1; +f:/etc/default/passwd -> !r:^# &&r:minweeks\p1\d; +f:/etc/default/passwd -> !r:^warnweeks\p4; +f:/etc/default/passwd -> !r:^# &&r:warnweeks\p4\d; +# +# +#7.2 Set Strong Password Creation Policies +[CIS - Solaris 11 Configuration - 7.2 Set Strong Password Creation Policies] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/passwd -> !r:^passlength\p8; +f:/etc/default/passwd -> !r:^# && r:passlength\p8\d; +f:/etc/default/passwd -> !r:^namecheck\pyes; +f:/etc/default/passwd -> !r:^# && r:namecheck\pno; +f:/etc/default/passwd -> !r:^history\p10; +f:/etc/default/passwd -> !r:^# && r:history\p10\d; +f:/etc/default/passwd -> !r:^mindiff\p3; +f:/etc/default/passwd -> !r:^# && r:mindiff\p3\d; +f:/etc/default/passwd -> !r:^minalpha\p2; +f:/etc/default/passwd -> !r:^# && r:minalpha\p2\d; +f:/etc/default/passwd -> !r:^minupper\p1; +f:/etc/default/passwd -> !r:^# && r:minupper\p1\d; +f:/etc/default/passwd -> !r:^minlower\p1; +f:/etc/default/passwd -> !r:^# && r:minlower\p1\d; +f:/etc/default/passwd -> !r:^minnonalpha\p1; +f:/etc/default/passwd -> !r:^# && r:minnonalpha\p1\d; +f:/etc/default/passwd -> !r:^maxrepeats\p0; +f:/etc/default/passwd -> !r:^# && r:maxrepeats\p0\d; +f:/etc/default/passwd -> !r:^whitespace\pyes; +f:/etc/default/passwd -> !r:^# && r:whitespace\pno; +f:/etc/default/passwd -> !r:^dictiondbdir\p/var/passwd; +f:/etc/default/passwd -> !r:^dictionlist\p/usr/share/lib/dict/words; +# +# +#7.3 Set Default umask for users +[CIS - Solaris 11 Configuration - 7.3 Set Default umask for users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/login -> !r:^umask\p027|^umask\p077; +f:/etc/default/login -> !r:^# && r:umask\p026; +f:/etc/default/login -> !r:^# && r:umask\p022; +# +# +#7.4 Set Default File Creation Mask for FTP Users +[CIS - Solaris 11 Configuration - 7.4 Set Default File Creation Mask for FTP Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/proftpd.conf -> !r:^umask\s*027; +f:/etc/proftpd.conf -> !r:^# && r:umask\s*026; +f:/etc/proftpd.conf -> !r:^# && r:umask\s*022; +# +# +#7.5 Set "mesg n" as Default for All Users +[CIS - Solaris 11 Configuration - 7.5 Set "mesg n" as Default for All Users] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/.login -> !r:^mesg\s*n; +f:/etc/profile -> !r:^mesg\s*n; +# +# +#8.1 Create Warnings for Standard Login Services +[CIS - Solaris 11 Configuration - 8.1 Create Warnings for Standard Login Services] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/issue -> r:SunOS; +f:/etc/issue -> r:Oracle; +f:/etc/issue -> r:solaris; +f:/etc/issue -> !r:Authorized users only. All activity may be monitored and reported; +f:/etc/motd -> r:SunOS; +f:/etc/motd -> r:Oracle; +f:/etc/motd -> r:solaris; +f:/etc/motd -> !r:Authorized users only. All activity may be monitored and reported; +# +# +#8.2 Enable a Warning Banner for the SSH Service +[CIS - Solaris 11 Configuration - 8.2 Enable a Warning Banner for the SSH Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/ssh/sshd_config -> !r:^Banner\s*/etc/issue; +# +# +#8.3 Enable a Warning Banner for the GNOME Service +[CIS - Solaris 11 Configuration - 8.3 Enable a Warning Banner for the GNOME Service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/gdm/Init/Default -> !r:^/usr/bin/zenity\s\.; +# +# +#8.4 Enable a Warning Banner for the FTP service +[CIS - Solaris 11 Configuration - 8.4 Enable a Warning Banner for the FTP service] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/proftpd.conf -> !r:^DisplayConnect\s+/etc/issue; +# +# +#8.5 Check that the Banner Setting for telnet is Null +[CIS - Solaris 11 Configuration - 8.5 Check that the Banner Setting for telnet is Null] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/default/telnetd -> !r:^# && r:BANNER=\.; +f:/etc/default/telnetd -> !r:BANNER=$; +# +# +#9.3 Verify System Account Default Passwords +[CIS - Solaris 11 Configuration - 9.3 Verify System Account Default Passwords] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/shadow -> r:daemon && !r::NL:|:NP:; +f:/etc/shadow -> r:lp && !r::NL:|:NP:; +f:/etc/shadow -> r:adm && !r::NL:|:NP:; +f:/etc/shadow -> r:bin && !r::NL:|:NP:; +f:/etc/shadow -> r:gdm && !r::\p*LK\p*:; +f:/etc/shadow -> r:noaccess && !r::\p*LK\p*:; +f:/etc/shadow -> r:nobody && !r::\p*LK\p*:; +f:/etc/shadow -> r:nobody4 && !r::\p*LK\p*:; +f:/etc/shadow -> r:openldap && !r::\p*LK\p*:; +f:/etc/shadow -> r:unknown && !r::\p*LK\p*:; +f:/etc/shadow -> r:webservd && !r::\p*LK\p*:; +f:/etc/shadow -> r:mysql && !r::NL:|:NP:; +f:/etc/shadow -> r:nuuc && !r::NL:|:NP:; +f:/etc/shadow -> r:postgres && !r::NL:|:NP:; +f:/etc/shadow -> r:smmsp && !r::NL:|:NP:; +f:/etc/shadow -> r:sys && !r::NL:|:NP:; +f:/etc/shadow -> r:uucp && !r::NL:|:NP:; +f:/etc/shadow -> r:aiuser && !r::\p*LK\p*:; +f:/etc/shadow -> r:dhcpserv && !r::\p*LK\p*:; +f:/etc/shadow -> r:dladm && !r::\p*LK\p*:; +f:/etc/shadow -> r:ftp && !r::\p*LK\p*:; +f:/etc/shadow -> r:netadm && !r::\p*LK\p*:; +f:/etc/shadow -> r:netcfg && !r::\p*LK\p*:; +f:/etc/shadow -> r:pkg5srv && !r::\p*LK\p*:; +f:/etc/shadow -> r:svctag && !r::\p*LK\p*:; +f:/etc/shadow -> r:xvm && !r::\p*LK\p*:; +f:/etc/shadow -> r:upnp && !r::NL:|:NP:; +f:/etc/shadow -> r:zfssnap && !r::NL:|:NP:; +# +# +#9.4 Ensure Password Fields are Not Empty +[CIS - Solaris 11 Configuration - 9.4 Ensure Password Fields are Not Empty] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/shadow -> r:\.+::\.+\w+\.*$; +# +# +#9.5 Verify No UID 0 Accounts Exist Other than root +[CIS - Solaris 11 Configuration - 9.5 Verify No UID 0 Accounts Exist Other than root] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/passwd -> !r:^root && r::\.:0:\.*; +# +# +#9.6 Ensure root PATH Integrity +[CIS - Solaris 11 Configuration - Ensure root PATH Integrity] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/profile -> r:.; +f:/etc/environment -> r:.; +f:/.profile -> r:.; +f:/.bash_profile -> r:.; +f:/.bashrc -> r:.; +f:/etc/profile -> r:::; +f:/etc/environment -> r:::; +f:/.profile -> r:::; +f:/.bash_profile -> r:::; +f:/.bashrc -> r:::; +f:/etc/profile -> r::$; +f:/etc/environment -> r::$; +f:/.profile -> r::$; +f:/.bash_profile -> r::$; +f:/.bashrc -> r::$; +# +# +#9.10 Check for Presence of User .rhosts Files +[CIS - Solaris 11 Configuration - 9.10 Check for Presence of User .rhosts Files] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:$home_dirs -> ^.rhosts$; +# +# +#9.12 Check That Users Are Assigned Home Directories +[CIS - Solaris 11 Configuration - 9.12 Check That Users Are Assigned Home Directories] [any] [https://workbench.cisecurity.org/benchmarks/410] +f:/etc/passwd -> \w+:\.*:\d*:\d*:\.*:\S+:\.*; +# +# +#9.20 Check for Presence of User .netrc Files +[CIS - Solaris 11 Configuration - 9.20 Check for Presence of User .netrc Files] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:$home_dirs -> ^.netrc$; +# +# +#9.21 Check for Presence of User .forward Files +[CIS - Solaris 11 Configuration - 9.21 Check for Presence of User .forward Files] [any] [https://workbench.cisecurity.org/benchmarks/410] +d:$home_dirs -> ^.forward$; +# +# +# diff --git a/src/rootcheck/db/cis_win10_enterprise_L1_rcl.txt b/src/rootcheck/db/cis_win10_enterprise_L1_rcl.txt new file mode 100644 index 000000000..d8a8456af --- /dev/null +++ b/src/rootcheck/db/cis_win10_enterprise_L1_rcl.txt @@ -0,0 +1,1548 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows 10 +# Based on Center for Internet Security Benchmark v1.4.0 for Microsoft Windows 10 Release 1709 (https://workbench.cisecurity.org/benchmarks/766) +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows 10 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'[CIS - Microsoft Windows 10 - 2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users' +[CIS - Microsoft Windows 10 - 2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators and Interactive Users'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'[CIS - Microsoft Windows 10 - 2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> !0; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> !1; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> !1; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> !0; +# +# +#2.3.7.4 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'[CIS - Microsoft Windows 10 - 2.3.7.4 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.8 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows 10 - 2.3.7.8 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows 10 - 2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows 10 - 2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher +[CIS - Microsoft Windows 10 - 2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> SMBServerNameHardeningLevel -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> !SMBServerNameHardeningLevel; +# +# +#2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymousSAM -> 0; +# +# +#2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> !1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> !RestrictAnonymous; +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows 10 - 2.3.10.6 Ensure 'Network access: Named Pipes that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> r:\S*; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Ensure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows 10 - 2.3.10.7 Ensure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> !Machine; +# +# +#2.3.10.8 Ensure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows 10 - 2.3.10.8 Ensure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> !Machine; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' +[CIS - Microsoft Windows 10 - 2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> restrictremotesam -> !r:O:BAG:BAD:\(A;;RC;;;BA\); +# +# +#2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows 10 - 2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows 10 - 2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows 10 - 2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> !SupportedEncryptionTypes; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows 10 - 2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows 10 - 2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows 10 - 2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows 10 - 2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows 10 - 2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows 10 - 2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#5.3 Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.3 Ensure 'Computer Browser (Browser)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser -> Start -> !4; +# +# +#5.6 Ensure 'HomeGroup Listener (HomeGroupListener)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.6 Ensure 'HomeGroup Listener (HomeGroupListener)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupListener -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupListener -> !Start; +# +# +#5.7 Ensure 'HomeGroup Provider (HomeGroupProvider)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.7 Ensure 'HomeGroup Provider (HomeGroupProvider)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupProvider -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HomeGroupProvider -> !Start; +# +# +#5.8 Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.8 Ensure 'IIS Admin Service (IISADMIN)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IISADMIN -> Start -> !4; +# +# +#5.9 Ensure 'Infrared monitor service (irmon)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.9 Ensure 'Infrared monitor service (irmon)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\irmon -> !Start; +# +# +#5.10 Ensure 'Internet Connection Sharing (ICS) (SharedAccess) ' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.10 Ensure 'Internet Connection Sharing (ICS) (SharedAccess) ' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess -> !Start; +# +# +#5.12 Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.12 Ensure 'LxssManager (LxssManager)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LxssManager -> Start -> !4; +# +# +#5.13 Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.13 Ensure 'Microsoft FTP Service (FTPSVC)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FTPSVC -> Start -> !4; +# +# +#5.24 Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.24 Ensure 'Remote Procedure Call (RPC) Locator (RpcLocator)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcLocator -> !Start; +# +# +#5.26 Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.26 Ensure 'Routing and Remote Access (RemoteAccess)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess -> !Start; +# +# +#5.28 Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.28 Ensure 'Simple TCP/IP Services (simptcp)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\simptcp -> Start -> !4; +# +# +#5.30 Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.30 Ensure 'SSDP Discovery (SSDPSRV)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SSDPSRV -> !Start; +# +# +#5.31 Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.31 Ensure 'UPnP Device Host (upnphost)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\upnphost -> !Start; +# +# +#5.32 Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.32 Ensure 'Web Management Service (WMSvc)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMSvc -> Start -> !4; +# +# +#5.35 Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.35 Ensure 'Windows Media Player Network Sharing Service (WMPNetworkSvc)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WMPNetworkSvc -> Start -> !4; +# +# +#5.36 Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.36 Ensure 'Windows Mobile Hotspot Service (icssvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\icssvc -> !Start; +# +# +#5.41 Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.41 Ensure 'World Wide Web Publishing Service (W3SVC)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC -> Start -> !4; +# +# +#5.42 Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.42 Ensure 'Xbox Accessory Management Service (XboxGipSvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxGipSvc -> !Start; +# +# +#5.43 Ensure 'Xbox Game Monitoring (xbgm)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.43 Ensure 'Xbox Game Monitoring (xbgm)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\xbgm -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\xbgm -> !Start; +# +# +#5.44 Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.44 Ensure 'Xbox Live Auth Manager (XblAuthManager)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblAuthManager -> !Start;# +# +#5.45 Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.45 Ensure 'Xbox Live Game Save (XblGameSave)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XblGameSave -> !Start; +# +# +#4.46 Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 4.46 Ensure 'Xbox Live Networking Service (XboxNetApiSvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvce -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\XboxNetApiSvce -> !Start; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows 10 - 9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows 10 - 9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows 10 - 9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows 10 - 9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows 10 - 9.1.5 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows 10 - 9.1.6 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.1.7 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.1.8 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows 10 - 9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows 10 - 9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows 10 - 9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows 10 - 9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows 10 - 9.2.5 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows 10 - 9.2.6 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.2.7 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.2.8 Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows 10 - 9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows 10 - 9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows 10 - 9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows 10 - 9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows 10 - 9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows 10 - 9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows 10 - 9.3.7 Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows 10 - 9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows 10 - 9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.1.2.2 Ensure 'Allow input personalization' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.1.2.2 Ensure 'Allow input personalization' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> AllowInputPersonalization -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> !AllowInputPersonalization; +# +# +#18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed +[CIS - Microsoft Windows 10 - 18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA} -> !DllName; +# +# +#18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PwdExpirationProtectionEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PwdExpirationProtectionEnabled; +# +# +#18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> AdmPwdEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !AdmPwdEnabled; +# +# +#18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' +[CIS - Microsoft Windows 10 - 18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordComplexity -> !4; +# +# +#18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' +[CIS - Microsoft Windows 10 - 18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PasswordLength; +# +# +#18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' +[CIS - Microsoft Windows 10 - 18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> 1F; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:2\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:3\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:4\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:5\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:6\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:7\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:8\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:9\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\w\w\w+; +# +# +#18.3.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.3.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> LocalAccountTokenFilterPolicy -> !0; +# +# +#18.3.2 Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver' +[CIS - Microsoft Windows 10 - 18.3.2 Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10 -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10 -> !Start; +# +# +#18.3.3 Ensure 'Configure SMB v1 server' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.3.3 Ensure 'Configure SMB v1 server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters -> SMB1 -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters -> !SMB1; +# +# +#18.3.4 Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.3.4 Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel -> DisableExceptionChainValidation -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel -> !DisableExceptionChainValidation; +# +# +#18.3.5 Ensure 'Turn on Windows Defender protection against Potentially Unwanted Applications' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.3.5 Ensure 'Turn on Windows Defender protection against Potentially Unwanted Applications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine -> MpEnablePus -> 0; +# +# +#18.3.6 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.3.6 Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.4.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.4.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.4.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows 10 - Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.4.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows 10 - 18.4.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.4.5 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.4.5 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.4.7 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.4.7 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.4.9 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.4.9 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.4.10 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows 10 - 18.4.10 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.4.13 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows 10 - 18.4.13 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.5.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)') +[CIS - Microsoft Windows 10 - 18.5.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)')] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> NodeType -> !2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> !NodeType; +# +# +#18.5.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> EnableMulticast -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> !EnableMulticast; +# +# +#18.5.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> AllowInsecureGuestAuth -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> !AllowInsecureGuestAuth; +# +# +#18.5.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.5.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_ShowSharedAccessUI -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_ShowSharedAccessUI; +# +# +#18.5.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.5.14.1 Ensure 'Hardened UNC Paths' is set to 'Enabled, with "Require Mutual Authentication" and "Require Integrity" set for all NETLOGON and SYSVOL shares' +[CIS - Microsoft Windows 10 - 18.5.14.1 Ensure 'Hardened UNC Paths' is set to 'Enabled, with "Require Mutual Authentication" and "Require Integrity" set for all NETLOGON and SYSVOL shares'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths -> \\\\*\\NETLOGON -> !r:RequireMutualAuthentication=1, RequireIntegrity=1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkProvider\HardenedPaths -> \\\\*\\SYSVOL -> !r:RequireMutualAuthentication=1, RequireIntegrity=1; +# +# +#18.5.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.5.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fBlockNonDomain -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> !fBlockNonDomain; +# +# +#18.5.23.2.1 Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.23.2.1 Ensure 'Allow Windows to automatically connect to suggested open hotspots, to networks shared by contacts, and to hotspots offering paid services' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config -> AutoConnectAllowedOEM -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config -> !AutoConnectAllowedOEM; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.4.1 Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.4.1 Ensure 'Remote host allows delegation of non-exportable credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation -> AllowProtectedCreds -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation -> !AllowProtectedCreds; +# +# +#18.8.14.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows 10 - 18.8.14.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.21.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows 10 - 18.8.21.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.21.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows 10 - 18.8.21.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.21.4 Ensure 'Continue experiences on this device' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.21.4 Ensure 'Continue experiences on this device' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableCdp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableCdp; +# +# +#18.8.21.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.21.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.22.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.22.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.22.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.27.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockUserFromShowingAccountDetailsOnSignin -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !BlockUserFromShowingAccountDetailsOnSignin; +# +# +#18.8.27.2 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.2 Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.27.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.27.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.27.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.27.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.27.6 Ensure 'Turn off picture password sign-in' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.27.6 Ensure 'Turn off picture password sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockDomainPicturePassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !BlockDomainPicturePassword; +# +# +#18.8.27.7 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.27.7 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.33.6.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> DCSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !DCSettingIndex; +# +# +#18.8.33.6.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> ACSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !ACSettingIndex; +# +# +#18.8.33.6.5 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.5 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.33.6.6 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.33.6.6 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.35.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.35.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.35.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.35.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.8.36.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.36.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> EnableAuthEpResolution -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !EnableAuthEpResolution; +# +# +#18.8.36.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' +[CIS - Microsoft Windows 10 - 18.8.36.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> RestrictRemoteClients -> !1; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows 10 - 18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows 10 - 18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.10.1.1 Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.10.1.1 Ensure 'Configure enhanced anti-spoofing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> EnhancedAntiSpoofing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> !EnhancedAntiSpoofing; +# +# +#18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> DisableWindowsConsumerFeatures -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> !DisableWindowsConsumerFeatures; +# +# +#18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> RequirePinForPairing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> !RequirePinForPairing; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.16.1 Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security (Enterprise Only)' or 'Enabled: 1 - Basic' +[CIS - Microsoft Windows 10 - 18.9.16.1 Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security (Enterprise Only)' or 'Enabled: 1 - Basic'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> AllowTelemetry -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> AllowTelemetry -> 3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !AllowTelemetry; +# +# +#18.9.16.3 Ensure 'Disable pre-release features or settings' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.16.3 Ensure 'Disable pre-release features or settings' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> EnableConfigFlighting -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !EnableConfigFlighting; +# +# +#18.9.16.4 Ensure 'Do not show feedback notifications' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.16.4 Ensure 'Do not show feedback notifications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DoNotShowFeedbackNotifications -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DoNotShowFeedbackNotifications; +# +# +#18.9.16.5 Ensure 'Toggle user control over Insider builds' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.16.5 Ensure 'Toggle user control over Insider builds' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> AllowBuildPreview -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !AllowBuildPreview; +# +# +#18.9.17.1 Ensure 'Download Mode' is NOT set to 'Enabled: Internet' +[CIS - Microsoft Windows 10 - 18.9.17.1 Ensure 'Download Mode' is NOT set to 'Enabled: Internet'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization -> DODownloadMode -> 3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization -> !DODownloadMode; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> 1; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'[CIS - Microsoft Windows 10 - 18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows 10 - 18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.30.2 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.3 Ensure 'Turn off heap termination on corruption' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.30.3 Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.4 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.30.4 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.35.1 Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.35.1 Ensure 'Prevent the computer from joining a homegroup' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HomeGroup -> DisableHomeGroup -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HomeGroup -> !DisableHomeGroup; +# +# +#18.9.44.1 Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.44.1 Ensure 'Block all consumer Microsoft account user authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount -> DisableUserAuth -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftAccount -> !DisableUserAuth; +# +# +#18.9.45.4 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher +[CIS - Microsoft Windows 10 - 18.9.45.4 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> Cookies -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !Cookies; +# +# +#18.9.45.5 Ensure 'Configure Password Manager' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.5 Ensure 'Configure Password Manager' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> FormSuggest Passwords -> !no; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !FormSuggest Passwords; +# +# +#18.9.45.8 Ensure 'Configure the Adobe Flash Click-to-Run setting' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.8 Ensure 'Configure the Adobe Flash Click-to-Run setting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Security -> FlashClickToRunMode -> !1; +# +# +#18.9.52.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.52.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.58.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.58.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdma -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.58.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.58.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.58.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows 10 - 18.9.58.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.58.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.58.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.59.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.59.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.60.3 Ensure 'Allow Cortana' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.3 Ensure 'Allow Cortana' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortana -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortana; +# +# +#18.9.60.4 Ensure 'Allow Cortana above lock screen' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.4 Ensure 'Allow Cortana above lock screen' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortanaAboveLock -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortanaAboveLock; +# +# +#18.9.60.5 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.5 Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.60.6 Ensure 'Allow search and Cortana to use location' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.60.6 Ensure 'Allow search and Cortana to use location' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowSearchToUseLocation -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowSearchToUseLocation; +# +# +#18.9.68.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.68.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.68.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.68.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.76.3.1 Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.3.1 Ensure 'Configure local setting override for reporting to Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> LocalSettingOverrideSpynetReporting -> !0; +# +# +#18.9.76.7.1 Ensure 'Turn on behavior monitoring' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.7.1 Ensure 'Turn on behavior monitoring' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection -> DisableBehaviorMonitoring -> !1; +# +# +#18.9.76.10.1 Ensure 'Scan removable drives' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.10.1 Ensure 'Scan removable drives' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> DisableRemovableDriveScanning -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> !DisableRemovableDriveScanning; +# +# +#18.9.76.10.2 Ensure 'Turn on e-mail scanning' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.10.2 Ensure 'Turn on e-mail scanning' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> DisableEmailScanning -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Scan -> !DisableEmailScanning; +# +# +#18.9.76.13.1.1 Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.76.13.1.1 Ensure 'Configure Attack Surface Reduction rules' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> ExploitGuard_ASR_Rules -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR -> !ExploitGuard_ASR_Rules; +# +# +#18.9.76.13.1.2 Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is 'configured' +[CIS - Microsoft Windows 10 - 18.9.76.13.1.2 Ensure 'Configure Attack Surface Reduction rules: Set the state for each ASR rule' is 'configured'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D4F940AB-401B-4EFC-AADC-AD5F3C50688A -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D4F940AB-401B-4EFC-AADC-AD5F3C50688A; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 3B576869-A4EC-4529-8536-B80A7769E899 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !3B576869-A4EC-4529-8536-B80A7769E899; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> D3E037E1-3EB8-44C8-A917-57927947596D -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !D3E037E1-3EB8-44C8-A917-57927947596D; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !5BEB7EFE-FD9A-4556-801D-275E5FFC04CC; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B -> !1; +r:HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR\Rules -> !92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B; +# +# +#18.9.76.13.3.1 Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block' +[CIS - Microsoft Windows 10 - 18.9.76.13.3.1 Ensure 'Prevent users and apps from accessing dangerous websites' is set to 'Enabled: Block'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection -> EnableNetworkProtection -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\Network Protection -> !EnableNetworkProtection; +# +# +#18.9.76.14 Ensure 'Turn off Windows Defender AntiVirus' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.14 Ensure 'Turn off Windows Defender AntiVirus' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender -> DisableAntiSpyware -> 1; +# +# +#18.9.79.1.1 Ensure 'Prevent users from modifying settings' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.79.1.1 Ensure 'Prevent users from modifying settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection -> DisallowExploitProtectionOverride -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection -> !DisallowExploitProtectionOverride; +# +# +#18.9.80.1.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass' +[CIS - Microsoft Windows 10 - 18.9.80.1.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled: Warn and prevent bypass'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> ShellSmartScreenLevel -> !Block; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !ShellSmartScreenLevel; +# +# +#18.9.80.2.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.80.2.1 Ensure 'Configure Windows Defender SmartScreen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> EnabledV9 -> !1; +# +# +#18.9.80.2.2 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for files' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.80.2.2 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for files' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverrideAppRepUnknown -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverrideAppRepUnknown; +# +# +#18.9.80.2.3 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.80.2.3 Ensure 'Prevent bypassing Windows Defender SmartScreen prompts for sites' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverride -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverride; +# +# +#18.9.82.1 Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.82.1 Ensure 'Enables or disables Windows Game Recording and Broadcasting' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR -> AllowGameDVR -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\GameDVR -> !AllowGameDVR; +# +# +#18.9.84.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On' +[CIS - Microsoft Windows 10 - 18.9.84.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowWindowsInkWorkspace -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowWindowsInkWorkspace; +# +# +#18.9.85.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.85.1 Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.85.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.85.2 Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.86.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.86.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.95.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.95.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.95.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.95.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.97.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.97.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.97.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.97.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.97.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.97.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.97.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.101.1.1 Ensure 'Manage preview builds' is set to 'Enabled: Disable preview builds' +[CIS - Microsoft Windows 10 - 18.9.101.1.1 Ensure 'Manage preview builds' is set to 'Enabled: Disable preview builds'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> ManagePreviewBuilds -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !ManagePreviewBuilds; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> ManagePreviewBuildsPolicyValue -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !ManagePreviewBuildsPolicyValue; +# +# +#18.9.101.1.2 Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: Semi-Annual Channel, 180 or more days' +[CIS - Microsoft Windows 10 - 18.9.101.1.2 Ensure 'Select when Preview Builds and Feature Updates are received' is set to 'Enabled: Semi-Annual Channel, 180 or more days'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferFeatureUpdates; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:10\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:11\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:12\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:13\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:14\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:15\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:16\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> r:17\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferFeatureUpdatesPeriodInDays -> !r:\d\d\d+; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferFeatureUpdatesPeriodInDays; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> BranchReadinessLevel -> !32; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !BranchReadinessLevel; +# +# +#18.9.101.1.13 Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days' +[CIS - Microsoft Windows 10 - 18.9.101.1.13 Ensure 'Select when Quality Updates are received' is set to 'Enabled: 0 days'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferQualityUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferQualityUpdates; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> DeferQualityUpdatesPeriodInDays -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -> !DeferQualityUpdatesPeriodInDays; +# +# +#18.9.101.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.101.2 Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.101.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows 10 - 18.9.101.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.101.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.101.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# +# +# diff --git a/src/rootcheck/db/cis_win10_enterprise_L2_rcl.txt b/src/rootcheck/db/cis_win10_enterprise_L2_rcl.txt new file mode 100644 index 000000000..6f5e031aa --- /dev/null +++ b/src/rootcheck/db/cis_win10_enterprise_L2_rcl.txt @@ -0,0 +1,591 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows 10 +# Based on Center for Internet Security Benchmark v1.4.0 for Microsoft Windows 10 Release 1709 (https://workbench.cisecurity.org/benchmarks/766) +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> !AddPrinterDrivers; +# +# +#2.3.7.7 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' +[CIS - Microsoft Windows 10 - 2.3.7.7 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> !4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !CachedLogonsCount; +# +# +#2.3.14.1 Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used' or higher +[CIS - Microsoft Windows 10 - 2.3.14.1 Ensure 'System cryptography: Force strong key protection for user keys stored on the computer' is set to 'User is prompted when the key is first used' or higher] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography -> ForceKeyProtection -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography -> !ForceKeyProtection; +# +# +#5.1 Ensure 'Bluetooth Handsfree Service (BthHFSrv)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.1 Ensure 'Bluetooth Handsfree Service (BthHFSrv)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BthHFSrv -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BthHFSrv -> !Start; +# +# +#5.2 Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.2 Ensure 'Bluetooth Support Service (bthserv)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bthserv -> !Start; +# +# +#5.4 Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.4 Ensure 'Downloaded Maps Manager (MapsBroker)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MapsBroker -> !Start; +# +# +#5.5 Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.5 Ensure 'Geolocation Service (lfsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lfsvc -> !Start; +# +# +#5.11 Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.11 Ensure 'Link-Layer Topology Discovery Mapper (lltdsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lltdsvc -> !Start; +# +# +#5.14 Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.14 Ensure 'Microsoft iSCSI Initiator Service (MSiSCSI)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSiSCSI -> !Start; +# +# +#5.15 Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.15 Ensure 'Peer Name Resolution Protocol (PNRPsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPsvc -> !Start; +# +# +#5.16 Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.16 Ensure 'Peer Networking Grouping (p2psvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2psvc -> !Start; +# +# +#5.17 Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.17 Ensure 'Peer Networking Identity Manager (p2pimsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\p2pimsvc -> !Start; +# +# +#5.18 Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.18 Ensure 'PNRP Machine Name Publication Service (PNRPAutoReg)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PNRPAutoReg -> !Start; +# +# +#5.19 Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.19 Ensure 'Problem Reports and Solutions Control Panel Support (wercplsupport)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wercplsupport -> !Start; +# +# +#5.20 Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.20 Ensure 'Remote Access Auto Connection Manager (RasAuto)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto -> !Start; +# +# +#5.21 Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.21 Ensure 'Remote Desktop Configuration (SessionEnv)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SessionEnv -> !Start; +# +# +#5.22 Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.22 Ensure 'Remote Desktop Services (TermService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService -> !Start; +# +# +#5.23 Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.23 Ensure 'Remote Desktop Services UserMode Port Redirector (UmRdpService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UmRdpService -> !Start; +# +# +#5.25 Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.25 Ensure 'Remote Registry (RemoteRegistry)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteRegistry -> !Start; +# +# +#5.27 Ensure 'Server (LanmanServer)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.27 Ensure 'Server (LanmanServer)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer -> !Start; +# +# +#5.29 Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed' +[CIS - Microsoft Windows 10 - 5.29 Ensure 'SNMP Service (SNMP)' is set to 'Disabled' or 'Not Installed'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP -> Start -> !4; +# +# +#5.33 Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.33 Ensure 'Windows Error Reporting Service (WerSvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WerSvc -> !Start; +# +# +#5.34 Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.34 Ensure 'Windows Event Collector (Wecsvc)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Wecsvc -> !Start; +# +# +#5.37 Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.37 Ensure 'Windows Push Notifications System Service (WpnService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WpnService -> !Start; +# +# +#5.38 Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.38 Ensure 'Windows PushToInstall Service (PushToInstall)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PushToInstall -> !Start; +# +# +#5.39 Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.39 Ensure 'Windows Remote Management (WS-Management) (WinRM)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinRM -> !Start; +# +# +#5.40 Ensure 'Windows Store Install Service (InstallService)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 5.40 Ensure 'Windows Store Install Service (InstallService)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InstallService -> Start -> !4; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InstallService -> !Start; +# +# +#18.1.3 Ensure 'Allow Online Tips' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.1.3 Ensure 'Allow Online Tips' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> AllowOnlineTips -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !AllowOnlineTips; +# +# +#18.4.4 Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.4.4 Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters -> DisableSavePassword -> !1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters -> !DisableSavePassword; +# +# +#18.4.6 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)' +[CIS - Microsoft Windows 10 - 18.4.6 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.4.8 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.4.8 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.4.11 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows 10 - 18.4.11 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.12 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows 10 - 18.4.12 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.5.5.1 Ensure 'Enable Font Providers' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.5.1 Ensure 'Enable Font Providers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableFontProviders -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableFontProviders; +# +# +#18.5.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.5.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.5.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.5.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows 10 - 18.5.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.5.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.5.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.5.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.5.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.8.22.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.22.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.22.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.22.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.22.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.22.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.22.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.22.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.22.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.22.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.22.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.22.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.22.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.25.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' +[CIS - Microsoft Windows 10 - 18.8.25.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitBehavior -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitEnabled -> !1; +# +# +#18.8.26.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.26.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.44.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.44.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.44.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.44.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.46.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.46.1 Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.49.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.8.49.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.8.49.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.8.49.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer -> Enabled -> !0; +# +# +#18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager -> AllowSharedLocalAppData -> !0; +# +# +#18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> BlockHostedAppAccessWinRT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !BlockHostedAppAccessWinRT; +# +# +#18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> AllowCamera -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> !AllowCamera; +# +# +#18.9.16.2 Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage' +[CIS - Microsoft Windows 10 - 18.9.16.2 Ensure 'Configure Authenticated Proxy usage for the Connected User Experience and Telemetry service' is set to 'Enabled: Disable Authenticated Proxy usage'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DisableEnterpriseAuthProxy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DisableEnterpriseAuthProxy; +# +# +#18.9.39.2 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.39.2 Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.43.1 Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.43.1 Ensure 'Allow Message Service Cloud Sync' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging -> AllowMessageSync -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Messaging -> !AllowMessageSync; +# +# +#18.9.45.1 Ensure 'Allow Address bar drop-down list suggestions' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.1 Ensure 'Allow Address bar drop-down list suggestions' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\ServiceUI -> ShowOneBox -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\ServiceUI -> !ShowOneBox; +# +# +#18.9.45.2 Ensure 'Allow Adobe Flash' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.2 Ensure 'Allow Adobe Flash' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Addons -> FlashPlayerEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Addons -> !FlashPlayerEnabled; +# +# +#18.9.45.3 Ensure 'Allow InPrivate Browsing' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.3 Ensure 'Allow InPrivate Browsing' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowInPrivate -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !AllowInPrivate; +# +# +#18.9.45.6 Ensure 'Configure Pop-up Blocker' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.6 Ensure 'Configure Pop-up Blocker' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowPopups -> !r:yes; +# +# +#18.9.45.7 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.45.7 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> ShowSearchSuggestionsGlobal -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> !ShowSearchSuggestionsGlobal; +# +# +#18.9.45.9 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.9 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> PreventAccessToAboutFlagsInMicrosoftEdge -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !PreventAccessToAboutFlagsInMicrosoftEdge; +# +# +#18.9.45.10 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.45.10 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> HideLocalHostIP -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !HideLocalHostIP; +# +# +#18.9.57.1 Ensure 'Turn off Push To Install service' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.57.1 Ensure 'Turn off Push To Install service' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall -> DisablePushToInstall -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PushToInstall -> !DisablePushToInstall; +# +# +#18.9.58.3.2.1 Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.2.1 Ensure 'Allow users to connect remotely by using Remote Desktop Services' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDenyTSConnections -> !1; +# +# +#18.9.58.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.58.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.58.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.58.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.58.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows 10 - 18.9.58.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.58.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows 10 - 18.9.58.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.60.2 Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search' +[CIS - Microsoft Windows 10 - 18.9.60.2 Ensure 'Allow Cloud Search' is set to 'Enabled: Disable Cloud Search'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCloudSearch -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCloudSearch; +# +# +#18.9.65.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.65.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.68.1 Ensure 'Disable all apps from Windows Store' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.68.1 Ensure 'Disable all apps from Windows Store' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableStoreApps -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableStoreApps; +# +# +#18.9.68.4 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows 10 - 18.9.68.4 Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.76.3.2 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.3.2 Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.76.9.1 Ensure 'Configure Watson events' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.76.9.1 Ensure 'Configure Watson events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> DisableGenericRePorts -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> !DisableGenericRePorts; +# +# +#18.9.84.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.84.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowSuggestedAppsInWindowsInkWorkspace -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowSuggestedAppsInWindowsInkWorkspace; +# +# +#18.9.85.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.85.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.97.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.97.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.98.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows 10 - 18.9.98.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/766] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# +# +# diff --git a/src/rootcheck/db/cis_win2012r2_domainL1_rcl.txt b/src/rootcheck/db/cis_win2012r2_domainL1_rcl.txt new file mode 100644 index 000000000..7f9ae1116 --- /dev/null +++ b/src/rootcheck/db/cis_win2012r2_domainL1_rcl.txt @@ -0,0 +1,1062 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L1 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +# +#1.1.2 Ensure 'Maximum password age' is set to '60 or fewer days, but not 0' +[CIS - Microsoft Windows Server 2012 R2 - Ensure 'Maximum password age' is set to '60 or fewer days, but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3D; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3E; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3F; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:A\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:B\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:C\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:E\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:F\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:\w\w\w+; +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.2: Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.4: Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.1: Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.2: Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.1: Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.2: Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.5.1 Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only) +[CIS - Microsoft Windows Server 2012 R2 - 2.3.5.1: Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' (DC only)] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl -> !0; + +# +# +#2.3.5.2 Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.5.2: Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters -> LDAPServerIntegrity -> !2; +# +# +#2.3.5.3 Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.5.3: Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RefusePasswordChange -> 1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.1: Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.2: Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.3: Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.4: Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> 1; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.6: Ensure 'Domain member: Require strong session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> 0; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.1: Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DontDisplayLastUserName; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.2: Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableCAD; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.3: Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.7: Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.9: Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.1: Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.2: Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.3: Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.1: Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.2: Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.3: Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.4: Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.5: Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.6: Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> !r:lsarpc|netlogon|samr; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.7: Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.8: Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.9: Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.10: Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.11 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.11: Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.1: Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.2: Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.3: Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.4: Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.5: Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.6: Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.7: Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.9: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption''] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.10: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.13.1: Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.1: Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.2: Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.1: Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.2: Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.3: Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.4: Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.5: Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.6: Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.7: Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.8: Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.9: Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.1: Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.2: Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.3: Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.4: Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.5: Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.6: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.7: Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.8: Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.9: Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.1: Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.2: Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.3: Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.4: Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.5: Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.6: Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.8: Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.9: Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.1: Ensure 'Windows Firewall: Public: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.2: Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.3: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.4: Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.5: Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.6: Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.8: Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.9: Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.10: Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.1: Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.2: Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.1: Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.2: Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.3: Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.4: Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.6: Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.8: Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.9: Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.12: Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.2: Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.3: Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.21.1: Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.6.2: Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.3.1: Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.12.1: Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.2: Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.3: Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.4: Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.1: Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.2 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.2: Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.3 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.3: Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.4 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.4: Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.5 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.5: Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.1: Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.2: Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.6.1: Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.1: Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.2: Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.3: Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.1: Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.2: Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> !0; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.47.2 Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.2: Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> DisableFileSync -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> !DisableFileSync; +# +# +#18.9.52.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.2: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.61.1 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.1: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.2 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.2: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.70.2.1 Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.2.1: Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting\Consent -> DefaultConsent -> !1; +# +# +#18.9.70.3 Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.3: Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> AutoApproveOSDumps -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !AutoApproveOSDumps; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# diff --git a/src/rootcheck/db/cis_win2012r2_domainL2_rcl.txt b/src/rootcheck/db/cis_win2012r2_domainL2_rcl.txt new file mode 100644 index 000000000..065d077a2 --- /dev/null +++ b/src/rootcheck/db/cis_win2012r2_domainL2_rcl.txt @@ -0,0 +1,340 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L2 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.4: Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.5: Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.7: Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.10: Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.11: Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.1: Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.2: Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.10.2: Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2012 R2 - 18.4.19.2.1: Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.1: Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.2: Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.1: Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.2: Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.3: Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.4: Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.5: Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.6: Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.7: Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.8: Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.9: Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.10: Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.11: Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.12: Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.13: Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.14: Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.24.1: Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.1: Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.29.5.2 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.2: Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.5.1: Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.11.1: Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.41.1: Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.44.1.1: Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.9.37.1 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.37.1: Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.2.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.3: Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.4: Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.1: Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.2: Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.54.3 Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.3: Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> ConnectedSearchPrivacy -> !3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !ConnectedSearchPrivacy; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.59.1: Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.3 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.3: Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.69.3.1: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.3: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.2: Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.87.1: Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# diff --git a/src/rootcheck/db/cis_win2012r2_memberL1_rcl.txt b/src/rootcheck/db/cis_win2012r2_memberL1_rcl.txt new file mode 100644 index 000000000..54f63b617 --- /dev/null +++ b/src/rootcheck/db/cis_win2012r2_memberL1_rcl.txt @@ -0,0 +1,1129 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L2 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +#1.1.2 Ensure 'Maximum password age' is set to '60 or fewer days, but not 0' +[CIS - Microsoft Windows Server 2012 R2 - Ensure 'Maximum password age' is set to '60 or fewer days, but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3D; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3E; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> 3F; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:A\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:B\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:C\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:E\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:F\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> MaximumPasswordAge -> r:\w\w\w+; +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.2: Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.1.4: Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.1: Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.2.2: Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.1: Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.4.2: Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.1: Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.2: Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.3: Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.4: Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> 1; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.6.6: Ensure 'Domain member: Require strong session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> 0; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.1: Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DontDisplayLastUserName; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.2: Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableCAD; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.3: Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.7: Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.8 Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.8: Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ForceUnlockLogon -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !ForceUnlockLogon; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.7.9: Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.1: Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.2: Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.8.3: Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.1: Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.2: Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.3: Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.4: Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.9.5: Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> SMBServerNameHardeningLevel -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> !SMBServerNameHardeningLevel; +# +# +#2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.2: Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymousSAM -> 0; +# +# +#2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.3: Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.5: Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.6: Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> r:\S*; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.7: Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.8: Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.9: Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.10: Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.11 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.11: Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.1: Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.2: Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.3: Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.4: Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.5: Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.6: Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.7: Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.9: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption''] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.11.10: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.13.1: Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.1: Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.15.2: Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.1: Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.2: Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.3: Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.4: Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.5: Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.6: Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.7: Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.8: Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.17.9: Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.1: Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.2: Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.3: Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.4: Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.5: Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.6: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.7: Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.8: Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.9: Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.1.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.1: Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.2: Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.3: Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.4: Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.5: Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.6: Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.8: Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.9: Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.2.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.1: Ensure 'Windows Firewall: Public: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.2: Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.3: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.4: Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.5: Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.6: Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.8: Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.9: Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2012 R2 - 9.3.10: Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.1: Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.1.1.2: Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed +[CIS - Microsoft Windows Server 2012 R2 - 18.2.1: Ensure LAPS AdmPwd GPO Extension / CSE is installed] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA} -> !DllName; +# +# +#18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.2: Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PwdExpirationProtectionEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PwdExpirationProtectionEnabled; +# +# +#18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.3: Ensure 'Enable Local Admin Password Management' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> AdmPwdEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !AdmPwdEnabled; +# +# +#18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.4: Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordComplexity -> !4; +# +# +#18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.5: Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PasswordLength; +# +# +#18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' +[CIS - Microsoft Windows Server 2012 R2 - 18.2.6: Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> 1F; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:2\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:3\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:4\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:5\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:6\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:7\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:8\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:9\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\w\w\w+; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.1: Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.2: Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.3: Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.4: Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.6: Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.8: Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.9: Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.12: Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.2: Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.11.3: Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.21.1: Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.6.1: Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> LocalAccountTokenFilterPolicy -> !0; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.6.2: Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.3.1: Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.12.1: Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.2: Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.3: Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.19.4: Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.1: Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.2 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.2: Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.3 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.3: Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.4 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.4: Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.5 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.25.5: Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.1: Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.31.2: Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.8.32.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.32.1: Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> EnableAuthEpResolution -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !EnableAuthEpResolution; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.6.1: Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.1: Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.2: Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.8.3: Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.1: Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.15.2: Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> !0; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled: Require approval from an administrator before running downloaded unknown software'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.47.2 Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.47.2: Ensure 'Prevent the usage of OneDrive for file storage on Windows 8.1' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> DisableFileSync -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Skydrive -> !DisableFileSync; +# +# +#18.9.52.2.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.2: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.61.1 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.1: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.2 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.2: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.70.2.1 Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.2.1: Ensure 'Configure Default consent' is set to 'Enabled: Always ask before sending data'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting\Consent -> DefaultConsent -> !1; +# +# +#18.9.70.3 Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.70.3: Ensure 'Automatically send memory dumps for OS-generated error reports' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> AutoApproveOSDumps -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !AutoApproveOSDumps; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# +# +# diff --git a/src/rootcheck/db/cis_win2012r2_memberL2_rcl.txt b/src/rootcheck/db/cis_win2012r2_memberL2_rcl.txt new file mode 100644 index 000000000..994e24cda --- /dev/null +++ b/src/rootcheck/db/cis_win2012r2_memberL2_rcl.txt @@ -0,0 +1,378 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2012 R2 Domain Controller L2 +# Based on Center for Internet Security Benchmark v2.2.1 for Microsoft Windows Server 2012 R2 (https://workbench.cisecurity.org/benchmarks/288) +# +# +#2.3.7.6 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' +[CIS - Microsoft Windows Server 2012 R2 - Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> f; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> \w\w+; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !CachedLogonsCount; +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 2.3.10.4: Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.5: Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.7: Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.10: Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2012 R2 - 18.3.11: Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.1: Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.9.2: Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.10.2: Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2012 R2 - 18.4.19.2.1: Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.1: Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.20.2: Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.4.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.4.21.2: Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fBlockNonDomain -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> !fBlockNonDomain; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.1: Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.2: Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.3: Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.4: Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.5: Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.6: Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.7: Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.8: Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.9: Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.10: Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.11: Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.12: Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.13: Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.20.1.14: Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.24.1: Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.1: Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> !DCSettingIndex; +# +# +#18.8.29.5.2 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.29.5.2: Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> !ACSettingIndex; +# +# +#18.8.32.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.32.2: Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> RestrictRemoteClients -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !RestrictRemoteClients; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.5.1: Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.39.11.1: Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.41.1: Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.44.1.1: Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.8.44.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.8.44.1.2: Ensure 'Enable Windows NTP Server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer -> Enabled -> !0; +# +# +#18.9.37.1 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.37.1: Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.2.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.1: Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.3: Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.3.4: Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.1: Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.52.3.10.2: Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.54.3 Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.54.3: Ensure 'Set what information is shared in Search' is set to 'Enabled: Anonymous info'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> ConnectedSearchPrivacy -> !3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !ConnectedSearchPrivacy; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.59.1: Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.3 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.61.3: Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.69.3.1: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.74.3: Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.86.2.2: Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2012 R2 - 18.9.87.1: Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/288] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# + + diff --git a/src/rootcheck/db/cis_win2016_domainL1_rcl.txt b/src/rootcheck/db/cis_win2016_domainL1_rcl.txt new file mode 100644 index 000000000..bf595046e --- /dev/null +++ b/src/rootcheck/db/cis_win2016_domainL1_rcl.txt @@ -0,0 +1,1144 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Domain Controller L1 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2016 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2016 - 2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> 2; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.5.1 Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.5.1 Ensure 'Domain controller: Allow server operators to schedule tasks' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl -> !0; +# +# +#2.3.5.2 Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing' +[CIS - Microsoft Windows Server 2016 - 2.3.5.2 Ensure 'Domain controller: LDAP server signing requirements' is set to 'Require signing'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters -> LDAPServerIntegrity -> !2; +# +# +#2.3.5.3 Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.5.3 Ensure 'Domain controller: Refuse machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RefusePasswordChange -> 1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> !0; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.6 Ensure 'Domain member: Require strong session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> !1; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> !1; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> !0; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2016 - 2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2016 - 2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2016 - 2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2016 - 2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> !r:lsarpc|netlogon|samr; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.7 Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2016 - 2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2016 - 2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2016 - 2.3.11.4 Ensure 'Network security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2016 - 2.3.11.7: Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.11.8: Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.9: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.10: Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.13.1: Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.1: Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.2: Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.1: Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.2: Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2016 - 2.3.17.3: Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2016 - 2.3.17.4: Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.5: Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.6: Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.7: Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.8: Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.9: Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.1.1: Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block' +[CIS - Microsoft Windows Server 2016 - 9.1.2: Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow' +[CIS - Microsoft Windows Server 2016 - 9.1.3: Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.1.4: Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.5: Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.6: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.1.7: Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.1.8: Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.9: Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.10: Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.2.1: Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block' +[CIS - Microsoft Windows Server 2016 - 9.2.2: Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.3: Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.2.4: Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.5: Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.6: Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\privatefw.log' +[CIS - Microsoft Windows Server 2016 - 9.2.7: Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\privatefw.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.2.8: Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.9: Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.10: Ensure 'Windows Firewall: Private: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)' +[CIS - Microsoft Windows Server 2016 - 9.3.1: Ensure 'Windows Firewall: Public: Firewall state' is set to 'On (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.2: Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.3: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.4: Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.5: Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.6: Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\publicfw.log' +[CIS - Microsoft Windows Server 2016 - 9.3.7: Ensure 'Windows Firewall: Public: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\publicfw.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.3.8: Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16,384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.9: Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.10: Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.1: Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.2: Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.1.2.1 Ensure 'Allow Input Personalization' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.1.2.1: Ensure 'Allow Input Personalization' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> AllowInputPersonalization -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> !AllowInputPersonalization; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.1: Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.2: Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level' is set to 'Enabled: Highest protection'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.3: Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.4: Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.6: Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.8: Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2016 - 18.3.9: Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2016 - 18.3.12: Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.8.1: Ensure 'Enable insecure guest logons' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> AllowInsecureGuestAuth -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> !AllowInsecureGuestAuth; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.2: Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.3: Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_ShowSharedAccessUI -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_ShowSharedAccessUI; +# +# +#18.4.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.4: Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.21.1: Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.6.2: Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.3.1: Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2016 - 18.8.12.1: Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.2: Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.3: Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Continue experiences on this device' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.4: Ensure 'Continue experiences on this device' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableCdp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableCdp; +# +# +#18.8.19.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.5: Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.1: Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockUserFromShowingAccountDetailsOnSignin -> !1; +# +# +#18.8.25.2 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.2: Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.3: Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.4: Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.5: Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.6 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.6: Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.26.1 Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events' +[CIS - Microsoft Windows Server 2016 - 18.8.26.1: Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions -> MitigationOptions_FontBocking -> !1000000000000; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.1: Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.2: Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.1: Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.8.1: Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2016 - 18.9.8.2: Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2016 - 18.9.8.3: Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.10.1.1 Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.10.1.1: Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> EnhancedAntiSpoofing -> !1; +# +# +#18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.13.1: Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> DisableWindowsConsumerFeatures -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> !DisableWindowsConsumerFeatures; +# +# +#18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled' (Scored) +[CIS - Microsoft Windows Server 2016 - 18.9.14.1: Ensure 'Require pin for pairing' is set to 'Enabled' (Scored)] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> RequirePinForPairing -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> !RequirePinForPairing; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.1: Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.2: Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.16.1 Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security [Enterprise Only]' +[CIS - Microsoft Windows Server 2016 - 18.9.16.1: Ensure 'Allow Telemetry' is set to 'Enabled: 0 - Security (Enterprise Only)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> AllowTelemetry -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !AllowTelemetry; +# +# +#18.9.16.2 Ensure 'Disable pre-release features or settings' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.2: Ensure 'Disable pre-release features or settings' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> EnableConfigFlighting -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !EnableConfigFlighting; +# +# +#18.9.16.3 Ensure 'Do not show feedback notifications' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.3: Ensure 'Do not show feedback notifications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DoNotShowFeedbackNotifications -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DoNotShowFeedbackNotifications; +# +# +#18.9.16.4 Ensure 'Toggle user control over Insider builds' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.4: Ensure 'Toggle user control over Insider builds' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> AllowBuildPreview -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !AllowBuildPreview; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> 1; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.41.3 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher +[CIS - Microsoft Windows Server 2016 - 18.9.41.3: Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> Cookies -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !Cookies; +# +# +#18.9.41.4 Ensure 'Configure Password Manager' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.4: Ensure 'Configure Password Manager' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> FormSuggest Passwords -> !no; +# +# +#18.9.41.6 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.6: Ensure 'Configure search suggestions in Address bar' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> ShowSearchSuggestionsGlobal -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> !ShowSearchSuggestionsGlobal; +# +# +#18.9.41.7 Ensure 'Configure SmartScreen Filter' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.7: Ensure 'Configure SmartScreen Filter' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> EnabledV9 -> !1; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.52.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdma -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow Cortana' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.2: Ensure 'Allow Cortana' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortana -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortana; +# +# +#18.9.54.3 Ensure 'Allow Cortana above lock screen' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.3: Ensure 'Allow Cortana above lock screen' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortanaAboveLock -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortanaAboveLock; +# +# +#18.9.54.4 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.4: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.54.5 Ensure 'Allow search and Cortana to use location' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.5: Ensure 'Allow search and Cortana to use location' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowSearchToUseLocation -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowSearchToUseLocation; +# +# +#18.9.61.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.2: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.3: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.73.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On' +[CIS - Microsoft Windows Server 2016 - 18.9.73.2: Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowWindowsInkWorkspace -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowWindowsInkWorkspace; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2016 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# diff --git a/src/rootcheck/db/cis_win2016_domainL2_rcl.txt b/src/rootcheck/db/cis_win2016_domainL2_rcl.txt new file mode 100644 index 000000000..69cfcb32e --- /dev/null +++ b/src/rootcheck/db/cis_win2016_domainL2_rcl.txt @@ -0,0 +1,468 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Domain Controller L2 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)' +[CIS - Microsoft Windows Server 2016 - 18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableFontProviders -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableFontProviders; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2016 - 18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' +[CIS - Microsoft Windows Server 2016 - 18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitBehavior -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitEnabled -> !1; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> DCSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !DCSettingIndex; +# +# +#18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> ACSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !ACSettingIndex; +# +# +#18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager -> AllowSharedLocalAppData -> !0; +# +# +#18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny' +[CIS - Microsoft Windows Server 2016 - 18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessAccountInfo -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessAccountInfo; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCallHistory -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCallHistory; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessContacts -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessContacts; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessEmail -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessEmail; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessLocation -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessLocation; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMessaging -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMessaging; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMotion -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMotion; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCalendar -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCalendar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCamera -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCamera; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMicrophone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMicrophone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessTrustedDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessTrustedDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessRadios -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessRadios; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsSyncWithDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsSyncWithDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessPhone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessPhone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessNotifications -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessNotifications; +# +# +#18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> BlockHostedAppAccessWinRT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !BlockHostedAppAccessWinRT; +# +# +#18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> AllowCamera -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> !AllowCamera; +# +# +#18.9.37.2 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.37.2 Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> ExtensionsEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> !ExtensionsEnabled; +# +# +#18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowInPrivate -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !AllowInPrivate; +# +# +#18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowPopups -> !r:yes; +# +# +#18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> PreventAccessToAboutFlagsInMicrosoftEdge -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !PreventAccessToAboutFlagsInMicrosoftEdge; +# +# +#18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverrideAppRepUnknown -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverrideAppRepUnknown; +# +# +#18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverride -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverride; +# +# +#18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> HideLocalHostIP -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !HideLocalHostIP; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableStoreApps -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableStoreApps; +# +# +#18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.69.8 Ensure 'Configure Watson events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.8 Ensure 'Configure Watson events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> DisableGenericRePorts -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> !DisableGenericRePorts; +# +# +#18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowSuggestedAppsInWindowsInkWorkspace -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowSuggestedAppsInWindowsInkWorkspace; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# diff --git a/src/rootcheck/db/cis_win2016_memberL1_rcl.txt b/src/rootcheck/db/cis_win2016_memberL1_rcl.txt new file mode 100644 index 000000000..ed9b215dd --- /dev/null +++ b/src/rootcheck/db/cis_win2016_memberL1_rcl.txt @@ -0,0 +1,1226 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Member Server L1 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +# +#2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts' +[CIS - Microsoft Windows Server 2016 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> NoConnectedUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !NoConnectedUser; +# +# +#2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.1.4 Ensure 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LimitBlankPasswordUse -> 0; +# +# +#2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings to override audit policy category settings' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.1 Ensure 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> SCENoApplyLegacyAuditPolicy -> !1; +# +# +#2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.2.2 Ensure 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> CrashOnAuditFail -> 2; +# +# +#2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators' +[CIS - Microsoft Windows Server 2016 - 2.3.4.1 Ensure 'Devices: Allowed to format and eject removable media' is set to 'Administrators'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AllocateDASD -> !0; +# +# +#2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.4.2 Ensure 'Devices: Prevent users from installing printer drivers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers -> AddPrinterDrivers -> !1; +# +# +#2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.1 Ensure 'Domain member: Digitally encrypt or sign secure channel data (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireSignOrSeal -> 0; +# +# +#2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.2 Ensure 'Domain member: Digitally encrypt secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SealSecureChannel -> 0; +# +# +#2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.3 Ensure 'Domain member: Digitally sign secure channel data (when possible)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> SignSecureChannel -> 0; +# +# +#2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.4 Ensure 'Domain member: Disable machine account password changes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> DisablePasswordChange -> 1; +# +# +#2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.6.6 Ensure 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters -> RequireStrongKey -> 0; +# +# +#2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.1 Ensure 'Interactive logon: Do not display last user name' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DontDisplayLastUserName -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DontDisplayLastUserName; +# +# +#2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.2 Ensure 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableCAD -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableCAD; +# +# +#2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0' +[CIS - Microsoft Windows Server 2016 - 2.3.7.3 Ensure 'Interactive logon: Machine inactivity limit' is set to '900 or fewer second(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 385; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 386; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 387; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 388; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> 389; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:38\D; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:39\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:3\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:4\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:5\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:6\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:7\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:8\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:9\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\D\w\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> InactivityTimeoutSecs -> r:\w\w\w\w+; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !InactivityTimeoutSecs; +# +# +#2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days' +[CIS - Microsoft Windows Server 2016 - 2.3.7.7 Ensure 'Interactive logon: Prompt user to change password before expiration' is set to 'between 5 and 14 days'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 2; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 3; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 4; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> 0F; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:1\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:2\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:3\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:4\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:5\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:6\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:7\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:8\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:9\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\D\w; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> PasswordExpiryWarning -> r:\w\w\w+; +# +# +#2.3.7.8 Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.7.8 Ensure 'Interactive logon: Require Domain Controller Authentication to unlock workstation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ForceUnlockLogon -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !ForceUnlockLogon; +# +# +#2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.7.9 Ensure 'Interactive logon: Smart card removal behavior' is set to 'Lock Workstation' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> ScRemoveOption -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon -> !ScRemoveOption; +# +# +#2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.1 Ensure 'Microsoft network client: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> !RequireSecuritySignature; +# +# +#2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.8.2 Ensure 'Microsoft network client: Digitally sign communications (if server agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnableSecuritySignature -> !1; +# +# +#2.3.8.3 Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - Ensure 'Microsoft network client: Send unencrypted password to third-party SMB servers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters -> EnablePlainTextPassword -> !0; +# +# +#2.3.9.1 Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0' +[CIS - Microsoft Windows Server 2016 - Ensure 'Microsoft network server: Amount of idle time required before suspending session' is set to '15 or fewer minute(s), but not 0'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:1\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:2\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:3\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:4\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:5\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:6\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:7\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:8\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:9\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\D\w; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> AutoDisconnect -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !AutoDisconnect; +# +# +#2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.2 Ensure 'Microsoft network server: Digitally sign communications (always)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RequireSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !RequireSecuritySignature; +# +# +#2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.3 Ensure 'Microsoft network server: Digitally sign communications (if client agrees)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableSecuritySignature -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !EnableSecuritySignature; +# +# +#2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.9.4 Ensure 'Microsoft network server: Disconnect clients when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.9.5 Ensure 'Microsoft network server: Server SPN target name validation level' is set to 'Accept if provided by client' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> SMBServerNameHardeningLevel -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> !SMBServerNameHardeningLevel; +# +# +#2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.2 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymousSAM -> 0; +# +# +#2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.3 Ensure 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> !1; +# +# +#2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.5 Ensure 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> EveryoneIncludesAnonymous -> 2; +# +# +#2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously' +[CIS - Microsoft Windows Server 2016 - 2.3.10.6 Configure 'Network access: Named Pipes that can be accessed anonymously'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionPipes -> r:\S*; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> !NullSessionPipes; +# +# +#2.3.10.7 Configure 'Network access: Remotely accessible registry paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.7 Configure 'Network access: Remotely accessible registry paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths -> Machine -> !r:System\\CurrentControlSet\\Control\\ProductOptions|System\\CurrentControlSet\\Control\\Server Applications|Software\\Microsoft\\Windows NT\\CurrentVersion; +# +# +#2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths' +[CIS - Microsoft Windows Server 2016 - 2.3.10.8 Configure 'Network access: Remotely accessible registry paths and sub-paths'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths -> Machine -> !r:Software\\Microsoft\\Windows NT\\CurrentVersion\\Print|Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows|System\\CurrentControlSet\\Control\\Print\\Printers|System\\CurrentControlSet\\Services\\Eventlog|Software\\Microsoft\\OLAP Server|System\\CurrentControlSet\\Control\\ContentIndex|System\\CurrentControlSet\\Control\\Terminal Server|System\\CurrentControlSet\\Control\\Terminal Server\\UserConfig|System\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration|Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib|System\\CurrentControlSet\\Services\\SysmonLog|System\\CurrentControlSet\\Services\\CertSvc|System\\CurrentControlSet\\Services\\WINS; +# +# +#2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.9 Ensure 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> RestrictNullSessAccess -> !1; +# +# +#2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow' +[CIS - Microsoft Windows Server 2016 - 2.3.10.10 Ensure 'Network access: Restrict clients allowed to make remote calls to SAM' is set to 'Administrators: Remote Access: Allow'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -> restrictremotesam -> !r:O:BAG:BAD:\(A;;RC;;;BA\); +# +# +#2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None' +[CIS - Microsoft Windows Server 2016 - 2.3.10.11 Ensure 'Network access: Shares that can be accessed anonymously' is set to 'None'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters -> NullSessionShares -> r:\S*; +# +# +#2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves' +[CIS - Microsoft Windows Server 2016 - 2.3.10.12 Ensure 'Network access: Sharing and security model for local accounts' is set to 'Classic - local users authenticate as themselves'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> ForceGuest -> 1; +# +# +#2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.1 Ensure 'Network security: Allow Local System to use computer identity for NTLM' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> UseMachineId -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !UseMachineId; +# +# +#2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.2 Ensure 'Network security: Allow LocalSystem NULL session fallback' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> allownullsessionfallback -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !allownullsessionfallback; +# +# +#2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.3 Ensure 'Network Security: Allow PKU2U authentication requests to this computer to use online identities' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u -> AllowOnlineID -> !0; +# +# +#2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types' +[CIS - Microsoft Windows Server 2016 - 2.3.11.4 Ensure 'Network Security: Configure encryption types allowed for Kerberos' is set to 'RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1, Future encryption types'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -> SupportedEncryptionTypes -> !2147483644; +# +# +#2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.5 Ensure 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> NoLMHash -> 0; +# +# +#2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.11.6 Ensure 'Network security: Force logoff when logon hours expire' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters -> EnableForcedLogOff -> !1; +# +# +#2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM' +[CIS - Microsoft Windows Server 2016 - 2.3.11.7 Ensure 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 3; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> LmCompatibilityLevel -> 4; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !LmCompatibilityLevel; +# +# +#2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher +[CIS - Microsoft Windows Server 2016 - 2.3.11.8 Ensure 'Network security: LDAP client signing requirements' is set to 'Negotiate signing' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP -> LDAPClientIntegrity -> !1; +# +# +#2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.9 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinClientSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinClientSec; +# +# +#2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption' +[CIS - Microsoft Windows Server 2016 - 2.3.11.10 Ensure 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers' is set to 'Require NTLMv2 session security, Require 128-bit encryption'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> NTLMMinServerSec -> !537395200; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0 -> !NTLMMinServerSec; +# +# +#2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.13.1 Ensure 'Shutdown: Allow system to be shut down without having to log on' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ShutdownWithoutLogon -> 1; +# +# +#2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.1 Ensure 'System objects: Require case insensitivity for non-Windows subsystems' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel -> ObCaseInsensitive -> !1; +# +# +#2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.15.2 Ensure 'System objects: Strengthen default permissions of internal system objects (e.g. Symbolic Links)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager -> ProtectionMode -> !1; +# +# +#2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.1 Ensure 'User Account Control: Admin Approval Mode for the Built-in Administrator account' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> FilterAdministratorToken -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !FilterAdministratorToken; +# +# +#2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.2 Ensure 'User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableUIADesktopToggle -> 1; +# +# +#2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop' +[CIS - Microsoft Windows Server 2016 - 2.3.17.3 Ensure 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Prompt for consent on the secure desktop'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 0; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorAdmin -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorAdmin; +# +# +#2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests' +[CIS - Microsoft Windows Server 2016 - 2.3.17.4 Ensure 'User Account Control: Behavior of the elevation prompt for standard users' is set to 'Automatically deny elevation requests'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> ConsentPromptBehaviorUser -> 1; +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !ConsentPromptBehaviorUser; +# +# +#2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.5 Ensure 'User Account Control: Detect application installations and prompt for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableInstallerDetection -> 0; +r:HKEY_LOCAL_MACHINE\MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> !EnableInstallerDetection; +# +# +#2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.6 Ensure 'User Account Control: Only elevate UIAccess applications that are installed in secure locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableSecureUIAPaths -> 0; +# +# +#2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.7 Ensure 'User Account Control: Run all administrators in Admin Approval Mode' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableLUA -> 0; +# +# +#2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.8 Ensure 'User Account Control: Switch to the secure desktop when prompting for elevation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> PromptOnSecureDesktop -> 0; +# +# +#2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.17.9 Ensure 'User Account Control: Virtualize file and registry write failures to per-user locations' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -> EnableVirtualization -> 0; +# +# +#9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.1.1 Ensure 'Windows Firewall: Domain: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> EnableFirewall -> 0; +# +# +#9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.2 Ensure 'Windows Firewall: Domain: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultInboundAction -> 0; +# +# +#9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.3 Ensure 'Windows Firewall: Domain: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DefaultOutboundAction -> 1; +# +# +#9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.1.4 Ensure 'Windows Firewall: Domain: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> !DisableNotifications; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> !DisableNotifications; +# +# +#9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.5 Ensure 'Windows Firewall: Domain: Settings: Apply local firewall rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.1.6 Ensure 'Windows Firewall: Domain: Settings: Apply local connection security rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.1.7 Ensure 'Windows Firewall: Domain: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.1.8 Ensure 'Windows Firewall: Domain: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.9 Ensure 'Windows Firewall: Domain: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.1.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.2.1 Ensure 'Windows Firewall: Private: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> EnableFirewall -> 0; +# +# +#9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.2 Ensure 'Windows Firewall: Private: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultInboundAction -> 0; +# +# +#9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.3 Ensure 'Windows Firewall: Private: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DefaultOutboundAction -> 1; +# +# +#9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.2.4 Ensure 'Windows Firewall: Private: Settings: Display a notification' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> DisableNotifications -> 0; +# +# +#9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.5 Ensure 'Windows Firewall: Private: Settings: Apply local firewall rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)' +[CIS - Microsoft Windows Server 2016 - 9.2.6 Ensure 'Windows Firewall: Private: Settings: Apply local connection security rules' is set to 'Yes (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.2.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.2.8 Ensure 'Windows Firewall: Private: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.9 Ensure 'Windows Firewall: Private: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.2.10 Ensure 'Windows Firewall: Domain: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On' +[CIS - Microsoft Windows Server 2016 - 9.3.1 Ensure 'Windows Firewall: Public: Firewall state' is set to 'On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> EnableFirewall -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> EnableFirewall -> 0; +# +# +#9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.2 Ensure 'Windows Firewall: Public: Inbound connections' is set to 'Block (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultInboundAction -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultInboundAction -> 0; +# +# +#9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)' +[CIS - Microsoft Windows Server 2016 - 9.3.3 Ensure 'Windows Firewall: Public: Outbound connections' is set to 'Allow (default)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DefaultOutboundAction -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DefaultOutboundAction -> 1; +# +# +#9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.4 Ensure 'Windows Firewall: Public: Settings: Display a notification' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> DisableNotifications -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> DisableNotifications -> 0; +# +# +#9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.5 Ensure 'Windows Firewall: Public: Settings: Apply local firewall rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalPolicyMerge -> 0; +# +# +#9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No' +[CIS - Microsoft Windows Server 2016 - 9.3.6 Ensure 'Windows Firewall: Public: Settings: Apply local connection security rules' is set to 'No'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile -> AllowLocalIPsecPolicyMerge -> 0; +# +# +#9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log' +[CIS - Microsoft Windows Server 2016 - 9.3.7 Ensure 'Windows Firewall: Private: Logging: Name' is set to '%SYSTEMROOT%\System32\logfiles\firewall\*.log'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFilePath -> r:\psystemroot\p\\system32\logfiles\firewall\\w+\plog; +# +# +#9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater' +[CIS - Microsoft Windows Server 2016 - 9.3.8 Ensure 'Windows Firewall: Public: Logging: Size limit (KB)' is set to '16384 KB or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogFileSize -> r:3\w\w\w; +# +# +#9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.9 Ensure 'Windows Firewall: Public: Logging: Log dropped packets' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogDroppedPackets -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogDroppedPackets -> 0; +# +# +#9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes' +[CIS - Microsoft Windows Server 2016 - 9.3.10 Ensure 'Windows Firewall: Public: Logging: Log successful connections' is set to 'Yes'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\Logging -> LogSuccessfulConnections -> 0; +# +# +#18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.1 Ensure 'Prevent enabling lock screen camera' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenCamera -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenCamera; +# +# +#18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.1.1.2 Ensure 'Prevent enabling lock screen slide show' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> NoLockScreenSlideshow -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization -> !NoLockScreenSlideshow; +# +# +#18.1.2.1 Ensure 'Allow Input Personalization' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.1.2.1 Ensure 'Allow Input Personalization' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> AllowInputPersonalization -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\InputPersonalization -> !AllowInputPersonalization; +# +# +#18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed +[CIS - Microsoft Windows Server 2016 - 18.2.1 Ensure LAPS AdmPwd GPO Extension / CSE is installed] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA} -> !DllName; +# +# +#18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.2.2 Ensure 'Do not allow password expiration time longer than required by policy' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PwdExpirationProtectionEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PwdExpirationProtectionEnabled; +# +# +#18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.2.3 Ensure 'Enable Local Admin Password Management' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> AdmPwdEnabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !AdmPwdEnabled; +# +# +#18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters' +[CIS - Microsoft Windows Server 2016 - 18.2.4 Ensure 'Password Settings: Password Complexity' is set to 'Enabled: Large letters + small letters + numbers + special characters'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordComplexity -> !4; +# +# +#18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more' +[CIS - Microsoft Windows Server 2016 - 18.2.5 Ensure 'Password Settings: Password Length' is set to 'Enabled: 15 or more'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:\d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:a; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:b; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:c; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:d; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordLength -> r:e; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> !PasswordLength; +# +# +#18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer' +[CIS - Microsoft Windows Server 2016 - 18.2.6 Ensure 'Password Settings: Password Age (Days)' is set to 'Enabled: 30 or fewer'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> 1F; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:2\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:3\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:4\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:5\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:6\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:7\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:8\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:9\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft Services\AdmPwd -> PasswordAgeDays -> r:\w\w\w+; +# +# +#18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.1 Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> AutoAdminLogon -> !0; +# +# +#18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.2 Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.3 Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> DisableIPSourceRouting -> !2; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !DisableIPSourceRouting; +# +# +#18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.4 Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> EnableICMPRedirect -> 1; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !EnableICMPRedirect; +# +# +#18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.6 Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters -> NoNameReleaseOnDemand -> !1; +# +# +#18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.3.8 Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager -> SafeDllSearchMode -> 0; +# +# +#18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds' +[CIS - Microsoft Windows Server 2016 - 18.3.9 Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> 9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> ScreenSaverGracePeriod -> r:\w\w+; +# +# +#18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less' +[CIS - Microsoft Windows Server 2016 - 18.3.12 Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5B; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5C; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5D; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5E; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> 5F; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:6\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:7\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:8\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:9\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\D\w; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> WarningLevel -> r:\w\w\w+; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security -> !WarningLevel; +# +# +#18.4.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)') +[CIS - Microsoft Windows Server 2016 - 18.4.4.1 Set 'NetBIOS node type' to 'P-node' (Ensure NetBT Parameter 'NodeType' is set to '0x2 (2)')] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> NodeType -> !2; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NetBT\Parameters -> !NodeType; +# +# +#18.4.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.4.2 Ensure 'Turn off multicast name resolution' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> EnableMulticast -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient -> !EnableMulticast; +# +# +#18.4.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.8.1 Ensure 'Enable insecure guest logons' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> AllowInsecureGuestAuth -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation -> !AllowInsecureGuestAuth; +# +# +#18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.2 Ensure 'Prohibit installation and configuration of Network Bridge on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_AllowNetBridge_NLA -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_AllowNetBridge_NLA; +# +# +#18.4.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.3 Ensure 'Prohibit use of Internet Connection Sharing on your DNS domain network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_ShowSharedAccessUI -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_ShowSharedAccessUI; +# +# +#18.4.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.11.4 Ensure 'Require domain users to elevate when setting a network's location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> NC_StdDomainUserSetLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Network Connections -> !NC_StdDomainUserSetLocation; +# +# +#18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.21.1 Ensure 'Minimize the number of simultaneous connections to the Internet or a Windows Domain' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fMinimizeConnections -> !1; +# +# +#18.6.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.6.1 Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> LocalAccountTokenFilterPolicy -> !0; +# +# +#18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.6.2 Ensure 'WDigest Authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest -> UseLogonCredential -> !0; +# +# +#18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.3.1 Ensure 'Include command line in process creation events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit -> ProcessCreationIncludeCmdLine_Enabled -> !0; +# +# +#18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical' +[CIS - Microsoft Windows Server 2016 - 18.8.12.1 Ensure 'Boot-Start Driver Initialization Policy' is set to 'Enabled: Good, unknown and bad but critical'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Policies\EarlyLaunch -> DriverLoadPolicy -> !3; +# +# +#18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.2 Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoBackgroundPolicy -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoBackgroundPolicy; +# +# +#18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE' +[CIS - Microsoft Windows Server 2016 - 18.8.19.3 Ensure 'Configure registry policy processing: Process even if the Group Policy objects have not changed' is set to 'Enabled: TRUE'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> NoGPOListChanges -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2} -> !NoGPOListChanges; +# +# +#18.8.19.4 Ensure 'Continue experiences on this device' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.4 Ensure 'Continue experiences on this device' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableCdp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableCdp; +# +# +#18.8.19.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.19.5 Ensure 'Turn off background refresh of Group Policy' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableBkGndGroupPolicy -> !0; +# +# +#18.8.25.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.1 Ensure 'Block user from showing account details on sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> BlockUserFromShowingAccountDetailsOnSignin -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !BlockUserFromShowingAccountDetailsOnSignin; +# +# +#18.8.25.2 Ensure 'Do not display network selection UI' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.2 Ensure 'Do not display network selection UI' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontDisplayNetworkSelectionUI -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontDisplayNetworkSelectionUI; +# +# +#18.8.25.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.3 Ensure 'Do not enumerate connected users on domain-joined computers' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DontEnumerateConnectedUsers -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DontEnumerateConnectedUsers; +# +# +#18.8.25.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.4 Ensure 'Enumerate local users on domain-joined computers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnumerateLocalUsers -> !0; +# +# +#18.8.25.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.5 Ensure 'Turn off app notifications on the lock screen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> DisableLockScreenAppNotifications -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !DisableLockScreenAppNotifications; +# +# +#18.8.25.6 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.25.6 Ensure 'Turn on convenience PIN sign-in' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> AllowDomainPINLogon -> !0; +# +# +#18.8.26.1 Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events' +[CIS - Microsoft Windows Server 2016 - 18.8.26.1 Ensure 'Untrusted Font Blocking' is set to 'Enabled: Block untrusted fonts and log events'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions -> MitigationOptions_FontBocking -> !1000000000000; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\MitigationOptions -> !MitigationOptions_FontBocking; +# +# +#18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.1 Ensure 'Configure Offer Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowUnsolicited -> !0; +# +# +#18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.31.2 Ensure 'Configure Solicited Remote Assistance' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fAllowToGetHelp -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fAllowToGetHelp; +# +# +#18.8.32.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.32.1 Ensure 'Enable RPC Endpoint Mapper Client Authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> EnableAuthEpResolution -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !EnableAuthEpResolution; +# +# +#18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.1 Ensure 'Allow Microsoft accounts to be optional' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> MSAOptional -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !MSAOptional; +# +# +#18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.8.1 Ensure 'Disallow Autoplay for non-volume devices' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoAutoplayfornonVolume -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoAutoplayfornonVolume; +# +# +#18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands' +[CIS - Microsoft Windows Server 2016 - 18.9.8.2 Ensure 'Set the default behavior for AutoRun' is set to 'Enabled: Do not execute any autorun commands'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoAutorun -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoAutorun; +# +# +#18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives' +[CIS - Microsoft Windows Server 2016 - 18.9.8.3 Ensure 'Turn off Autoplay' is set to 'Enabled: All drives'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> NoDriveTypeAutoRun -> !ff; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer-> !NoDriveTypeAutoRun; +# +# +#18.9.10.1.1 Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.10.1.1 Ensure 'Use enhanced anti-spoofing when available' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> EnhancedAntiSpoofing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Biometrics\FacialFeatures -> !EnhancedAntiSpoofing; +# +# +#18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.13.1 Ensure 'Turn off Microsoft consumer experiences' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> DisableWindowsConsumerFeatures -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CloudContent -> !DisableWindowsConsumerFeatures; +# +# +#18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.14.1 Ensure 'Require pin for pairing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> RequirePinForPairing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Connect -> !RequirePinForPairing; +# +# +#18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.1 Ensure 'Do not display the password reveal button' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> DisablePasswordReveal -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredUI -> !DisablePasswordReveal; +# +# +#18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.15.2 Ensure 'Enumerate administrator accounts on elevation' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\CredUI -> EnumerateAdministrators -> !0; +# +# +#18.9.16.2 Ensure 'Disable pre-release features or settings' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.2 Ensure 'Disable pre-release features or settings' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> EnableConfigFlighting -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !EnableConfigFlighting; +# +# +#18.9.16.3 Ensure 'Do not show feedback notifications' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.3: Ensure 'Do not show feedback notifications' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> DoNotShowFeedbackNotifications -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection -> !DoNotShowFeedbackNotifications; +# +# +#18.9.16.4 Ensure 'Toggle user control over Insider builds' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.16.4: Ensure 'Toggle user control over Insider builds' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> AllowBuildPreview -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds -> !AllowBuildPreview; +# +# +#18.9.26.1.1 Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.1: Ensure 'Application: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> Retention -> 1; +# +# +#18.9.26.1.2 Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.1.2: Ensure 'Application: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Application -> !MaxSize; +# +# +#18.9.26.2.1 Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.1: Ensure 'Security: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> Retention -> !0; +# +# +#18.9.26.2.2 Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.2.2: Ensure 'Security: Specify the maximum log file size (KB)' is set to 'Enabled: 196,608 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:0\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:1\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> MaxSize -> r:2\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Security -> !MaxSize; +# +# +#18.9.26.3.1 Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.1: Ensure 'Setup: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> Retention -> !0; +# +# +#18.9.26.3.2 Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.3.2: Ensure 'Setup: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\Setup -> !MaxSize; +# +# +#18.9.26.4.1 Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.1: Ensure 'System: Control Event Log behavior when the log file reaches its maximum size' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> Retention -> !0; +# +# +#18.9.26.4.2 Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater' +[CIS - Microsoft Windows Server 2016 - 18.9.26.4.2: Ensure 'System: Specify the maximum log file size (KB)' is set to 'Enabled: 32,768 or greater'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:0\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:1\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:2\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:3\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:4\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:5\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:6\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> MaxSize -> r:7\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\System -> !MaxSize; +# +# +#18.9.30.2 Ensure 'Configure Windows SmartScreen' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.2: Ensure 'Configure Windows SmartScreen' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableSmartScreen -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableSmartScreen; +# +# +#18.9.30.3 Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.3: Ensure 'Turn off Data Execution Prevention for Explorer' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoDataExecutionPrevention -> !0; +# +# +#18.9.30.4 Ensure 'Turn off heap termination on corruption' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.4: Ensure 'Turn off heap termination on corruption' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoHeapTerminationOnCorruption -> !0; +# +# +#18.9.30.5 Ensure 'Turn off shell protocol protected mode' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.30.5: Ensure 'Turn off shell protocol protected mode' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> PreXPSP2ShellProtocolBehavior -> !0; +# +# +#18.9.41.3 Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher +[CIS - Microsoft Windows Server 2016 - 18.9.41.3: Ensure 'Configure cookies' is set to 'Enabled: Block only 3rd-party cookies' or higher] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> Cookies -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !Cookies; +# +# +#18.9.41.4 Ensure 'Configure Password Manager' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.4: Ensure 'Configure Password Manager' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> FormSuggest Passwords -> !no; +# +# +#18.9.41.6 Ensure 'Configure search suggestions in Address bar' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.6: Ensure 'Configure search suggestions in Address bar' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> ShowSearchSuggestionsGlobal -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes -> !ShowSearchSuggestionsGlobal; +# +# +#18.9.41.7 Ensure 'Configure SmartScreen Filter' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.7: Ensure 'Configure SmartScreen Filter' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> EnabledV9 -> !1; +# +# +#18.9.47.1 Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.47.1: Ensure 'Prevent the usage of OneDrive for file storage' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> DisableFileSyncNGSC -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\OneDrive -> !DisableFileSyncNGSC; +# +# +#18.9.52.2 Ensure 'Do not allow passwords to be saved' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.2.2: Ensure 'Do not allow passwords to be saved' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DisablePasswordSaving -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !DisablePasswordSaving; +# +# +#18.9.52.3.3.2 Ensure 'Do not allow drive redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.2: Ensure 'Do not allow drive redirection' is set to 'Enabled] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCdma -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCdm; +# +# +#18.9.52.3.9.1 Ensure 'Always prompt for password upon connection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.1: Ensure 'Always prompt for password upon connection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fPromptForPassword -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fPromptForPassword; +# +# +#18.9.52.3.9.2 Ensure 'Require secure RPC communication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.2: Ensure 'Require secure RPC communication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fEncryptRPCTraffic -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fEncryptRPCTraffic; +# +# +#18.9.52.3.9.3 Ensure 'Set client connection encryption level' is set to 'Enabled: High Level' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.9.3: Ensure 'Set client connection encryption level' is set to 'Enabled: High Level'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MinEncryptionLevel -> !3; +# +# +#18.9.52.3.11.1 Ensure 'Do not delete temp folders upon exit' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.1: Ensure 'Do not delete temp folders upon exit' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> DeleteTempDirsOnExit -> !1; +# +# +#18.9.52.3.11.2 Ensure 'Do not use temporary folders per session' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.11.2: Ensure 'Do not use temporary folders per session' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> PerSessionTempDir -> !1; +# +# +#18.9.53.1 Ensure 'Prevent downloading of enclosures' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.53.1: Ensure 'Prevent downloading of enclosures' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> DisableEnclosureDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds -> !DisableEnclosureDownload; +# +# +#18.9.54.2 Ensure 'Allow Cortana' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.2: Ensure 'Allow Cortana' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortana -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortana; +# +# +#18.9.54.3 Ensure 'Allow Cortana above lock screen' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.3: Ensure 'Allow Cortana above lock screen' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowCortanaAboveLock -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowCortanaAboveLock; +# +# +#18.9.54.4 Ensure 'Allow indexing of encrypted files' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.4: Ensure 'Allow indexing of encrypted files' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowIndexingEncryptedStoresOrItems -> !0; +# +# +#18.9.54.5 Ensure 'Allow search and Cortana to use location' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.54.5: Ensure 'Allow search and Cortana to use location' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> AllowSearchToUseLocation -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Search -> !AllowSearchToUseLocation; +# +# +#18.9.61.2 Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.2: Ensure 'Turn off Automatic Download and Install of updates' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> AutoDownload -> !4; +# +# +#18.9.61.3 Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.3: Ensure 'Turn off the offer to update to the latest version of Windows' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableOSUpgrade -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableOSUpgrade; +# +# +#18.9.73.2 Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On' +[CIS - Microsoft Windows Server 2016 - 18.9.73.2: Ensure 'Allow Windows Ink Workspace' is set to 'Enabled: On, but disallow access above lock' OR 'Disabled' but not 'Enabled: On'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowWindowsInkWorkspace -> 2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowWindowsInkWorkspace; +# +# +#18.9.74.1 Ensure 'Allow user control over installs' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.1: Ensure 'Allow user control over installs' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> EnableUserControl -> !0; +# +# +#18.9.74.2 Ensure 'Always install with elevated privileges' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.2: Ensure 'Always install with elevated privileges' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> AlwaysInstallElevated -> !0; +# +# +#18.9.75.1 Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.75.1: Ensure 'Sign-in last interactive user automatically after a system-initiated restart' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> DisableAutomaticRestartSignOn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !DisableAutomaticRestartSignOn; +# +# +#18.9.84.1 Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.1: Ensure 'Turn on PowerShell Script Block Logging' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> EnableScriptBlockLogging -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging -> !EnableScriptBlockLogging; +# +# +#18.9.84.2 Ensure 'Turn on PowerShell Transcription' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.84.2: Ensure 'Turn on PowerShell Transcription' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -> EnableTranscripting -> !0; +# +# +#18.9.86.1.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowBasic -> !0; +# +# +#18.9.86.1.2 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.2: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.1.3 Ensure 'Disallow Digest authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.1.3: Ensure 'Disallow Digest authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> AllowDigest -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client -> !AllowDigest; +# +# +#18.9.86.2.1 Ensure 'Allow Basic authentication' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.1: Ensure 'Allow Basic authentication' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowBasic -> !0; +# +# +#18.9.86.2.3 Ensure 'Allow unencrypted traffic' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.3: Ensure 'Allow unencrypted traffic' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowUnencryptedTraffic -> !0; +# +# +#18.9.86.2.4 Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.4: Ensure 'Disallow WinRM from storing RunAs credentials' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> DisableRunAs -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> !DisableRunAs; +# +# +#18.9.90.2 Ensure 'Configure Automatic Updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.2: Ensure 'Configure Automatic Updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoUpdate -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !NoAutoUpdate; +# +# +#18.9.90.3 Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day' +[CIS - Microsoft Windows Server 2016 - 18.9.90.3: Ensure 'Configure Automatic Updates: Scheduled install day' is set to '0 - Every day'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> ScheduledInstallDay -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> !ScheduledInstallDay; +# +# +#18.9.90.4 Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.90.4: Ensure 'No auto-restart with logged on users for scheduled automatic updates installations' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -> NoAutoRebootWithLoggedOnUsers -> !0; +# diff --git a/src/rootcheck/db/cis_win2016_memberL2_rcl.txt b/src/rootcheck/db/cis_win2016_memberL2_rcl.txt new file mode 100644 index 000000000..122baf224 --- /dev/null +++ b/src/rootcheck/db/cis_win2016_memberL2_rcl.txt @@ -0,0 +1,492 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# CIS Checks for Windows Server 2016 Member Server L2 +# Based on Center for Internet Security Benchmark v1.0.0 for Microsoft Windows Server 2016 (https://workbench.cisecurity.org/benchmarks/515) +# +# +# +#2.3.7.6 Ensure 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' is set to '4 or fewer logon(s)' +[CIS - Microsoft Windows Server 2016 - 2.3.1.2 Ensure 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> CachedLogonsCount -> !4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon -> !CachedLogonsCount; +# +# +#2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 2.3.10.4 Ensure 'Network access: Do not allow storage of passwords and credentials for network authentication' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> DisableDomainCreds -> !1; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa -> !DisableDomainCreds; +# +# +#18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)' +[CIS - Microsoft Windows Server 2016 - 18.3.5 Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes (recommended)'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> KeepAliveTime -> !493e0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !KeepAliveTime; +# +# +#18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.3.7 Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> PerformRouterDiscovery -> !0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !PerformRouterDiscovery; +# +# +#18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.10 Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3' +[CIS - Microsoft Windows Server 2016 - 18.3.11 Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> TcpMaxDataRetransmissions -> !3; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -> !TcpMaxDataRetransmissions; +# +# +#18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.5.1 Ensure 'Enable Font Providers' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> EnableFontProviders -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System -> !EnableFontProviders; +# +# +#18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.1 Ensure 'Turn on Mapper I/O (LLTDIO) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowLLTDIOOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableLLTDIO -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitLLTDIOOnPrivateNet -> !0; +# +# +#18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.9.2 Ensure 'Turn on Responder (RSPNDR) driver' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnDomain -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> AllowRspndrOnPublicNet -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> EnableRspndr -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LLTD -> ProhibitRspndrOnPrivateNet -> !0; +# +# +#18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.10.2 Ensure 'Turn off Microsoft Peer-to-Peer Networking Services' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> Disabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Peernet -> !Disabled; +# +# +#18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)') +[CIS - Microsoft Windows Server 2016 - 18.4.19.2.1 Disable IPv6 (Ensure TCPIP6 Parameter 'DisabledComponents' is set to '0xff (255)')] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> DisabledComponents -> !ff; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters -> !DisabledComponents; +# +# +#18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.1 Ensure 'Configuration of wireless settings using Windows Connect Now' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> EnableRegistrars -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !EnableRegistrars; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableUPnPRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableUPnPRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableInBand802DOT11Registrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableInBand802DOT11Registrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableFlashConfigRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableFlashConfigRegistrar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> DisableWPDRegistrar -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars -> !DisableWPDRegistrar; +# +# +#18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.20.2 Ensure 'Prohibit access of the Windows Connect Now wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> DisableWcnUi -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WCN\UI -> !DisableWcnUi; +# +# +#18.4.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.4.21.2 Ensure 'Prohibit connection to non-domain networks when connected to domain authenticated network' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> fBlockNonDomain -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WcmSvc\GroupPolicy -> !fBlockNonDomain; +# +# +#18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.1 Ensure 'Turn off access to the Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> NoUseStoreOpenWith -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer -> !NoUseStoreOpenWith; +# +# +#18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.2 Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableWebPnPDownload -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableWebPnPDownload; +# +# +#18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.3 Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> PreventHandwritingDataSharing -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\TabletPC -> !PreventHandwritingDataSharing; +# +# +#18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.4 Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> PreventHandwritingErrorReports -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HandwritingErrorReports -> !PreventHandwritingErrorReports; +# +# +#18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.5 Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> ExitOnMSICW -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Internet Connection Wizard -> !ExitOnMSICW; +# +# +#18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.6 Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoWebServices -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoWebServices; +# +# +#18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.7 Ensure 'Turn off printing over HTTP' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> DisableHTTPPrinting -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers -> !DisableHTTPPrinting; +# +# +#18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.8 Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> NoRegistration -> !1; +r:HKEY_LOCAL_MACHINE\Policies\Microsoft\Windows\Registration Wizard Control -> !NoRegistration; +# +# +#18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.9 Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> DisableContentFileUpdates -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SearchCompanion -> !DisableContentFileUpdates; +# +# +#18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.10 Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoOnlinePrintsWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoOnlinePrintsWizard; +# +# +#18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.11 Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> NoPublishingWizard -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -> !NoPublishingWizard; +# +# +#18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.12 Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> CEIP -> 1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Messenger\Client -> !CEIP; +# +# +#18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.13 Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> CEIPEnable -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows -> !CEIPEnable; +# +# +#18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.20.1.14 Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> Disabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting -> !Disabled; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> DoReport -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PCHealth\ErrorReporting -> !DoReport; +# +# +#18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic' +[CIS - Microsoft Windows Server 2016 - 18.8.23.1 Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitBehavior -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters -> DevicePKInitEnabled -> !1; +# +# +#18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.24.1 Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> BlockUserInputMethodsForSignIn -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Control Panel\International -> !BlockUserInputMethodsForSignIn; +# +# +#18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.1 Ensure 'Allow network connectivity during connected-standby (on battery)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> DCSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !DCSettingIndex; +# +# +#18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.2 Ensure 'Allow network connectivity during connected-standby (plugged in)' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> ACSettingIndex -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\f15576e8-98b7-4186-b944-eafa664402d9 -> !ACSettingIndex; +# +# +#18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.3 Ensure 'Require a password when a computer wakes (on battery)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> DCSettingIndex -> !1; +# +# +#18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.29.5.4 Ensure 'Require a password when a computer wakes (plugged in)' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51 -> ACSettingIndex -> !1; +# +# +#18.8.32.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated' +[CIS - Microsoft Windows Server 2016 - 18.8.32.2 Ensure 'Restrict Unauthenticated RPC clients' is set to 'Enabled: Authenticated'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> RestrictRemoteClients -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc -> !RestrictRemoteClients; +# +# +#18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.5.1 Ensure 'Microsoft Support Diagnostic Tool: Turn on MSDT interactive communication with support provider' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> DisableQueryRemoteServer -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScriptedDiagnosticsProvider\Policy -> !DisableQueryRemoteServer; +# +# +#18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.39.11.1 Ensure 'Enable/Disable PerfTrack' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> ScenarioExecutionEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WDI\{9c5a40da-b965-4fc3-8781-88dd50a6299d} -> !ScenarioExecutionEnabled; +# +# +#18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.41.1 Ensure 'Turn off the advertising ID' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> DisabledByGroupPolicy -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo -> !DisabledByGroupPolicy; +# +# +#18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.8.44.1.1 Ensure 'Enable Windows NTP Client' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> Enabled -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpClient -> !Enabled; +# +# +#18.8.44.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.8.44.1.2 Ensure 'Enable Windows NTP Server' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W32Time\TimeProviders\NtpServer -> Enabled -> !0; +# +# +#18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.4.1 Ensure 'Allow a Windows app to share application data between users' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\AppModel\StateManager -> AllowSharedLocalAppData -> !0; +# +# +#18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny' +[CIS - Microsoft Windows Server 2016 - 18.9.5.1 Ensure 'Let Windows apps *' is set to 'Enabled: Force Deny'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessAccountInfo -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessAccountInfo; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCallHistory -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCallHistory; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessContacts -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessContacts; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessEmail -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessEmail; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessLocation -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessLocation; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMessaging -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMessaging; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMotion -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMotion; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCalendar -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCalendar; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessCamera -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessCamera; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessMicrophone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessMicrophone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessTrustedDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessTrustedDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessRadios -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessRadios; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsSyncWithDevices -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsSyncWithDevices; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessPhone -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessPhone; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> LetAppsAccessNotifications -> !2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy -> !LetAppsAccessNotifications; +# +# +#18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.6.2 Ensure 'Block launching Windows Store apps with Windows Runtime API access from hosted content.' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> BlockHostedAppAccessWinRT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -> !BlockHostedAppAccessWinRT; +# +# +#18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.12.1 Ensure 'Allow Use of Camera' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> AllowCamera -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Camera -> !AllowCamera; +# +# +#18.9.37.2 Ensure 'Turn off location' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.37.2 Ensure 'Turn off location' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> DisableLocation -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors -> !DisableLocation; +# +# +#18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.1 Ensure 'Allow Extensions' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> ExtensionsEnabled -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Extensions -> !ExtensionsEnabled; +# +# +#18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.2 Ensure 'Allow InPrivate Browsing' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowInPrivate -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !AllowInPrivate; +# +# +#18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.5 Ensure 'Configure Pop-up Blocker' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> AllowPopups -> !r:yes; +# +# +#18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.8 Ensure 'Prevent access to the about:flags page in Microsoft Edge' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> PreventAccessToAboutFlagsInMicrosoftEdge -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !PreventAccessToAboutFlagsInMicrosoftEdge; +# +# +#18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.9 Ensure 'Prevent bypassing SmartScreen prompts for files' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverrideAppRepUnknown -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverrideAppRepUnknown; +# +# +#18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.10 Ensure 'Prevent bypassing SmartScreen prompts for sites' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> PreventOverride -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter -> !PreventOverride; +# +# +#18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.41.11 Ensure 'Prevent using Localhost IP address for WebRTC' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> HideLocalHostIP -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main -> !HideLocalHostIP; +# +# +#18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.2.1 Ensure 'Restrict Remote Desktop Services users to a single Remote Desktop Services session' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fSingleSessionPerUser -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fSingleSessionPerUser; +# +# +#18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.1 Ensure 'Do not allow COM port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableCcm -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableCcm; +# +# +#18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.3 Ensure 'Do not allow LPT port redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisableLPT -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisableLPT; +# +# +#18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.3.4 Ensure 'Do not allow supported Plug and Play device redirection' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> fDisablePNPRedir -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !fDisablePNPRedir; +# +# +#18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.1 Ensure 'Set time limit for active but idle Remote Desktop Services sessions' is set to 'Enabled: 15 minutes or less'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba2; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba3; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba4; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba5; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba6; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba7; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba8; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba9; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbba\D; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbb\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbc\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbd\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbe\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbbf\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbc\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbd\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbe\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dbf\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dc\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:dd\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:de\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:df\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:e\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:f\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxIdleTime -> r:\w\w\w\w\w\w; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxIdleTime; +# +# +#18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute' +[CIS - Microsoft Windows Server 2016 - 18.9.52.3.10.2 Ensure 'Set time limit for disconnected sessions' is set to 'Enabled: 1 minute'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> MaxDisconnectionTime -> !EA60; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services -> !MaxDisconnectionTime; +# +# +#18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.59.1 Ensure 'Turn off KMS Client Online AVS Validation' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> NoGenTicket -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform -> !NoGenTicket; +# +# +#18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.1 Ensure 'Disable all apps from Windows Store' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> DisableStoreApps -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !DisableStoreApps; +# +# +#18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled' +[CIS - Microsoft Windows Server 2016 - 18.9.61.4 Ensure 'Turn off the Store application' is set to 'Enabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> RemoveWindowsStore -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore -> !RemoveWindowsStore; +# +# +#18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.3.1 Ensure 'Join Microsoft MAPS' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet -> SpynetReporting -> !0; +# +# +#18.9.69.8.1 Ensure 'Configure Watson events' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.69.8 Ensure 'Configure Watson events' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> DisableGenericRePorts -> !1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting -> !DisableGenericRePorts; +# +# +#18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.73.1 Ensure 'Allow suggested apps in Windows Ink Workspace' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> AllowSuggestedAppsInWindowsInkWorkspace -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsInkWorkspace -> !AllowSuggestedAppsInWindowsInkWorkspace; +# +# +#18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.74.3 Ensure 'Prevent Internet Explorer security prompt for Windows Installer scripts' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer -> SafeForScripting -> !0; +# +# +#18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.86.2.2 Ensure 'Allow remote server management through WinRM' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service -> AllowAutoConfig -> !0; +# +# +#18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled' +[CIS - Microsoft Windows Server 2016 - 18.9.87.1 Ensure 'Allow Remote Shell Access' is set to 'Disabled'] [any] [https://workbench.cisecurity.org/benchmarks/515] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> AllowRemoteShellAccess -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\WinRS -> !AllowRemoteShellAccess; +# diff --git a/src/rootcheck/db/rootkit_files.txt b/src/rootcheck/db/rootkit_files.txt new file mode 100644 index 000000000..c7dc6d580 --- /dev/null +++ b/src/rootcheck/db/rootkit_files.txt @@ -0,0 +1,419 @@ +# rootkit_files.txt, (C) 2018 openarmor Project +# Imported from the rootcheck project. +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# Blank lines and lines starting with '#' are ignored. +# +# Each line must be in the following format: +# file_name ! Name ::Link to it +# +# Files that start with an '*' will be searched in the whole system. + +# Bash door +tmp/mcliZokhb ! Bash door ::/rootkits/bashdoor.php +tmp/mclzaKmfa ! Bash door ::/rootkits/bashdoor.php + +# adore Worm +dev/.shit/red.tgz ! Adore Worm ::/rootkits/adorew.php +usr/lib/libt ! Adore Worm ::/rootkits/adorew.php +usr/bin/adore ! Adore Worm ::/rootkits/adorew.php +*/klogd.o ! Adore Worm ::/rootkits/adorew.php +*/red.tar ! Adore Worm ::/rootkits/adorew.php + +# T.R.K rootkit +usr/bin/soucemask ! TRK rootkit ::/rootkits/trk.php +usr/bin/sourcemask ! TRK rootkit ::/rootkits/trk.php + +# 55.808.A Worm +tmp/.../a ! 55808.A Worm :: +tmp/.../r ! 55808.A Worm :: + +# Volc Rootkit +usr/lib/volc ! Volc Rootkit :: +usr/bin/volc ! Volc Rootkit :: + +# Illogic +lib/security/.config ! Illogic Rootkit ::rootkits/illogic.php +usr/bin/sia ! Illogic Rootkit ::rootkits/illogic.php +etc/ld.so.hash ! Illogic Rootkit ::rootkits/illogic.php +*/uconf.inv ! Illogic Rootkit ::rootkits/illogic.php + +# T0rnkit +usr/src/.puta ! t0rn Rootkit ::rootkits/torn.php +usr/info/.t0rn ! t0rn Rootkit ::rootkits/torn.php +lib/ldlib.tk ! t0rn Rootkit ::rootkits/torn.php +etc/ttyhash ! t0rn Rootkit ::rootkits/torn.php +sbin/xlogin ! t0rn Rootkit ::rootkits/torn.php +*/ldlib.tk ! t0rn Rootkit ::rootkits/torn.php +*/.t0rn ! t0rn Rootkit ::rootkits/torn.php +*/.puta ! t0rn Rootkit ::rootkits/torn.php + +# RK17 +bin/rtty ! RK17 :: +bin/squit ! RK17 :: +sbin/pback ! RK17 :: +proc/kset ! RK17 :: +usr/src/linux/modules/autod.o ! RK17 :: +usr/src/linux/modules/soundx.o ! RK17 :: + +# Ramen Worm +usr/lib/ldlibps.so ! Ramen Worm ::rootkits/ramen.php +usr/lib/ldlibns.so ! Ramen Worm ::rootkits/ramen.php +usr/lib/ldliblogin.so ! Ramen Worm ::rootkits/ramen.php +usr/src/.poop ! Ramen Worm ::rootkits/ramen.php +tmp/ramen.tgz ! Ramen Worm ::rootkits/ramen.php +etc/xinetd.d/asp ! Ramen Worm ::rootkits/ramen.php + +# Sadmind/IIS Worm +dev/cuc ! Sadmind/IIS Worm :: + +# Monkit +lib/defs ! Monkit :: +usr/lib/libpikapp.a ! Monkit found :: + +# RSHA +usr/bin/kr4p ! RSHA :: +usr/bin/n3tstat ! RSHA :: +usr/bin/chsh2 ! RSHA :: +usr/bin/slice2 ! RSHA :: +etc/rc.d/rsha ! RSHA :: + +# ShitC worm +bin/home ! ShitC :: +sbin/home ! ShitC :: +usr/sbin/in.slogind ! ShitC :: + +# Omega Worm +dev/chr ! Omega Worm :: + +# rh-sharpe +bin/.ps ! Rh-Sharpe :: +usr/bin/cleaner ! Rh-Sharpe :: +usr/bin/slice ! Rh-Sharpe :: +usr/bin/vadim ! Rh-Sharpe :: +usr/bin/.ps ! Rh-Sharpe :: +bin/.lpstree ! Rh-Sharpe :: +usr/bin/.lpstree ! Rh-Sharpe :: +usr/bin/lnetstat ! Rh-Sharpe :: +bin/lnetstat ! Rh-Sharpe :: +usr/bin/ldu ! Rh-Sharpe :: +bin/ldu ! Rh-Sharpe :: +usr/bin/lkillall ! Rh-Sharpe :: +bin/lkillall ! Rh-Sharpe :: +usr/include/rpcsvc/du ! Rh-Sharpe :: + +# Maniac RK +usr/bin/mailrc ! Maniac RK :: + +# Showtee / Romanian +usr/lib/.egcs ! Showtee :: +usr/lib/.wormie ! Showtee :: +usr/lib/.kinetic ! Showtee :: +usr/lib/liblog.o ! Showtee :: +usr/include/addr.h ! Showtee / Romanian rootkit :: +usr/include/cron.h ! Showtee :: +usr/include/file.h ! Showtee / Romanian rootkit :: +usr/include/syslogs.h ! Showtee / Romanian rootkit :: +usr/include/proc.h ! Showtee / Romanian rootkit :: +usr/include/chk.h ! Showtee :: +usr/sbin/initdl ! Romanian rootkit :: +usr/sbin/xntps ! Romanian rootkit :: + +# Optickit +usr/bin/xchk ! Optickit :: +usr/bin/xsf ! Optickit :: + +# LDP worm +dev/.kork ! LDP Worm :: +bin/.login ! LDP Worm :: +bin/.ps ! LDP Worm :: + +# Telekit +dev/hda06 ! TeLeKit trojan :: +usr/info/libc1.so ! TeleKit trojan :: + +# Tribe bot +dev/wd4 ! Tribe bot :: + +# LRK +dev/ida/.inet ! LRK rootkit ::rootkits/lrk.php +*/bindshell ! LRK rootkit ::rootkits/lrk.php + +# Adore Rootkit +etc/bin/ava ! Adore Rootkit :: +etc/sbin/ava ! Adore Rootkit :: + +# Slapper +tmp/.bugtraq ! Slapper installed :: +tmp/.bugtraq.c ! Slapper installed :: +tmp/.cinik ! Slapper installed :: +tmp/.b ! Slapper installed :: +tmp/httpd ! Slapper installed :: +tmp./update ! Slapper installed :: +tmp/.unlock ! Slapper installed :: +tmp/.font-unix/.cinik ! Slapper installed :: +tmp/.cinik ! Slapper installed :: + +# Scalper +tmp/.uua ! Scalper installed :: +tmp/.a ! Scalper installed :: + +# Knark +proc/knark ! Knark Installed ::rootkits/knark.php +dev/.pizda ! Knark Installed ::rootkits/knark.php +dev/.pula ! Knark Installed ::rootkits/knark.php +dev/.pula ! Knark Installed ::rootkits/knark.php +*/taskhack ! Knark Installed ::rootkits/knark.php +*/rootme ! Knark Installed ::rootkits/knark.php +*/nethide ! Knark Installed ::rootkits/knark.php +*/hidef ! Knark Installed ::rootkits/knark.php +*/ered ! Knark Installed ::rootkits/knark.php + +# Lion worm +dev/.lib ! Lion Worm ::rootkits/lion.php +dev/.lib/1iOn.sh ! Lion Worm ::rootkits/lion.php +bin/mjy ! Lion Worm ::rootkits/lion.php +bin/in.telnetd ! Lion Worm ::rootkits/lion.php +usr/info/torn ! Lion Worm ::rootkits/lion.php +*/1iOn\.sh ! Lion Worm ::rootkits/lion.php + +# Bobkit +usr/include/.../ ! Bobkit Rootkit ::rootkits/bobkit.php +usr/lib/.../ ! Bobkit Rootkit ::rootkits/bobkit.php +usr/sbin/.../ ! Bobkit Rootkit ::rootkits/bobkit.php +usr/bin/ntpsx ! Bobkit Rootkit ::rootkits/bobkit.php +tmp/.bkp ! Bobkit Rootkit ::rootkits/bobkit.php +usr/lib/.bkit- ! Bobkit Rootkit ::rootkits/bobkit.php +*/bkit- ! Bobkit Rootkit ::rootkits/bobkit.php + +# Hidrootkit +var/lib/games/.k ! Hidr00tkit :: + +# Ark +dev/ptyxx ! Ark rootkit :: + +# Mithra Rootkit +usr/lib/locale/uboot ! Mithra`s rootkit :: + +# Optickit +usr/bin/xsf ! OpticKit :: +usr/bin/xchk ! OpticKit :: + +# LOC rookit +tmp/xp ! LOC rookit :: +tmp/kidd0.c ! LOC rookit :: +tmp/kidd0 ! LOC rookit :: + +# TC2 worm +usr/info/.tc2k ! TC2 Worm :: +usr/bin/util ! TC2 Worm :: +usr/sbin/initcheck ! TC2 Worm :: +usr/sbin/ldb ! TC2 Worm :: + +# Anonoiyng rootkit +usr/sbin/mech ! Anonoiyng rootkit :: +usr/sbin/kswapd ! Anonoiyng rootkit :: + +# SuckIt +lib/.x ! SuckIt rootkit :: +*/hide.log ! Suckit rootkit :: +lib/sk ! SuckIT rootkit :: + +# Beastkit +usr/local/bin/bin ! Beastkit rootkit ::rootkits/beastkit.php +usr/man/.man10 ! Beastkit rootkit ::rootkits/beastkit.php +usr/sbin/arobia ! Beastkit rootkit ::rootkits/beastkit.php +usr/lib/elm/arobia ! Beastkit rootkit ::rootkits/beastkit.php +usr/local/bin/.../bktd ! Beastkit rootkit ::rootkits/beastkit.php + +# Tuxkit +dev/tux ! Tuxkit rootkit ::rootkits/Tuxkit.php +usr/bin/xsf ! Tuxkit rootkit ::rootkits/Tuxkit.php +usr/bin/xchk ! Tuxkit rootkit ::rootkits/Tuxkit.php +*/.file ! Tuxkit rootkit ::rootkits/Tuxkit.php +*/.addr ! Tuxkit rootkit ::rootkits/Tuxkit.php + +# Old rootkits +usr/include/rpc/ ../kit ! Old rootkits ::rootkits/Old.php +usr/include/rpc/ ../kit2 ! Old rootkits ::rootkits/Old.php +usr/doc/.sl ! Old rootkits ::rootkits/Old.php +usr/doc/.sp ! Old rootkits ::rootkits/Old.php +usr/doc/.statnet ! Old rootkits ::rootkits/Old.php +usr/doc/.logdsys ! Old rootkits ::rootkits/Old.php +usr/doc/.dpct ! Old rootkits ::rootkits/Old.php +usr/doc/.gifnocfi ! Old rootkits ::rootkits/Old.php +usr/doc/.dnif ! Old rootkits ::rootkits/Old.php +usr/doc/.nigol ! Old rootkits ::rootkits/Old.php + +# Kenga3 rootkit +usr/include/. . ! Kenga3 rootkit + +# ESRK rootkit +usr/lib/tcl5.3 ! ESRK rootkit + +# Fu rootkit +sbin/xc ! Fu rootkit +usr/include/ivtype.h ! Fu rootkit +bin/.lib ! Fu rootkit + +# ShKit rootkit +lib/security/.config ! ShKit rootkit +etc/ld.so.hash ! ShKit rootkit + +# AjaKit rootkit +lib/.ligh.gh ! AjaKit rootkit +lib/.libgh.gh ! AjaKit rootkit +lib/.libgh-gh ! AjaKit rootkit +dev/tux ! AjaKit rootkit +dev/tux/.proc ! AjaKit rootkit +dev/tux/.file ! AjaKit rootkit + +# zaRwT rootkit +bin/imin ! zaRwT rootkit +bin/imout ! zaRwT rootkit + +# Madalin rootkit +usr/include/icekey.h ! Madalin rootkit +usr/include/iceconf.h ! Madalin rootkit +usr/include/iceseed.h ! Madalin rootkit + +# shv5 rootkit XXX http://www.askaboutskating.com/forum/.../shv5/setup +lib/libsh.so ! shv5 rootkit +usr/lib/libsh ! shv5 rootkit + +# BMBL rootkit (http://www.giac.com/practical/GSEC/Steve_Terrell_GSEC.pdf) +etc/.bmbl ! BMBL rootkit +etc/.bmbl/sk ! BMBL rootkit + +# rootedoor rootkit +*/rootedoor ! Rootedoor rootkit + +# 0vason rootkit +*/ovas0n ! ovas0n rootkit ::/rootkits/ovason.php +*/ovason ! ovas0n rootkit ::/rootkits/ovason.php + +# Rpimp reverse telnet +*/rpimp ! rpv21 (Reverse Pimpage)::/rootkits/rpimp.php + +# Cback Linux worm +tmp/cback ! cback worm ::/rootkits/cback.php +tmp/derfiq ! cback worm ::/rootkits/cback.php + +# aPa Kit (from rkhunter) +usr/share/.aPa ! Apa Kit + +# enye-sec Rootkit +etc/.enyelkmHIDE^IT.ko ! enye-sec Rootkit ::/rootkits/enye-sec.php + +# Override Rootkit +dev/grid-hide-pid- ! Override rootkit ::/rootkits/override.php +dev/grid-unhide-pid- ! Override rootkit ::/rootkits/override.php +dev/grid-show-pids ! Override rootkit ::/rootkits/override.php +dev/grid-hide-port- ! Override rootkit ::/rootkits/override.php +dev/grid-unhide-port- ! Override rootkit ::/rootkits/override.php + +# PHALANX rootkit +usr/share/.home* ! PHALANX rootkit :: +usr/share/.home*/tty ! PHALANX rootkit :: +etc/host.ph1 ! PHALANX rootkit :: +bin/host.ph1 ! PHALANX rootkit :: + +# ZK rootkit (http://honeyblog.org/junkyard/reports/redhat-compromise2.pdf) +# and from chkrootkit +usr/share/.zk ! ZK rootkit :: +usr/share/.zk/zk ! ZK rootkit :: +etc/1ssue.net ! ZK rootkit :: +usr/X11R6/.zk ! ZK rootkit :: +usr/X11R6/.zk/xfs ! ZK rootkit :: +usr/X11R6/.zk/echo ! ZK rootkit :: +etc/sysconfig/console/load.zk ! ZK rootkit :: + +# Public sniffers +*/.linux-sniff ! Sniffer log :: +*/sniff-l0g ! Sniffer log :: +*/core_$ ! Sniffer log :: +*/tcp.log ! Sniffer log :: +*/chipsul ! Sniffer log :: +*/beshina ! Sniffer log :: +*/.owned$ | Sniffer log :: + +# Solaris worm - +# http://blogs.sun.com/security/entry/solaris_in_telnetd_worm_seen +var/adm/.profile ! Solaris Worm :: +var/spool/lp/.profile ! Solaris Worm :: +var/adm/sa/.adm ! Solaris Worm :: +var/spool/lp/admins/.lp ! Solaris Worm :: + +# Suspicious files +etc/rc.d/init.d/rc.modules ! Suspicious file ::rootkits/Suspicious.php +lib/ldd.so ! Suspicious file ::rootkits/Suspicious.php +usr/man/muie ! Suspicious file ::rootkits/Suspicious.php +usr/X11R6/include/pain ! Suspicious file ::rootkits/Suspicious.php +usr/bin/sourcemask ! Suspicious file ::rootkits/Suspicious.php +usr/bin/ras2xm ! Suspicious file ::rootkits/Suspicious.php +usr/bin/ddc ! Suspicious file ::rootkits/Suspicious.php +usr/bin/jdc ! Suspicious file ::rootkits/Suspicious.php +usr/sbin/in.telnet ! Suspicious file ::rootkits/Suspicious.php +sbin/vobiscum ! Suspicious file ::rootkits/Suspicious.php +usr/sbin/jcd ! Suspicious file ::rootkits/Suspicious.php +usr/sbin/atd2 ! Suspicious file ::rootkits/Suspicious.php +usr/bin/ishit ! Suspicious file ::rootkits/Suspicious.php +usr/bin/.etc ! Suspicious file ::rootkits/Suspicious.php +usr/bin/xstat ! Suspicious file ::rootkits/Suspicious.php +var/run/.tmp ! Suspicious file ::rootkits/Suspicious.php +usr/man/man1/lib/.lib ! Suspicious file ::rootkits/Suspicious.php +usr/man/man2/.man8 ! Suspicious file ::rootkits/Suspicious.php +var/run/.pid ! Suspicious file ::rootkits/Suspicious.php +lib/.so ! Suspicious file ::rootkits/Suspicious.php +lib/.fx ! Suspicious file ::rootkits/Suspicious.php +lib/lblip.tk ! Suspicious file ::rootkits/Suspicious.php +usr/lib/.fx ! Suspicious file ::rootkits/Suspicious.php +var/local/.lpd ! Suspicious file ::rootkits/Suspicious.php +dev/rd/cdb ! Suspicious file ::rootkits/Suspicious.php +dev/.rd/ ! Suspicious file ::rootkits/Suspicious.php +usr/lib/pt07 ! Suspicious file ::rootkits/Suspicious.php +usr/bin/atm ! Suspicious file ::rootkits/Suspicious.php +tmp/.cheese ! Suspicious file ::rootkits/Suspicious.php +dev/.arctic ! Suspicious file ::rootkits/Suspicious.php +dev/.xman ! Suspicious file ::rootkits/Suspicious.php +dev/.golf ! Suspicious file ::rootkits/Suspicious.php +dev/srd0 ! Suspicious file ::rootkits/Suspicious.php +dev/ptyzx ! Suspicious file ::rootkits/Suspicious.php +dev/ptyzg ! Suspicious file ::rootkits/Suspicious.php +dev/xdf1 ! Suspicious file ::rootkits/Suspicious.php +dev/ttyop ! Suspicious file ::rootkits/Suspicious.php +dev/ttyof ! Suspicious file ::rootkits/Suspicious.php +dev/hd7 ! Suspicious file ::rootkits/Suspicious.php +dev/hdx1 ! Suspicious file ::rootkits/Suspicious.php +dev/hdx2 ! Suspicious file ::rootkits/Suspicious.php +dev/xdf2 ! Suspicious file ::rootkits/Suspicious.php +dev/ptyp ! Suspicious file ::rootkits/Suspicious.php +dev/ptyr ! Suspicious file ::rootkits/Suspicious.php +sbin/pback ! Suspicious file ::rootkits/Suspicious.php +usr/man/man3/psid ! Suspicious file ::rootkits/Suspicious.php +proc/kset ! Suspicious file ::rootkits/Suspicious.php +usr/bin/gib ! Suspicious file ::rootkits/Suspicious.php +usr/bin/snick ! Suspicious file ::rootkits/Suspicious.php +usr/bin/kfl ! Suspicious file ::rootkits/Suspicious.php +tmp/.dump ! Suspicious file ::rootkits/Suspicious.php +var/.x ! Suspicious file ::rootkits/Suspicious.php +var/.x/psotnic ! Suspicious file ::rootkits/Suspicious.php +*/.log ! Suspicious file ::rootkits/Suspicious.php +*/ecmf ! Suspicious file ::rootkits/Suspicious.php +*/mirkforce ! Suspicious file ::rootkits/Suspicious.php +*/mfclean ! Suspicious file ::rootkits/Suspicious.php + +/reptile/reptile_cmd ! Suspicious file ::reptile +/lib/udev/reptile ! Suspicious file ::reptile + +# BEURK rootkit +/lib/libselinux.so ! BEURK rootkit + +# JynxKit2 rootkit +*/jynx2.so ! JynxKit2 rootkit + +# JynxKit rootkit +*/ld_poison.so ! JynxKit rootkit diff --git a/src/rootcheck/db/rootkit_trojans.txt b/src/rootcheck/db/rootkit_trojans.txt new file mode 100644 index 000000000..dcc3bd785 --- /dev/null +++ b/src/rootcheck/db/rootkit_trojans.txt @@ -0,0 +1,107 @@ +# rootkit_trojans.txt, (C) 2018 openarmor Project +# Imported from the rootcheck project. +# Some entries taken from the chkrootkit project. +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# Blank lines and lines starting with '#' are ignored. +# +# Each line must be in the following format: +# file_name !string_to_search!Description + +# Common binaries and public trojan entries +ls !bash|^/bin/sh|dev/[^clu]|\.tmp/lsfile|duarawkz|/prof|/security|file\.h! +env !bash|^/bin/sh|file\.h|proc\.h|/dev/|^/bin/.*sh! +echo !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +chown !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +chmod !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +chgrp !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +cat !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cl]|^/bin/.*sh! +bash !proc\.h|/dev/[0-9]|/dev/[hijkz]! +sh !proc\.h|/dev/[0-9]|/dev/[hijkz]! +uname !bash|^/bin/sh|file\.h|proc\.h|^/bin/.*sh! +date !bash|^/bin/sh|file\.h|proc\.h|/dev/[^cln]|^/bin/.*sh! +du !w0rm|/prof|file\.h! +df !bash|^/bin/sh|file\.h|proc\.h|/dev/[^clurdv]|^/bin/.*sh! +login !elite|SucKIT|xlogin|vejeta|porcao|lets_log|sukasuk! +passwd !bash|file\.h|proc\.h|/dev/ttyo|/dev/[A-Z]|/dev/[b-s,uvxz]! +mingetty !bash|Dimensioni|pacchetto! +chfn !bash|file\.h|proc\.h|/dev/ttyo|/dev/[A-Z]|/dev/[a-s,uvxz]! +chsh !bash|file\.h|proc\.h|/dev/ttyo|/dev/[A-Z]|/dev/[a-s,uvxz]! +mail !file\.h|proc\.h|/dev/[^nu]! +su !/dev/[d-s,abuvxz]|/dev/[A-D]|/dev/[F-Z]|/dev/[0-9]|satori|vejeta|conf\.inv! +sudo !satori|vejeta|conf\.inv! +crond !/dev/[^nt]|bash! +gpm !bash|mingetty! +ifconfig !bash|^/bin/sh|/dev/tux|session.null|/dev/[^cludisopt]! +diff !bash|^/bin/sh|file\.h|proc\.h|^/bin/.*sh! +md5sum !bash|^/bin/sh|file\.h|proc\.h|/dev/|^/bin/.*sh! +hdparm !bash|/dev/ida! +ldd !/dev/[^n]|proc\.h|libshow.so|libproc.a! + +# Trojan entries for troubleshooting binaries +grep !bash|givemer! +egrep !bash|^/bin/sh|file\.h|proc\.h|/dev/|^/bin/.*sh! +find !bash|/dev/[^tnlcs]|/prof|/home/virus|file\.h! +lsof !/prof|/dev/[^apcmnfk]|proc\.h|bash|^/bin/sh|/dev/ttyo|/dev/ttyp! +netstat !bash|^/bin/sh|/dev/[^aik]|/prof|grep|addr\.h! +top !/dev/[^npi3st%]|proc\.h|/prof/! +ps !/dev/ttyo|\.1proc|proc\.h|bash|^/bin/sh! +tcpdump !bash|^/bin/sh|file\.h|proc\.h|/dev/[^bu]|^/bin/.*sh! +pidof !bash|^/bin/sh|file\.h|proc\.h|/dev/[^f]|^/bin/.*sh! +fuser !bash|^/bin/sh|file\.h|proc\.h|/dev/[a-dtz]|^/bin/.*sh! +w !uname -a|proc\.h|bash! + +# Trojan entries for common daemons +sendmail !bash|fuck! +named !bash|blah|/dev/[0-9]|^/bin/sh! +inetd !bash|^/bin/sh|file\.h|proc\.h|/dev/[^un%]|^/bin/.*sh! +apachectl !bash|^/bin/sh|file\.h|proc\.h|/dev/[^n]|^/bin/.*sh! +sshd !check_global_passwd|panasonic|satori|vejeta|\.ark|/hash\.zk|bash|/dev[a-s]|/dev[A-Z]/! +syslogd !bash|/usr/lib/pt07|/dev/[^cln]]|syslogs\.h|proc\.h! +xinetd !bash|file\.h|proc\.h! +in.telnetd !cterm100|vt350|VT100|ansi-term|bash|^/bin/sh|/dev[A-R]|/dev/[a-z]/! +in.fingerd !bash|^/bin/sh|cterm100|/dev/! +identd !bash|^/bin/sh|file\.h|proc\.h|/dev/[^n]|^/bin/.*sh! +init !bash|/dev/h +tcpd !bash|proc\.h|p1r0c4|hack|/dev/[^n]! +rlogin !p1r0c4|r00t|bash|/dev/[^nt]! + +# Kill trojan +killall !/dev/[^t%]|proc\.h|bash|tmp! +kill !/dev/[ab,d-k,m-z]|/dev/[F-Z]|/dev/[A-D]|/dev/[0-9]|proc\.h|bash|tmp! + +# Rootkit entries +/etc/rc.d/rc.sysinit !enyelkmHIDE! enye-sec Rootkit + +# ZK rootkit (http://honeyblog.org/junkyard/reports/redhat-compromise2.pdf) +/etc/sysconfig/console/load.zk !/bin/sh! ZK rootkit +/etc/sysconfig/console/load.zk !usr/bin/run! ZK rootkit + +# Modified /etc/hosts entries +# Idea taken from: +# http://blog.tenablesecurity.com/2006/12/detecting_compr.html +# http://www.sophos.com/security/analyses/trojbagledll.html +# http://www.f-secure.com/v-descs/fantibag_b.shtml +/etc/hosts !^[^#]*avp.ch!Anti-virus site on the hosts file +/etc/hosts !^[^#]*avp.ru!Anti-virus site on the hosts file +/etc/hosts !^[^#]*awaps.net! Anti-virus site on the hosts file +/etc/hosts !^[^#]*ca.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*mcafee.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*microsoft.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*f-secure.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*sophos.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*symantec.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*my-etrust.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*nai.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*networkassociates.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*viruslist.ru! Anti-virus site on the hosts file +/etc/hosts !^[^#]*kaspersky! Anti-virus site on the hosts file +/etc/hosts !^[^#]*symantecliveupdate.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*grisoft.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*clamav.net! Anti-virus site on the hosts file +/etc/hosts !^[^#]*bitdefender.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*antivirus.com! Anti-virus site on the hosts file +/etc/hosts !^[^#]*sans.org! Security site on the hosts file diff --git a/src/rootcheck/db/system_audit_pw.txt b/src/rootcheck/db/system_audit_pw.txt new file mode 100644 index 000000000..cc2012a6d --- /dev/null +++ b/src/rootcheck/db/system_audit_pw.txt @@ -0,0 +1,103 @@ +# openarmor Linux Audit - (C) 2018 +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry , use "->" to look for a specific entry and another +# "->" to look for the value. +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceeded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). +# +# Checks for Password Security on Linux Systems +# +#1 Set Default Algorithm for Password Encryption to SHA256 or SHA 512 +[Password Hardening - 1: Set Default Algorithm for Password Encryption to SHA256 or SHA 512] [any] [https://security.stackexchange.com/questions/77349/how-can-i-find-out-the-password-hashing-schemes-used-by-the-specific-unix-accoun, https://docs.oracle.com/cd/E26505_01/html/E27224/secsystask-42.html] +f:/etc/security/policy.conf -> !r:^# && r:^CRYPT_DEFAULT=1|^CRYPT_DEFAULT=2|^CRYPT_DEFAULT=2a|^CRYPT_DEFAULT=2x|^CRYPT_DEFAULT=2y|^CRYPT_DEFAULT=md5|^CRYPT_DEFAULT=__unix__; +f:/etc/security/policy.conf -> !r:^CRYPT_DEFAULT=\d; +f:/etc/login.defs -> !r:^# && r:^ENCRYPT_METHOD\s+MD5|^ENCRYPT_METHOD\s+DES; +f:/etc/login.defs -> !r:^ENCRYPT_METHOD\s+SHA512|^ENCRYPT_METHOD\s+SHA256; +f:/etc/pam.d/common-password -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/common-password -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +f:/etc/pam.d/password-auth -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/password-auth -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +f:/etc/pam.d/system-auth -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/system-auth -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +f:/etc/pam.d/system-auth-ac -> !r:^# && r:password\.+pam_unix.so\.+md5|password\.+pam_unix.so\.+des; +f:/etc/pam.d/system-auth-ac -> !r:^password\.+pam_unix.so\.+sha512|^password\.+pam_unix.so\.+sha256; +# +# +#2 Passwords in /etc/shadow not hashed with SHA-256 or SHA-512 +[Password Hardening - 2: Not all Passwords in /etc/shadow are hashed with SHA-256 or SHA-512] [any] [https://linux-audit.com/password-security-with-linux-etc-shadow-file/, https://docs.oracle.com/cd/E19253-01/816-4557/concept-23/index.html] +f:/etc/shadow -> !r:^# && !r:^\w+:NP:\d+:\d*:\d*:\d*:\d*:\d*:\d*$ && r:^\w+:\w\.*:\d+:\d*:\d*:\d*:\d*:\d*:\d*$; +f:/etc/shadow -> !r:^# && r:\w+:\$1\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2a\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2x\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$2y\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$md5\$\.+; +f:/etc/shadow -> !r:^# && r:\w+:\$__unix__\$\.+; +# +# +#3 Set Password Creation Requirement Parameters +[Password Hardening - 3: Set Password Creation Requirement Parameters] [any] [https://linux-audit.com/configure-the-minimum-password-length-on-linux-systems/, https://workbench.cisecurity.org] +f:/etc/pam.d/common-password -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/common-password -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/password-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/password-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/system-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/system-auth -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/system-auth-ac -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass; +f:/etc/pam.d/system-auth-ac -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+; +f:/etc/pam.d/passwd -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_cracklib.so\.+try_first_pass|^password\s*\t*required\s*\t*pam_pwquality.so\.+try_first_pass|^@include\s+common-password; +f:/etc/pam.d/passwd -> !r:^password\s*\t*requisite\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*requisite\s*\t*pam_pwquality.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_cracklib.so\.+retry=\d+|^password\s*\t*required\s*\t*pam_pwquality.so\.+retry=\d+|^@include\s+common-password; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:minlen=\d\d+; +f:/etc/security/pwquality.conf -> !r:^minlen=\d\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:dcredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^dcredit=\p*\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:lcredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^lcredit=\p*\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:ocredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^ocredit=\p*\d+; +f:/etc/pam.d/common-password -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/pam.d/password-auth -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/pam.d/system-auth -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/pam.d/passwd -> r:pam_cracklib.so && !r:ucredit=\p*\d+; +f:/etc/security/pwquality.conf -> !r:^ucredit=\p*\d+; +# +# +#4 Set default password expiration / aging parameters +[Password Hardening - 4: Set password expiration / aging parameters] [any] [https://www.thegeekdiary.com/understanding-etclogin-defs-file, https://workbench.cisecurity.org/sections/26024/recommendations/63001] +f:/etc/default/passwd -> !r:^MAXWEEKS=\d\d$; +f:/etc/default/passwd -> !r:^MINWEEKS=\d; +f:/etc/default/passwd -> !r:^WARNWEEKS=\d; +f:/etc/login.defs -> !r:^PASS_MAX_DAYS\s*\t*\d\d$; +f:/etc/login.defs -> !r:^PASS_MIN_DAYS\s*\t*\d; +f:/etc/login.defs -> !r:^PASS_WARN_AGE\s*\t*\d; diff --git a/src/rootcheck/db/system_audit_rcl.txt b/src/rootcheck/db/system_audit_rcl.txt new file mode 100644 index 000000000..2a1be7138 --- /dev/null +++ b/src/rootcheck/db/system_audit_rcl.txt @@ -0,0 +1,95 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - p (process running) +# - d (any file inside the directory) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +$php.ini=/etc/php.ini,/var/www/conf/php.ini,/etc/php5/apache2/php.ini,/usr/local/etc/php.ini; +$web_dirs=/var/www,/var/htdocs,/home/httpd,/usr/local/apache,/usr/local/apache2,/usr/local/www; + +# PHP checks +[PHP - Register globals are enabled] [any] [] +f:$php.ini -> r:^register_globals = On; + +# PHP checks +[PHP - Expose PHP is enabled] [any] [] +f:$php.ini -> r:^expose_php = On; + +# PHP checks +[PHP - Allow URL fopen is enabled] [any] [] +f:$php.ini -> r:^allow_url_fopen = On; + +# PHP checks +[PHP - Displaying of errors is enabled] [any] [] +f:$php.ini -> r:^display_errors = On; + +# PHP checks - consider open_basedir && disable_functions + + +## Looking for common web exploits (might indicate that you are owned). +## Using http://dcid.me/blog/logsamples/webattacks_links as a reference. +#[Web exploits - Possible compromise] [any] [] +#d:$web_dirs -> .txt$ -> r:^ ^.yop$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^id$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^.ssh$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^...$; + +[Web exploits (uncommon file name inside htdocs) - Possible compromise {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> ^.shell$; + +## Looking for outdated Web applications +## Taken from http://sucuri.net/latest-versions +[Web vulnerability - Outdated WordPress installation {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://sucuri.net/latest-versions] +d:$web_dirs -> ^version.php$ -> r:^\.wp_version && >:$wp_version = '4.4.2'; + +[Web vulnerability - Outdated Joomla installation {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://sucuri.net/latest-versions] +d:$web_dirs -> ^version.php$ -> r:var \.RELEASE && r:'3.4.8'; + +[Web vulnerability - Outdated osCommerce (v2.2) installation {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://sucuri.net/latest-versions] +d:$web_dirs -> ^application_top.php$ -> r:'osCommerce 2.2-; + +## Looking for known backdoors +[Web vulnerability - Backdoors / Web based malware found - eval(base64_decode {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> .php$ -> r:eval\(base64_decode\(\paWYo; + +[Web vulnerability - Backdoors / Web based malware found - eval(base64_decode(POST {PCI_DSS: 6.5, 6.6, 11.4}] [any] [] +d:$web_dirs -> .php$ -> r:eval\(base64_decode\(\S_POST; + +[Web vulnerability - .htaccess file compromised {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://blog.sucuri.net/2011/05/understanding-htaccess-attacks-part-1.html] +d:$web_dirs -> ^.htaccess$ -> r:RewriteCond \S+HTTP_REFERERS \S+google; + +[Web vulnerability - .htaccess file compromised - auto append {PCI_DSS: 6.5, 6.6, 11.4}] [any] [http://blog.sucuri.net/2011/05/understanding-htaccess-attacks-part-1.html] +d:$web_dirs -> ^.htaccess$ -> r:php_value auto_append_file; diff --git a/src/rootcheck/db/system_audit_ssh.txt b/src/rootcheck/db/system_audit_ssh.txt new file mode 100644 index 000000000..8edfa91d6 --- /dev/null +++ b/src/rootcheck/db/system_audit_ssh.txt @@ -0,0 +1,81 @@ +# SSH Rootcheck +# +# v1.0 2016/01/20 +# Created by Wazuh, Inc. . +# jesus@wazuh.com +# This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2 +# + + +$sshd_file=/etc/ssh/sshd_config; + + +# Listen PORT != 22 +# The option Port specifies on which port number ssh daemon listens for incoming connections. +# Changing the default port you may reduce the number of successful attacks from zombie bots, an attacker or bot doing port-scanning can quickly identify your SSH port. +[SSH Hardening - 1: Port 22 {PCI_DSS: 2.2.4}] [any] [1] +f:$sshd_file -> !r:^# && r:Port\.+22; + + +# Protocol 2 +# The Protocol parameter dictates which version of the SSH communication and encryption protocols are in use. +# Version 1 of the SSH protocol has weaknesses. +[SSH Hardening - 2: Protocol 1 {PCI_DSS: 2.2.4}] [any] [2] +f:$sshd_file -> !r:^# && r:Protocol\.+1; + + +# PermitRootLogin no +# The option PermitRootLogin specifies whether root can log in using ssh. +# If you want log in as root, you should use the option "Match" and restrict it to a few IP addresses. +[SSH Hardening - 3: Root can log in] [any] [3] +f:$sshd_file -> !r:^# && r:PermitRootLogin\.+yes; +f:$sshd_file -> r:^#\s*PermitRootLogin; + + +# PubkeyAuthentication yes +# Access only by public key +# Generally people will use weak passwords and have poor password practices. Keys are considered stronger than password. +[SSH Hardening - 4: No Public Key autentication {PCI_DSS: 2.2.4}] [any] [4] +f:$sshd_file -> !r:^# && r:PubkeyAuthentication\.+no; +f:$sshd_file -> r:^#\s*PubkeyAuthentication; + + +# PasswordAuthentication no +# The option PasswordAuthentication specifies whether we should use password-based authentication. +# Use public key authentication instead of passwords +[SSH Hardening - 5: Password Authentication {PCI_DSS: 2.2.4}] [any] [5] +f:$sshd_file -> !r:^# && r:PasswordAuthentication\.+yes; +f:$sshd_file -> r:^#\s*PasswordAuthentication; + + +# PermitEmptyPasswords no +# The option PermitEmptyPasswords specifies whether the server allows logging in to accounts with a null password +# Accounts with null passwords are a bad practice. +[SSH Hardening - 6: Empty passwords allowed {PCI_DSS: 2.2.4}] [any] [6] +f:$sshd_file -> !r:^# && r:PermitEmptyPasswords\.+yes; +f:$sshd_file -> r:^#\s*PermitEmptyPasswords; + + +# IgnoreRhosts yes +# The option IgnoreRhosts specifies whether rhosts or shosts files should not be used in authentication. +# For security reasons it is recommended to no use rhosts or shosts files for authentication. +[SSH Hardening - 7: Rhost or shost used for authentication {PCI_DSS: 2.2.4}] [any] [7] +f:$sshd_file -> !r:^# && r:IgnoreRhosts\.+no; +f:$sshd_file -> r:^#\s*IgnoreRhosts; + + +# LoginGraceTime 30 +# The option LoginGraceTime specifies how long in seconds after a connection request the server will wait before disconnecting if the user has not successfully logged in. +# 30 seconds is the recommended time for avoiding open connections without authenticate +[SSH Hardening - 8: Wrong Grace Time {PCI_DSS: 2.2.4}] [any] [8] +f:$sshd_file -> !r:^# && r:LoginGraceTime && !r:30\s*$; +f:$sshd_file -> r:^#\s*LoginGraceTime; + + +# MaxAuthTries 3 +# The MaxAuthTries parameter specifices the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged. +# This should be set to 3. +[SSH Hardening - 9: Wrong Maximum number of authentication attempts {PCI_DSS: 2.2.4}] [any] [9] +f:$sshd_file -> !r:^# && r:MaxAuthTries && !r:3\s*$; +f:$sshd_file -> r:^#\s*MaxAuthTries; +f:$sshd_file -> !r:MaxAuthTries; diff --git a/src/rootcheck/db/win_applications_rcl.txt b/src/rootcheck/db/win_applications_rcl.txt new file mode 100644 index 000000000..ab61dceb4 --- /dev/null +++ b/src/rootcheck/db/win_applications_rcl.txt @@ -0,0 +1,126 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +[Chat/IM/VoIP - Skype {PCI_DSS: 10.6.1}] [any] [] +f:\Program Files\Skype\Phone; +f:\Documents and Settings\All Users\Documents\My Skype Pictures; +f:\Documents and Settings\Skype; +f:\Documents and Settings\All Users\Start Menu\Programs\Skype; +r:HKLM\SOFTWARE\Skype; +r:HKEY_LOCAL_MACHINE\Software\Policies\Skype; +p:r:Skype.exe; + +[Chat/IM - Yahoo {PCI_DSS: 10.6.1}] [any] [] +f:\Documents and Settings\All Users\Start Menu\Programs\Yahoo! Messenger; +r:HKLM\SOFTWARE\Yahoo; + +[Chat/IM - ICQ {PCI_DSS: 10.6.1}] [any] [] +r:HKEY_CURRENT_USER\Software\Mirabilis\ICQ; + +[Chat/IM - AOL {PCI_DSS: 10.6.1}] [any] [http://www.aol.com] +r:HKEY_LOCAL_MACHINE\SOFTWARE\America Online\AOL Instant Messenger; +r:HKEY_CLASSES_ROOT\aim\shell\open\command; +r:HKEY_CLASSES_ROOT\AIM.Protocol; +r:HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/x-aim; +f:\Program Files\AIM95; +p:r:aim.exe; + +[Chat/IM - MSN {PCI_DSS: 10.6.1}] [any] [http://www.msn.com] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSNMessenger; +r:HKEY_CURRENT_USER\SOFTWARE\Microsoft\MSNMessenger; +f:\Program Files\MSN Messenger; +f:\Program Files\Messenger; +p:r:msnmsgr.exe; + +[Chat/IM - ICQ {PCI_DSS: 10.6.1}] [any] [http://www.icq.com] +r:HKLM\SOFTWARE\Mirabilis\ICQ; + +[P2P - UTorrent {PCI_DSS: 10.6.1}] [any] [] +p:r:utorrent.exe; + +[P2P - LimeWire {PCI_DSS: 11.4}] [any] [] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Limewire; +r:HKLM\software\microsoft\windows\currentversion\run -> limeshop; +f:\Program Files\limewire; +f:\Program Files\limeshop; + +[P2P/Adware - Kazaa {PCI_DSS: 11.4}] [any] [] +f:\Program Files\kazaa; +f:\Documents and Settings\All Users\Start Menu\Programs\kazaa; +f:\Documents and Settings\All Users\DESKTOP\Kazaa Media Desktop.lnk; +f:\Documents and Settings\All Users\DESKTOP\Kazaa Promotions.lnk; +f:%WINDIR%\System32\Cd_clint.dll; +r:HKEY_LOCAL_MACHINE\SOFTWARE\KAZAA; +r:HKEY_CURRENT_USER\SOFTWARE\KAZAA; +r:HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN\KAZAA; + +# http://vil.nai.com/vil/content/v_135023.htm +[Adware - RxToolBar {PCI_DSS: 11.4}] [any] [http://vil.nai.com/vil/content/v_135023.htm] +r:HKEY_CURRENT_USER\Software\Infotechnics; +r:HKEY_CURRENT_USER\Software\Infotechnics\RX Toolbar; +r:HKEY_CURRENT_USER\Software\RX Toolbar; +r:HKEY_CLASSES_ROOT\BarInfoUrl.TBInfo; +r:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RX Toolbar; +f:\Program Files\RXToolBar; + +# http://btfaq.com/serve/cache/18.html +[P2P - BitTorrent {PCI_DSS: 10.6.1}] [any] [http://btfaq.com/serve/cache/18.html] +f:\Program Files\BitTorrent; +r:HKEY_CLASSES_ROOT\.torrent; +r:HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/x-bittorrent; +r:HKEY_CLASSES_ROOT\bittorrent; +r:HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\BitTorrent; + +# http://www.gotomypc.com +[Remote Access - GoToMyPC {PCI_DSS: 10.6.1}] [any] [] +f:\Program Files\Citrix\GoToMyPC; +f:\Program Files\Citrix\GoToMyPC\g2svc.exe; +f:\Program Files\Citrix\GoToMyPC\g2comm.exe; +f:\Program Files\expertcity\GoToMyPC; +r:HKLM\software\microsoft\windows\currentversion\run -> gotomypc; +r:HKEY_LOCAL_MACHINE\software\citrix\gotomypc; +r:HKEY_LOCAL_MACHINE\system\currentcontrolset\services\gotomypc; +p:r:g2svc.exe; +p:r:g2pre.exe; + +[Spyware - Twain Tec Spyware {PCI_DSS: 11.4}] [any] [] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TwaintecDll.TwaintecDllObj.1; +r:HKEY_LOCAL_MACHINE\SOFTWARE\twaintech; +f:%WINDIR%\twaintec.dll; + +# http://www.symantec.com/security_response/writeup.jsp?docid=2004-062611-4548-99&tabid=2 +[Spyware - SpyBuddy {PCI_DSS: 11.4}] [any] [] +f:\Program Files\ExploreAnywhere\SpyBuddy\sb32mon.exe; +f:\Program Files\ExploreAnywhere\SpyBuddy; +f:\Program Files\ExploreAnywhere; +f:%WINDIR%\System32\sysicept.dll; +r:HKEY_LOCAL_MACHINE\Software\ExploreAnywhere Software\SpyBuddy; + +[Spyware - InternetOptimizer {PCI_DSS: 11.4}] [any] [] +r:HKLM\SOFTWARE\Avenue Media; +r:HKEY_CLASSES_ROOT\\safesurfinghelper.iebho.1; +r:HKEY_CLASSES_ROOT\\safesurfinghelper.iebho; diff --git a/src/rootcheck/db/win_audit_rcl.txt b/src/rootcheck/db/win_audit_rcl.txt new file mode 100644 index 000000000..e39ed7ea4 --- /dev/null +++ b/src/rootcheck/db/win_audit_rcl.txt @@ -0,0 +1,74 @@ +# openarmor Linux Audit - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Application name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# http://technet2.microsoft.com/windowsserver/en/library/486896ba-dfa1-4850-9875-13764f749bba1033.mspx?mfr=true +[Disabled Registry tools set {PCI_DSS: 10.6.1}] [any] [] +r:HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableRegistryTools -> 1; +r:HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System -> DisableRegistryTools -> 1; + +# http://support.microsoft.com/kb/825750 +[DCOM disabled {PCI_DSS: 10.6.1}] [any] [] +r:HKEY_LOCAL_MACHINE\Software\Microsoft\OLE -> EnableDCOM -> N; + +# http://web.mit.edu/is/topics/windows/server/winmitedu/security.html +[LM authentication allowed (weak passwords) {PCI_DSS: 10.6.1, 11.4}] [any] [] +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA -> LMCompatibilityLevel -> 0; +r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA -> LMCompatibilityLevel -> 1; + +# http://research.eeye.com/html/alerts/AL20060813.html +# Disabled by some Malwares (sometimes by McAfee and Symantec +# security center too). +[Firewall/Anti Virus notification disabled {PCI_DSS: 10.6.1}] [any] [] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> FirewallDisableNotify -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> antivirusoverride -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> firewalldisablenotify -> !0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center -> firewalldisableoverride -> !0; + +# Checking for the microsoft firewall. +[Microsoft Firewall disabled {PCI_DSS: 10.6.1, 1.4}] [all] [] +r:HKEY_LOCAL_MACHINE\software\policies\microsoft\windowsfirewall\domainprofile -> enablefirewall -> 0; +r:HKEY_LOCAL_MACHINE\software\policies\microsoft\windowsfirewall\standardprofile -> enablefirewall -> 0; + +#http://web.mit.edu/is/topics/windows/server/winmitedu/security.html +[Null sessions allowed {PCI_DSS: 11.4}] [any] [] +r:HKLM\System\CurrentControlSet\Control\Lsa -> RestrictAnonymous -> 0; + +[Error reporting disabled {PCI_DSS: 10.6.1}] [any] [http://windowsir.blogspot.com/2007/04/something-new-to-look-for.html] +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> DoReport -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeKernelFaults -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeMicrosoftApps -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeWindowsApps -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> IncludeShutdownErrs -> 0; +r:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PCHealth\ErrorReporting -> ShowUI -> 0; + +# http://support.microsoft.com/default.aspx?scid=315231 +[Automatic Logon enabled {PCI_DSS: 10.6.1}] [any] [http://support.microsoft.com/default.aspx?scid=315231] +r:HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon -> DefaultPassword; +r:HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon -> AutoAdminLogon -> 1; + +[Winpcap packet filter driver found {PCI_DSS: 10.6.1}] [any] [] +f:%WINDIR%\System32\drivers\npf.sys; diff --git a/src/rootcheck/db/win_malware_rcl.txt b/src/rootcheck/db/win_malware_rcl.txt new file mode 100644 index 000000000..cab4ef0d8 --- /dev/null +++ b/src/rootcheck/db/win_malware_rcl.txt @@ -0,0 +1,122 @@ +# openarmor Windows Malware list - (C) 2018 openarmor Project +# +# Released under the same license as openarmor. +# More details at the LICENSE file included with openarmor or online +# at: https://github.com/openarmor/openarmor-hids/blob/master/LICENSE +# +# [Malware name] [any or all] [reference] +# type:; +# +# Type can be: +# - f (for file or directory) +# - r (registry entry) +# - p (process running) +# +# Additional values: +# For the registry and for directories, use "->" to look for a specific entry and another +# "->" to look for the value. +# Also, use " -> r:^\. -> ..." to search all files in a directory +# For files, use "->" to look for a specific value in the file. +# +# # Values can be preceded by: =: (for equal) - default +# r: (for openarmor regexes) +# >: (for strcmp greater) +# <: (for strcmp lower) +# Multiple patterns can be specified by using " && " between them. +# (All of them must match for it to return true). + +# http://www.iss.net/threats/ginwui.html +[Ginwui Backdoor {PCI_DSS: 11.4}] [any] [http://www.iss.net/threats/ginwui.html] +f:%WINDIR%\System32\zsyhide.dll; +f:%WINDIR%\System32\zsydll.dll; +r:HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\zsydll; +r:HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows -> AppInit_DLLs -> r:zsyhide.dll; + +# http://www.symantec.com/security_response/writeup.jsp?docid=2006-081312-3302-99&tabid=2 +[Wargbot Backdoor {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\wgareg.exe; +r:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\wgareg; + +# http://www.f-prot.com/virusinfo/descriptions/sober_j.html +[Sober Worm {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\nonzipsr.noz; +f:%WINDIR%\System32\clonzips.ssc; +f:%WINDIR%\System32\clsobern.isc; +f:%WINDIR%\System32\sb2run.dii; +f:%WINDIR%\System32\winsend32.dal; +f:%WINDIR%\System32\winroot64.dal; +f:%WINDIR%\System32\zippedsr.piz; +f:%WINDIR%\System32\winexerun.dal; +f:%WINDIR%\System32\winmprot.dal; +f:%WINDIR%\System32\dgssxy.yoi; +f:%WINDIR%\System32\cvqaikxt.apk; +f:%WINDIR%\System32\sysmms32.lla; +f:%WINDIR%\System32\Odin-Anon.Ger; + +# http://www.symantec.com/security_response/writeup.jsp?docid=2005-042611-0148-99&tabid=2 +[Hotword Trojan {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\_; +f:%WINDIR%\System32\explore.exe; +f:%WINDIR%\System32\ svchost.exe; +f:%WINDIR%\System32\mmsystem.dlx; +f:%WINDIR%\System32\WINDLL-ObjectsWin*.DLX; +f:%WINDIR%\System32\CFXP.DRV; +f:%WINDIR%\System32\CHJO.DRV; +f:%WINDIR%\System32\MMSYSTEM.DLX; +f:%WINDIR%\System32\OLECLI.DL; + +[Beagle worm {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\System32\winxp.exe; +f:%WINDIR%\System32\winxp.exeopen; +f:%WINDIR%\System32\winxp.exeopenopen; +f:%WINDIR%\System32\winxp.exeopenopenopen; +f:%WINDIR%\System32\winxp.exeopenopenopenopen; + +# http://symantec.com/security_response/writeup.jsp?docid=2007-071711-3132-99 +[Gpcoder Trojan {PCI_DSS: 11.4}] [any] [http://symantec.com/security_response/writeup.jsp?docid=2007-071711-3132-99] +f:%WINDIR%\System32\ntos.exe; +f:%WINDIR%\System32\wsnpoem; +f:%WINDIR%\System32\wsnpoem\audio.dll; +f:%WINDIR%\System32\wsnpoem\video.dll; +r:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run -> userinit -> r:ntos.exe; + +# [http://www.symantec.com/security_response/writeup.jsp?docid=2006-112813-0222-99&tabid=2 +[Looked.BK Worm {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\uninstall\rundl132.exe; +f:%WINDIR%\Logo1_.exe; +f:%Windir%\RichDll.dll; +r:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run -> load -> r:rundl132.exe; + +[Possible Malware - Svchost running outside system32 {PCI_DSS: 11.4}] [all] [] +p:r:svchost.exe && !%WINDIR%\System32\svchost.exe; +f:!%WINDIR%\SysWOW64; + +[Possible Malware - Inetinfo running outside system32\inetsrv {PCI_DSS: 11.4}] [all] [] +p:r:inetinfo.exe && !%WINDIR%\System32\inetsrv\inetinfo.exe; +f:!%WINDIR%\SysWOW64; + +[Possible Malware - Rbot/Sdbot detected {PCI_DSS: 11.4}] [any] [] +f:%Windir%\System32\rdriv.sys; +f:%Windir%\lsass.exe; + +[Possible Malware File {PCI_DSS: 11.4}] [any] [] +f:%WINDIR%\utorrent.exe; +f:%WINDIR%\System32\utorrent.exe; +f:%WINDIR%\System32\Files32.vxd; + +# Modified /etc/hosts entries +# Idea taken from: +# http://blog.tenablesecurity.com/2006/12/detecting_compr.html +# http://www.sophos.com/security/analyses/trojbagledll.html +# http://www.f-secure.com/v-descs/fantibag_b.shtml +[Anti-virus site on the hosts file] [any] [] +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:avp.ch|avp.ru|nai.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:awaps.net|ca.com|mcafee.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:microsoft.com|f-secure.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:sophos.com|symantec.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:my-etrust.com|viruslist.ru; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:networkassociates.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:kaspersky|grisoft.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:symantecliveupdate.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:clamav.net|bitdefender.com; +f:%WINDIR%\System32\Drivers\etc\HOSTS -> r:antivirus.com|sans.org; diff --git a/src/rootcheck/os_string.c b/src/rootcheck/os_string.c new file mode 100644 index 000000000..981a34c18 --- /dev/null +++ b/src/rootcheck/os_string.c @@ -0,0 +1,271 @@ +/* Included and modified strings.c from the OpenBSD project */ + +/* + * Copyright (c) 1980, 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef WIN32 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef SOLARIS +#include +#elif defined Darwin || defined HPUX + +/* For some reason darwin does not have that */ +struct exec { + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned char a_machtype; /* machine type */ + unsigned short a_magic; /* magic number */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define OMAGIC 0407 /* Object file or impure executable */ +#define NMAGIC 0410 /* Code indicating pure executable */ +#define ZMAGIC 0413 /* Code indicating demand-paged executable */ +#define BMAGIC 0415 /* Used by a b.out object */ +#define M_OLDSUN2 0 + +#else +#include +#endif + +#ifndef PAGSIZ +#define PAGSIZ 0x02000 +#endif + +#ifndef OLD_PAGSIZ +#define OLD_PAGSIZ 0x00800 +#endif + +#ifndef N_BADMAG + +#ifdef AIX +#define N_BADMAG(x) \ + (((x).magic)!=U802TOCMAGIC && ((x).magic)!=U803TOCMAGIC && ((x).magic)!=U803XTOCMAGIC && ((x).magic)!=U64_TOCMAGIC) +#else /* non AIX */ +#define N_BADMAG(x) \ + (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC) +#endif + +#endif /* N_BADMAG */ + +#ifndef N_PAGSIZ +#define N_PAGSIZ(x) \ + ((x).a_machtype == M_OLDSUN2? OLD_PAGSIZ : PAGSIZ) +#endif + +#ifndef N_TXTOFF + +#ifdef AIX +#define N_TXTOFF(x) \ + /* text segment */ \ + ((x).magic==U64_TOCMAGIC ? 0 : sizeof (struct aouthdr)) +#else /* non AIX */ +#define N_TXTOFF(x) \ + /* text segment */ \ + ((x).a_machtype == M_OLDSUN2 \ + ? ((x).a_magic==ZMAGIC ? N_PAGSIZ(x) : sizeof (struct exec)) \ + : ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec)) ) +#endif + +#endif /* N_TXTOFF */ + +#include "headers/defs.h" +#include "headers/debug_op.h" +#include "headers/regex_op.h" + +#include "error_messages/error_messages.h" + +#define STR_MINLEN 4 /* Minimum length for a string */ + +#define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t')) + +#ifdef AIX +typedef struct aouthdr EXEC; +#else +typedef struct exec EXEC; +#endif + +typedef struct _os_strings { + int head_len; + int read_len; + int hcnt; + long foff; + unsigned char hbfr[sizeof(EXEC)]; + FILE *fp; +} os_strings; + +/* Read each character from a binary file */ +int os_getch(os_strings *oss); + + +/* List the strings of a binary and check if the regex given is there */ +int os_string(char *file, char *regex) +{ + int ch, cnt; + unsigned char *C; + unsigned char *bfr; + char line[OS_SIZE_1024 + 1]; + char *buf; + EXEC *head; + os_strings oss; + + /* Return didn't match */ + if (!file || !regex) { + return (0); + } + + /* Allocate the buffer */ + bfr = (unsigned char *) calloc(STR_MINLEN + 2, sizeof(unsigned char)); + if (!bfr) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return (0); + } + + /* Open the file */ + oss.fp = fopen(file, "r"); + if (!oss.fp) { + free(bfr); + return (0); + } + + /* Clean the line */ + memset(line, '\0', OS_SIZE_1024 + 1); + + /* Start (from old strings.c) */ + oss.foff = 0; + oss.head_len = 0; + oss.read_len = -1; + head = (EXEC *)oss.hbfr; + + if ((oss.head_len = read(fileno(oss.fp), head, sizeof(EXEC))) == -1) { + oss.head_len = 0; + oss.read_len = -1; + } else if (oss.head_len == sizeof(EXEC) && !N_BADMAG(*head)) { + oss.foff = N_TXTOFF(*head); + if (fseek(stdin, oss.foff, SEEK_SET) == -1) { + oss.read_len = -1; + } else { +#ifdef AIX + oss.read_len = head->tsize + head->dsize; +#else + oss.read_len = head->a_text + head->a_data; +#endif + } + + oss.head_len = 0; + } else { + oss.hcnt = 0; + } + + /* Read the file and perform the regex comparison */ + for (cnt = 0, C = bfr; (ch = os_getch(&oss)) != EOF;) { + if (ISSTR(ch)) { + if (!cnt) { + C = bfr; + } + *C++ = ch; + if (++cnt < STR_MINLEN) { + continue; + } + + strncpy(line, (char *)bfr, STR_MINLEN + 1); + buf = line; + buf += strlen(line); + + while ((ch = os_getch(&oss)) != EOF && ISSTR(ch)) { + if (cnt < OS_SIZE_1024) { + *buf = (char)ch; + buf++; + } else { + *buf = '\0'; + break; + } + cnt++; + } + + *buf = '\0'; + + if (OS_PRegex(line, regex)) { + if (oss.fp) { + fclose(oss.fp); + } + free(bfr); + return (1); + } + } + + cnt = 0; + } + + if (oss.fp) { + fclose(oss.fp); + } + free(bfr); + return (0); +} + +/* Get next character from wherever */ +int os_getch(os_strings *oss) +{ + ++oss->foff; + if (oss->head_len) { + if (oss->hcnt < oss->head_len) { + return ((int)oss->hbfr[oss->hcnt++]); + } + oss->head_len = 0; + } + if (oss->read_len == -1 || oss->read_len-- > 0) { + return (fgetc(oss->fp)); + } + return (EOF); +} + +#else +int os_string(__attribute__((unused)) char *file, __attribute__((unused)) char *regex) +{ + return (0); +} +#endif + diff --git a/src/rootcheck/rootcheck-config.c b/src/rootcheck/rootcheck-config.c new file mode 100644 index 000000000..6b6665ac0 --- /dev/null +++ b/src/rootcheck/rootcheck-config.c @@ -0,0 +1,160 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef openarmorHIDS + +#include +#include +#include +#include + +#include "shared.h" +#include "os_xml/os_xml.h" +#include "rootcheck.h" + + +/* Evaluate boolean with two arguments + * str: input string, "yes"|"no" + * default_val: 1(yes)|0(no) + */ +short eval_bool2(char *str, short default_val) +{ + short ret = default_val; + + if (str == NULL) { + return (ret); + } else if (strcmp(str, "yes") == 0) { + ret = 1; + } else if (strcmp(str, "no") == 0) { + ret = 0; + } + + free(str); + return (ret); +} + +/* Read the rootcheck config */ +int Read_Rootcheck_Config(const char *cfgfile) +{ + OS_XML xml; +#ifdef openarmorHIDS + char *str = NULL; +#endif + + /* XML Definitions */ + const char *(xml_base_dir[]) = {xml_rootcheck, "base_directory", NULL}; + const char *(xml_workdir[]) = {xml_rootcheck, "work_directory", NULL}; + const char *(xml_rootkit_files[]) = {xml_rootcheck, "rootkit_files", NULL}; + const char *(xml_rootkit_trojans[]) = {xml_rootcheck, "rootkit_trojans", NULL}; + const char *(xml_rootkit_unixaudit[]) = {xml_rootcheck, "system_audit", NULL}; + const char *(xml_rootkit_winaudit[]) = {xml_rootcheck, "windows_audit", NULL}; + const char *(xml_rootkit_winapps[]) = {xml_rootcheck, "windows_apps", NULL}; + const char *(xml_rootkit_winmalware[]) = {xml_rootcheck, "windows_malware", NULL}; + const char *(xml_scanall[]) = {xml_rootcheck, "scanall", NULL}; + const char *(xml_readall[]) = {xml_rootcheck, "readall", NULL}; +#ifdef openarmorHIDS + const char *(xml_time[]) = {xml_rootcheck, "frequency", NULL}; +#endif + const char *(xml_check_dev[]) = {xml_rootcheck, "check_dev", NULL}; + const char *(xml_check_files[]) = {xml_rootcheck, "check_files", NULL}; + const char *(xml_check_if[]) = {xml_rootcheck, "check_if", NULL}; + const char *(xml_check_pids[]) = {xml_rootcheck, "check_pids", NULL}; + const char *(xml_check_ports[]) = {xml_rootcheck, "check_ports", NULL}; + const char *(xml_check_sys[]) = {xml_rootcheck, "check_sys", NULL}; + const char *(xml_check_trojans[]) = {xml_rootcheck, "check_trojans", NULL}; +#ifdef WIN32 + const char *(xml_check_winapps[]) = {xml_rootcheck, "check_winapps", NULL}; + const char *(xml_check_winaudit[]) = {xml_rootcheck, "check_winaudit", NULL}; + const char *(xml_check_winmalware[]) = {xml_rootcheck, "check_winmalware", NULL}; +#else + const char *(xml_check_unixaudit[]) = {xml_rootcheck, "check_unixaudit", NULL}; +#endif + +#ifdef openarmorHIDS + /* :) */ + xml_time[2] = NULL; +#endif + + if (OS_ReadXML(cfgfile, &xml) < 0) { + merror("config_op: XML error: %s", xml.err); + return (OS_INVALID); + } + + if (!OS_RootElementExist(&xml, xml_rootcheck)) { + OS_ClearXML(&xml); + merror("%s: Rootcheck configuration not found. ", ARGV0); + return (-1); + } + + +#ifdef openarmorHIDS + /* time */ + str = OS_GetOneContentforElement(&xml, xml_time); + if (str) { + if (!OS_StrIsNum(str)) { + merror("Invalid frequency time '%s' for the rootkit " + "detection (must be int).", str); + return (OS_INVALID); + } + + rootcheck.time = atoi(str); + free(str); + str = NULL; + } +#endif /* openarmorHIDS */ + + /* Scan all flags */ + if (!rootcheck.scanall) { + rootcheck.scanall = eval_bool2(OS_GetOneContentforElement(&xml, xml_scanall), 0); + } + + /* Read all flags */ + if (!rootcheck.readall) { + rootcheck.readall = eval_bool2(OS_GetOneContentforElement(&xml, xml_readall), 0); + } + + /* Get work directory */ + if (!rootcheck.workdir) { + rootcheck.workdir = OS_GetOneContentforElement(&xml, xml_workdir); + } + + rootcheck.rootkit_files = OS_GetOneContentforElement + (&xml, xml_rootkit_files); + rootcheck.rootkit_trojans = OS_GetOneContentforElement + (&xml, xml_rootkit_trojans); + rootcheck.unixaudit = OS_GetContents + (&xml, xml_rootkit_unixaudit); + rootcheck.winaudit = OS_GetOneContentforElement + (&xml, xml_rootkit_winaudit); + rootcheck.winapps = OS_GetOneContentforElement + (&xml, xml_rootkit_winapps); + rootcheck.winmalware = OS_GetOneContentforElement + (&xml, xml_rootkit_winmalware); + rootcheck.basedir = OS_GetOneContentforElement(&xml, xml_base_dir); + rootcheck.checks.rc_dev = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_dev), 1); + rootcheck.checks.rc_files = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_files), 1); + rootcheck.checks.rc_if = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_if), 1); + rootcheck.checks.rc_pids = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_pids), 1); + rootcheck.checks.rc_ports = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_ports), 1); + rootcheck.checks.rc_sys = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_sys), 1); + rootcheck.checks.rc_trojans = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_trojans), 1); +#ifdef WIN32 + rootcheck.checks.rc_winapps = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_winapps), 1); + rootcheck.checks.rc_winaudit = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_winaudit), 1); + rootcheck.checks.rc_winmalware = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_winmalware), 1); +#else + rootcheck.checks.rc_unixaudit = eval_bool2(OS_GetOneContentforElement(&xml, xml_check_unixaudit), 1); +#endif /* WIN32 */ + OS_ClearXML(&xml); + + + return (0); +} +#endif + diff --git a/src/rootcheck/rootcheck.c b/src/rootcheck/rootcheck.c new file mode 100644 index 000000000..37cca7352 --- /dev/null +++ b/src/rootcheck/rootcheck.c @@ -0,0 +1,255 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* + * Rootcheck + * Copyright (C) 2003 Daniel B. Cid + * http://www.theopenarmor.org/rootcheck/ + */ + +#include "headers/shared.h" +#include "rootcheck.h" + +rkconfig rootcheck; +char **rk_sys_file; +char **rk_sys_name; +int rk_sys_count; +char total_ports_udp[65535 + 1]; +char total_ports_tcp[65535 + 1]; + +#ifndef ARGV0 +#define ARGV0 "rootcheck" +#endif + +#ifndef openarmorHIDS + + +/* Print help statement */ +void help_rootcheck() +{ + print_header(); + print_out(" %s: -[Vhdtsr] [-c config] [-D dir]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h Print this help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -s Scan the whole system"); + print_out(" -r Read all the files for kernel-based detection"); + print_out(" -c Configuration file to use"); + print_out(" -D Directory to chroot into (default: %s)", DEFAULTDIR); + print_out(" "); + exit(1); +} + +int main(int argc, char **argv) +{ + int test_config = 0; + const char *cfg = "./rootcheck.conf"; + +#else + +int rootcheck_init(int test_config) +{ + const char *cfg = DEFAULTCPATH; + +#endif /* openarmorHIDS */ + + int c; + + /* Zero the structure, initialize default values */ + rootcheck.workdir = NULL; + rootcheck.basedir = NULL; + rootcheck.unixaudit = NULL; + rootcheck.ignore = NULL; + rootcheck.rootkit_files = NULL; + rootcheck.rootkit_trojans = NULL; + rootcheck.winaudit = NULL; + rootcheck.winmalware = NULL; + rootcheck.winapps = NULL; + rootcheck.daemon = 1; + rootcheck.notify = QUEUE; + rootcheck.scanall = 0; + rootcheck.readall = 0; + rootcheck.disabled = 0; + rootcheck.skip_nfs = 0; + rootcheck.alert_msg = NULL; + rootcheck.time = ROOTCHECK_WAIT; + + rootcheck.checks.rc_dev = 1; + rootcheck.checks.rc_files = 1; + rootcheck.checks.rc_if = 1; + rootcheck.checks.rc_pids = 1; + rootcheck.checks.rc_ports = 1; + rootcheck.checks.rc_sys = 1; + rootcheck.checks.rc_trojans = 1; + +#ifdef openarmorHIDS + rootcheck.tsleep = (unsigned int) getDefine_Int("rootcheck", "sleep", 0, 64); +#endif + +#ifdef WIN32 + rootcheck.checks.rc_winaudit = 1; + rootcheck.checks.rc_winmalware = 1; + rootcheck.checks.rc_winapps = 1; +#else + rootcheck.checks.rc_unixaudit = 1; +#endif + + /* We store up to 255 alerts in there */ + os_calloc(256, sizeof(char *), rootcheck.alert_msg); + c = 0; + while (c <= 255) { + rootcheck.alert_msg[c] = NULL; + c++; + } + +#ifndef openarmorHIDS + rootcheck.notify = SYSLOG; + rootcheck.daemon = 0; + while ((c = getopt(argc, argv, "VstrdhD:c:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_rootcheck(); + break; + case 'd': + nowDebug(); + break; + case 'D': + if (!optarg) { + ErrorExit("%s: -D needs an argument", ARGV0); + } + rootcheck.workdir = optarg; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 's': + rootcheck.scanall = 1; + break; + case 't': + test_config = 1; + break; + case 'r': + rootcheck.readall = 1; + break; + default: + help_rootcheck(); + break; + } + } +#ifdef WIN32 + /* Start Winsock */ + { + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { + ErrorExit("%s: WSAStartup() failed", ARGV0); + } + } +#endif /* WIN32 */ + +#endif /* openarmorHIDS */ + + /* Start up message */ + debug1(STARTED_MSG, ARGV0); + + /* Check if the configuration is present */ + if (File_DateofChange(cfg) < 0) { + merror("%s: Configuration file '%s' not found", ARGV0, cfg); + return (-1); + } + + /* Read configuration --function specified twice (check makefile) */ + if (Read_Rootcheck_Config(cfg) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* If testing config, exit here */ + if (test_config) { + return (0); + } + + /* Return 1 disables rootcheck */ + if (rootcheck.disabled == 1) { + verbose("%s: Rootcheck disabled. Exiting.", ARGV0); + return (1); + } + + /* Check if Unix audit file is configured */ + if (!rootcheck.unixaudit) { +#ifndef WIN32 + log2file("%s: System audit file not configured.", ARGV0); +#endif + } + + /* Set default values */ + if (rootcheck.workdir == NULL) { + rootcheck.workdir = DEFAULTDIR; + } + +#ifdef openarmorHIDS + /* Start up message */ +#ifdef WIN32 + verbose(STARTUP_MSG, "openarmor-rootcheck", getpid()); +#else + + /* Connect to the queue if configured to do so */ + if (rootcheck.notify == QUEUE) { + debug1("%s: Starting queue ...", ARGV0); + + /* Start the queue */ + if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno)); + + /* 5 seconds to see if the agent starts */ + sleep(5); + if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + /* Wait 10 more seconds */ + merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno)); + sleep(10); + if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + } + +#endif /* WIN32 */ + +#endif /* openarmorHIDS */ + + /* Initialize rk list */ + rk_sys_name = (char **) calloc(MAX_RK_SYS + 2, sizeof(char *)); + rk_sys_file = (char **) calloc(MAX_RK_SYS + 2, sizeof(char *)); + if (!rk_sys_name || !rk_sys_file) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + rk_sys_name[0] = NULL; + rk_sys_file[0] = NULL; + +#ifndef openarmorHIDS +#ifndef WIN32 + /* Start signal handling */ + StartSIG(ARGV0); +#endif + debug1("%s: DEBUG: Running run_rk_check", ARGV0); + run_rk_check(); + + debug1("%s: DEBUG: Leaving...", ARGV0); +#endif /* openarmorHIDS */ + return (0); +} + diff --git a/src/rootcheck/rootcheck.conf b/src/rootcheck/rootcheck.conf new file mode 100644 index 000000000..e7c17af3e --- /dev/null +++ b/src/rootcheck/rootcheck.conf @@ -0,0 +1,27 @@ + + no + ./db/rootkit_files.txt + ./db/rootkit_trojans.txt + + ./db/system_audit_rcl.txt + ./db/cis_debian_linux_rcl.txt + ./db/cis_rhel_linux_rcl.txt + ./db/cis_rhel5_linux_rcl.txt + ./shared/win_audit_rcl.txt + ./shared/win_applications_rcl.txt + ./shared/win_malware_rcl.txt + + yes + yes + + yes + yes + yes + yes + + yes + yes + yes + yes + yes + diff --git a/src/rootcheck/rootcheck.h b/src/rootcheck/rootcheck.h new file mode 100644 index 000000000..5ceb574c9 --- /dev/null +++ b/src/rootcheck/rootcheck.h @@ -0,0 +1,129 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __ROOTCHECK_H +#define __ROOTCHECK_H + +#include "list_op.h" +#include "config/rootcheck-config.h" +extern rkconfig rootcheck; + +/* Output types */ +#define QUEUE 101 +#define SYSLOG 102 + +/* Maximum files to search on the whole system */ +#define MAX_RK_SYS 512 + +/* rk_types */ +#define ALERT_OK 0 +#define ALERT_SYSTEM_ERR 1 +#define ALERT_SYSTEM_CRIT 2 +#define ALERT_ROOTKIT_FOUND 3 +#define ALERT_POLICY_VIOLATION 4 + +#define ROOTCHECK "rootcheck" + +/* Default to 10 hours */ +#define ROOTCHECK_WAIT 72000 + +/** Prototypes **/ + +/* Check if file is present on dir */ +int isfile_ondir(const char *file, const char *dir); + +int rk_check_file(char *file, char *pattern); + +int rk_check_dir(const char *dir, const char *file, char *pattern); + +/* Check if pattern is present on string */ +int pt_matches(const char *str, char *pattern); + +/* Check if the patterns is made up completely of negate matches */ +int pt_check_negate(const char *pattern); + +/* Check if a file exist (using stat, fopen and opendir) */ +int is_file(char *file_name); + +/* Check if an entry is in the registry */ +int is_registry(char *entry_name, char *reg_option, char *reg_value); + +/* Read cl configuration file */ +int rkcl_get_entry(FILE *fp, const char *msg, OSList *p_list); + +/* Normalize a string, removing white spaces and tabs + * from the beginning and the end of it. + */ +char *normalize_string(char *str); + +/* Check if regex is present on the file. + * Similar to `strings file | grep -r regex` + */ +int os_string(char *file, char *regex); + +/* Check for NTFS ADS (Windows only) */ +int os_check_ads(const char *full_path); + +/* Get list of processes */ +OSList *os_get_process_list(void); + +/* Check if a process is running */ +int is_process(char *value, OSList *p_list); + +/* Delete the process list */ +int del_plist(OSList *p_list); + +/* Used to report messages */ +int notify_rk(int rk_type, const char *msg); + +/* Start the rootcheck externally */ +int rootcheck_init(int test_config); + +/* run_rk_check: checks the integrity of the files against the + * saved database + */ +void run_rk_check(void); + +/*** Plugins prototypes ***/ +void check_rc_files(const char *basedir, FILE *fp); +void check_rc_trojans(const char *basedir, FILE *fp); +void check_rc_unixaudit(FILE *fp, OSList *p_list); +void check_rc_winaudit(FILE *fp, OSList *p_list); +void check_rc_winmalware(FILE *fp, OSList *p_list); +void check_rc_winapps(FILE *fp, OSList *p_list); +void check_rc_dev(const char *basedir); +void check_rc_sys(const char *basedir); +void check_rc_pids(void); + +/* Verify if "pid" is in the proc directory */ +int check_rc_readproc(int pid); + +void check_rc_ports(void); +void check_open_ports(void); +void check_rc_if(void); + +int Read_Rootcheck_Config(const char *cfgfile); + +/* Global variables */ +extern char **rk_sys_file; +extern char **rk_sys_name; +extern int rk_sys_count; + +/* All the ports */ +extern char total_ports_udp[65535 + 1]; +extern char total_ports_tcp[65535 + 1]; + +/* Process struct */ +typedef struct _Proc_Info { + char *p_name; + char *p_path; +} Proc_Info; + +#endif /* __ROOTCHECK_H */ + diff --git a/src/rootcheck/run_rk_check.c b/src/rootcheck/run_rk_check.c new file mode 100644 index 000000000..2396fa7a0 --- /dev/null +++ b/src/rootcheck/run_rk_check.c @@ -0,0 +1,313 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + + +/* Report a problem */ +int notify_rk(int rk_type, const char *msg) +{ + /* Non-queue notification */ + if (rootcheck.notify != QUEUE) { + if (rk_type == ALERT_OK) { + printf("[OK]: %s\n", msg); + } else if (rk_type == ALERT_SYSTEM_ERR) { + printf("[ERR]: %s\n", msg); + } else if (rk_type == ALERT_POLICY_VIOLATION) { + printf("[INFO]: %s\n", msg); + } else { + printf("[FAILED]: %s\n", msg); + } + + printf("\n"); + return (0); + } + + /* No need to alert on that to the server */ + if (rk_type <= ALERT_SYSTEM_ERR) { + return (0); + } + +#ifdef openarmorHIDS + /* When running in context of openarmor-HIDS, send problem to the rootcheck queue */ + if (SendMSG(rootcheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + if (SendMSG(rootcheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } +#endif + + return (0); +} + +/* Execute the rootkit checks */ +void run_rk_check() +{ + time_t time1; + time_t time2; + FILE *fp; + OSList *plist; + +#ifndef WIN32 + /* On non-Windows, always start at / */ + size_t i; + char basedir[] = "/"; + + /* Removing the last / from basedir */ + i = strlen(basedir); + if (i > 0) { + if (basedir[i - 1] == '/') { + basedir[i - 1] = '\0'; + } + } +#else + /* On Windows, always start at C:\ */ + char basedir[] = "C:\\"; + +#endif + + /* Set basedir */ + if (rootcheck.basedir == NULL) { + rootcheck.basedir = basedir; + } + + time1 = time(0); + + /* Initial message */ + if (rootcheck.notify != QUEUE) { + printf("\n"); + printf("** Starting Rootcheck v0.9 by Daniel B. Cid **\n"); + printf("** http://www.theopenarmor.org/en/about.html#dev-team **\n"); + printf("** http://www.theopenarmor.org/rootcheck/ **\n\n"); + printf("Be patient, it may take a few minutes to complete...\n"); + printf("\n"); + } + + /* Clean the global variables */ + rk_sys_count = 0; + rk_sys_file[rk_sys_count] = NULL; + rk_sys_name[rk_sys_count] = NULL; + + /* Send scan start message */ + notify_rk(ALERT_POLICY_VIOLATION, "Starting rootcheck scan."); + if (rootcheck.notify == QUEUE) { + merror("%s: INFO: Starting rootcheck scan.", ARGV0); + } + + /* Check for Rootkits */ + /* Open rootkit_files and pass the pointer to check_rc_files */ + if (rootcheck.checks.rc_files) { + if (!rootcheck.rootkit_files) { +#ifndef WIN32 + merror("%s: No rootcheck_files file configured.", ARGV0); +#endif + } else { + fp = fopen(rootcheck.rootkit_files, "r"); + if (!fp) { + merror("%s: No rootcheck_files file: '%s'", ARGV0, + rootcheck.rootkit_files); + } + + else { + check_rc_files(rootcheck.basedir, fp); + + fclose(fp); + } + } + } + + /* Check for trojan entries in common binaries */ + if (rootcheck.checks.rc_trojans) { + if (!rootcheck.rootkit_trojans) { +#ifndef WIN32 + merror("%s: No rootcheck_trojans file configured.", ARGV0); +#endif + } else { + fp = fopen(rootcheck.rootkit_trojans, "r"); + if (!fp) { + merror("%s: No rootcheck_trojans file: '%s'", ARGV0, + rootcheck.rootkit_trojans); + } else { +#ifndef HPUX + check_rc_trojans(rootcheck.basedir, fp); +#endif + fclose(fp); + } + } + } + +#ifdef WIN32 + /* Get process list */ + plist = os_get_process_list(); + + /* Windows audit check */ + if (rootcheck.checks.rc_winaudit) { + if (!rootcheck.winaudit) { + merror("%s: No winaudit file configured.", ARGV0); + } else { + fp = fopen(rootcheck.winaudit, "r"); + if (!fp) { + merror("%s: No winaudit file: '%s'", ARGV0, + rootcheck.winaudit); + } else { + check_rc_winaudit(fp, plist); + fclose(fp); + } + } + } + + /* Windows malware */ + if (rootcheck.checks.rc_winmalware) { + if (!rootcheck.winmalware) { + merror("%s: No winmalware file configured.", ARGV0); + } else { + fp = fopen(rootcheck.winmalware, "r"); + if (!fp) { + merror("%s: No winmalware file: '%s'", ARGV0, + rootcheck.winmalware); + } else { + check_rc_winmalware(fp, plist); + fclose(fp); + } + } + } + + /* Windows Apps */ + if (rootcheck.checks.rc_winapps) { + if (!rootcheck.winapps) { + merror("%s: No winapps file configured.", ARGV0); + } else { + fp = fopen(rootcheck.winapps, "r"); + if (!fp) { + merror("%s: No winapps file: '%s'", ARGV0, + rootcheck.winapps); + } else { + check_rc_winapps(fp, plist); + fclose(fp); + } + } + } + + /* Free the process list */ + del_plist((void *)plist); + +#else + /* Checks for other non-Windows */ + + /* Unix audit check ***/ + if (rootcheck.checks.rc_unixaudit) { + if (rootcheck.unixaudit) { + /* Get process list */ + plist = os_get_process_list(); + + i = 0; + while (rootcheck.unixaudit[i]) { + fp = fopen(rootcheck.unixaudit[i], "r"); + if (!fp) { + merror("%s: No unixaudit file: '%s'", ARGV0, + rootcheck.unixaudit[i]); + } else { + /* Run unix audit */ + check_rc_unixaudit(fp, plist); + fclose(fp); + } + + i++; + } + + /* Free list */ + del_plist(plist); + } + } + +#endif /* !WIN32 */ + + /* Check for files in the /dev filesystem */ + if (rootcheck.checks.rc_dev) { + debug1("%s: DEBUG: Going into check_rc_dev", ARGV0); + check_rc_dev(rootcheck.basedir); + debug1("%s: DEBUG: Exiting check_rc_dev", ARGV0); + } + + /* Scan the whole system for additional issues */ + if (rootcheck.checks.rc_sys) { + debug1("%s: DEBUG: Going into check_rc_sys", ARGV0); + check_rc_sys(rootcheck.basedir); + debug1("%s: DEBUG: Exiting check_rc_sys", ARGV0); + } + + /* Check processes */ + if (rootcheck.checks.rc_pids) { + debug1("%s: DEBUG: Going into check_rc_pids", ARGV0); + check_rc_pids(); + debug1("%s: DEBUG: Exiting check_rc_pids", ARGV0); + } + + /* Check all ports */ + if (rootcheck.checks.rc_ports) { + debug1("%s: DEBUG: Going into check_rc_ports", ARGV0); + check_rc_ports(); + debug1("%s: DEBUG: Exiting check_rc_ports", ARGV0); + + /* Check open ports */ + debug1("%s: DEBUG: Going into check_open_ports", ARGV0); + check_open_ports(); + debug1("%s: DEBUG: Exiting check_open_ports", ARGV0); + } + + /* Check interfaces */ + if (rootcheck.checks.rc_if) { + debug1("%s: DEBUG: Going into check_rc_if", ARGV0); + check_rc_if(); + debug1("%s: DEBUG: Exiting check_rc_if", ARGV0); + } + + debug1("%s: DEBUG: Completed with all checks.", ARGV0); + + /* Clean the global memory */ + { + int li; + for (li = 0; li <= rk_sys_count; li++) { + if (!rk_sys_file[li] || + !rk_sys_name[li]) { + break; + } + + free(rk_sys_file[li]); + free(rk_sys_name[li]); + } + } + + /* Final message */ + time2 = time(0); + + if (rootcheck.notify != QUEUE) { + printf("\n"); + printf("- Scan completed in %d seconds.\n\n", (int)(time2 - time1)); + } else { + sleep(5); + } + + /* Send scan ending message */ + notify_rk(ALERT_POLICY_VIOLATION, "Ending rootcheck scan."); + if (rootcheck.notify == QUEUE) { + merror("%s: INFO: Ending rootcheck scan.", ARGV0); + } + + debug1("%s: DEBUG: Leaving run_rk_check", ARGV0); + return; +} + diff --git a/src/rootcheck/unix-process.c b/src/rootcheck/unix-process.c new file mode 100644 index 000000000..9bc753ae4 --- /dev/null +++ b/src/rootcheck/unix-process.c @@ -0,0 +1,115 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + + +#ifndef WIN32 + +static char *_os_get_runps(const char *ps, int mpid) +{ + char *tmp_str, *nbuf; + char buf[OS_SIZE_2048 + 1]; + char command[OS_SIZE_1024 + 1]; + FILE *fp; + + buf[0] = '\0'; + command[0] = '\0'; + command[OS_SIZE_1024] = '\0'; + + snprintf(command, OS_SIZE_1024, "%s -p %d 2> /dev/null", ps, mpid); + fp = popen(command, "r"); + if (fp) { + while (fgets(buf, OS_SIZE_2048, fp) != NULL) { + tmp_str = strchr(buf, ':'); + if (!tmp_str) { + continue; + } + + nbuf = tmp_str++; + + tmp_str = strchr(nbuf, ' '); + if (!tmp_str) { + continue; + } + tmp_str++; + + /* Remove whitespaces */ + while (*tmp_str == ' ') { + tmp_str++; + } + + nbuf = tmp_str; + + tmp_str = strchr(nbuf, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + pclose(fp); + return (strdup(nbuf)); + } + + pclose(fp); + } + + return (NULL); +} + +/* Get list of Unix processes */ +OSList *os_get_process_list() +{ + int i = 1; + pid_t max_pid = MAX_PID; + OSList *p_list = NULL; + char ps[OS_SIZE_1024 + 1]; + + /* Check where ps is */ + memset(ps, '\0', OS_SIZE_1024 + 1); + strncpy(ps, "/bin/ps", OS_SIZE_1024); + if (!is_file(ps)) { + strncpy(ps, "/usr/bin/ps", OS_SIZE_1024); + if (!is_file(ps)) { + merror("%s: ERROR: 'ps' not found.", ARGV0); + return (NULL); + } + } + + /* Create process list */ + p_list = OSList_Create(); + if (!p_list) { + merror(LIST_ERROR, ARGV0); + return (NULL); + } + + for (i = 1; i <= max_pid; i++) { + /* Check if the pid is present */ + if ((!((getsid(i) == -1) && (errno == ESRCH))) && + (!((getpgid(i) == -1) && (errno == ESRCH)))) { + Proc_Info *p_info; + char *p_name; + + p_name = _os_get_runps(ps, (int)i); + if (!p_name) { + continue; + } + + os_calloc(1, sizeof(Proc_Info), p_info); + p_info->p_path = p_name; + p_info->p_name = NULL; + OSList_AddData(p_list, p_info); + } + } + + return (p_list); +} + +#endif /* WIN32 */ + diff --git a/src/rootcheck/util/ads_dump.c b/src/rootcheck/util/ads_dump.c new file mode 100644 index 000000000..f985e08a5 --- /dev/null +++ b/src/rootcheck/util/ads_dump.c @@ -0,0 +1,178 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include +#include + +/* ads_dump + * Dumps every NTFS ADS found in a directory (recursive) + */ + +/* Prototypes */ +int os_get_streams(char *full_path); +int read_sys_dir(char *dir_name); +int read_sys_file(char *file_name); + +/* Global variables */ +int ads_found = 0; + + +/* Print out streams of a file */ +int os_get_streams(char *full_path) +{ + HANDLE file_h; + WIN32_STREAM_ID sid; + void *context = NULL; + char stream_name[MAX_PATH + 1]; + char final_name[MAX_PATH + 1]; + DWORD dwRead, shs, dw1, dw2; + + /* Open file */ + file_h = CreateFile(full_path, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, + NULL); + + if (file_h == INVALID_HANDLE_VALUE) { + return 0; + } + + /* Zero memory */ + ZeroMemory(&sid, sizeof(WIN32_STREAM_ID)); + + /* Get stream header size -- should be 20 bytes */ + shs = (LPBYTE)&sid.cStreamName - (LPBYTE)&sid + sid.dwStreamNameSize; + + while (1) { + if (BackupRead(file_h, (LPBYTE) &sid, shs, &dwRead, + FALSE, FALSE, &context) == 0) { + break; + } + if (dwRead == 0) { + break; + } + + stream_name[0] = '\0'; + stream_name[MAX_PATH] = '\0'; + if (BackupRead(file_h, (LPBYTE)stream_name, + sid.dwStreamNameSize, + &dwRead, FALSE, FALSE, &context)) { + if (dwRead != 0) { + char *tmp_pt; + snprintf(final_name, MAX_PATH, "%s%S", full_path, + (WCHAR *)stream_name); + tmp_pt = strrchr(final_name, ':'); + if (tmp_pt) { + *tmp_pt = '\0'; + } + printf("Found NTFS ADS: '%s' \n", final_name); + ads_found = 1; + } + } + + /* Get next */ + if (!BackupSeek(file_h, sid.Size.LowPart, sid.Size.HighPart, + &dw1, &dw2, &context)) { + break; + } + } + + CloseHandle(file_h); + return (0); +} + +int read_sys_file(char *file_name) +{ + struct stat statbuf; + + /* Get streams */ + os_get_streams(file_name); + if (stat(file_name, &statbuf) < 0) { + return (0); + } + + /* If directory, read the directory */ + else if (S_ISDIR(statbuf.st_mode)) { + return (read_sys_dir(file_name)); + } + + return (0); +} + +int read_sys_dir(char *dir_name) +{ + DIR *dp; + struct dirent *entry; + struct stat statbuf; + + /* Get the number of nodes. The total number on opendir + * must be the same. + */ + if (stat(dir_name, &statbuf) < 0) { + return (-1); + } + + /* Must be a directory */ + if (!S_ISDIR(statbuf.st_mode)) { + return (-1); + } + + /* Open the directory given */ + dp = opendir(dir_name); + if (!dp) { + return (-1); + } + + /* Read every entry in the directory */ + while ((entry = readdir(dp)) != NULL) { + char f_name[MAX_PATH + 2]; + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + /* Create new file + path string */ + snprintf(f_name, MAX_PATH + 1, "%s\\%s", dir_name, entry->d_name); + + read_sys_file(f_name); + } + + closedir(dp); + + return (0); +} + +int main(int argc, char **argv) +{ + printf("%s: NTFS ADS dumper (GPL v2)\n", argv[0]); + printf("by Daniel B. Cid - dcid at theopenarmor.org\n\n"); + + /* Print every NTFS ADS found */ + if (argc < 2) { + printf("%s dir\n", argv[0]); + exit(1); + } + + /* Get streams */ + read_sys_file(argv[1]); + + if (ads_found == 0) { + printf("No NTFS ADS found.\n"); + } + return (0); +} + diff --git a/src/rootcheck/win-common.c b/src/rootcheck/win-common.c new file mode 100644 index 000000000..ad9a09638 --- /dev/null +++ b/src/rootcheck/win-common.c @@ -0,0 +1,364 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "rootcheck.h" + +#ifdef WIN32 + +/* Global variables */ +HKEY rk_sub_tree; + +/* Default values */ +#define MAX_KEY_LENGTH 255 +#define MAX_KEY 2048 +#define MAX_VALUE_NAME 16383 + + +/* Check if file has NTFS ADS */ +int os_check_ads(const char *full_path) +{ + HANDLE file_h; + WIN32_STREAM_ID sid; + void *context = NULL; + char stream_name[MAX_PATH + 1]; + char final_name[MAX_PATH + 1]; + DWORD dwRead, shs, dw1, dw2; + + /* Open file */ + file_h = CreateFile(full_path, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, + NULL); + + if (file_h == INVALID_HANDLE_VALUE) { + return 0; + } + + /* Zero memory */ + ZeroMemory(&sid, sizeof(WIN32_STREAM_ID)); + + /* Get stream header size -- should be 20 bytes */ + shs = (LPBYTE)&sid.cStreamName - (LPBYTE)&sid + sid.dwStreamNameSize; + + while (1) { + if (BackupRead(file_h, (LPBYTE) &sid, shs, &dwRead, + FALSE, FALSE, &context) == 0) { + break; + } + if (dwRead == 0) { + break; + } + + stream_name[0] = '\0'; + stream_name[MAX_PATH] = '\0'; + if (BackupRead(file_h, (LPBYTE)stream_name, + sid.dwStreamNameSize, + &dwRead, FALSE, FALSE, &context)) { + if (dwRead != 0) { + DWORD i = 0; + int max_path_size = 0; + char *tmp_pt; + char op_msg[OS_SIZE_1024 + 1]; + + snprintf(final_name, MAX_PATH, "%s", full_path); + max_path_size = strlen(final_name); + + /* Copy from wide char to char */ + while ((i < dwRead) && (max_path_size < MAX_PATH)) { + if (stream_name[i] != 0) { + final_name[max_path_size] = stream_name[i]; + max_path_size++; + final_name[max_path_size] = '\0'; + } + i++; + } + + tmp_pt = strrchr(final_name, ':'); + if (tmp_pt) { + *tmp_pt = '\0'; + } + + snprintf(op_msg, OS_SIZE_1024, "NTFS Alternate data stream " + "found: '%s'. Possible hidden" + " content.", + final_name); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); + } + } + + /* Get next */ + if (!BackupSeek(file_h, sid.Size.LowPart, sid.Size.HighPart, + &dw1, &dw2, &context)) { + break; + } + } + + CloseHandle(file_h); + return (0); +} + +/* Get registry high level key */ +char *__os_winreg_getkey(char *reg_entry) +{ + char *ret = NULL; + char *tmp_str; + + /* Get only the sub tree first */ + tmp_str = strchr(reg_entry, '\\'); + if (tmp_str) { + *tmp_str = '\0'; + ret = tmp_str + 1; + } + + /* Set sub tree */ + if ((strcmp(reg_entry, "HKEY_LOCAL_MACHINE") == 0) || + (strcmp(reg_entry, "HKLM") == 0)) { + rk_sub_tree = HKEY_LOCAL_MACHINE; + } else if (strcmp(reg_entry, "HKEY_CLASSES_ROOT") == 0) { + rk_sub_tree = HKEY_CLASSES_ROOT; + } else if (strcmp(reg_entry, "HKEY_CURRENT_CONFIG") == 0) { + rk_sub_tree = HKEY_CURRENT_CONFIG; + } else if (strcmp(reg_entry, "HKEY_USERS") == 0) { + rk_sub_tree = HKEY_USERS; + } else if ((strcmp(reg_entry, "HKCU") == 0) || + (strcmp(reg_entry, "HKEY_CURRENT_USER") == 0)) { + rk_sub_tree = HKEY_CURRENT_USER; + } else { + /* Set sub tree to null */ + rk_sub_tree = NULL; + + /* Return tmp_str to the previous value */ + if (tmp_str && (*tmp_str == '\0')) { + *tmp_str = '\\'; + } + return (NULL); + } + + /* Check if ret has nothing else */ + if (ret && (*ret == '\0')) { + ret = NULL; + } + + /* Fixing tmp_str and the real name of the registry */ + if (tmp_str && (*tmp_str == '\0')) { + *tmp_str = '\\'; + } + + return (ret); +} + +/* Query the key and get the value of a specific entry */ +int __os_winreg_querykey(HKEY hKey, + __attribute__((unused))char *p_key, + __attribute__((unused)) char *full_key_name, + char *reg_option, char *reg_value) +{ + int rc; + DWORD i, j; + + /* QueryInfo and EnumKey variables */ + TCHAR class_name_b[MAX_PATH + 1]; + DWORD class_name_s = MAX_PATH; + + /* Number of sub keys */ + DWORD subkey_count = 0; + + /* Number of values */ + DWORD value_count; + + /* Variables for RegEnumValue */ + TCHAR value_buffer[MAX_VALUE_NAME + 1]; + TCHAR data_buffer[MAX_VALUE_NAME + 1]; + DWORD value_size; + DWORD data_size; + + /* Data type for RegEnumValue */ + DWORD data_type = 0; + + /* Storage var */ + char var_storage[MAX_VALUE_NAME + 1]; + + /* Initialize the memory for some variables */ + class_name_b[0] = '\0'; + class_name_b[MAX_PATH] = '\0'; + + /* We use the class_name, subkey_count and the value count */ + rc = RegQueryInfoKey(hKey, class_name_b, &class_name_s, NULL, + &subkey_count, NULL, NULL, &value_count, + NULL, NULL, NULL, NULL); + if (rc != ERROR_SUCCESS) { + return (0); + } + + /* Get values (if available) */ + if (value_count) { + char *mt_data; + + /* Clear the values for value_size and data_size */ + value_buffer[MAX_VALUE_NAME] = '\0'; + data_buffer[MAX_VALUE_NAME] = '\0'; + var_storage[MAX_VALUE_NAME] = '\0'; + + /* Get each value */ + for (i = 0; i < value_count; i++) { + value_size = MAX_VALUE_NAME; + data_size = MAX_VALUE_NAME; + + value_buffer[0] = '\0'; + data_buffer[0] = '\0'; + var_storage[0] = '\0'; + + rc = RegEnumValue(hKey, i, value_buffer, &value_size, + NULL, &data_type, (LPBYTE)data_buffer, &data_size); + + /* No more values available */ + if (rc != ERROR_SUCCESS) { + break; + } + + /* Check if no value name is specified */ + if (value_buffer[0] == '\0') { + value_buffer[0] = '@'; + value_buffer[1] = '\0'; + } + + /* Check if the entry name matches the reg_option */ + if (strcasecmp(value_buffer, reg_option) != 0) { + continue; + } + + /* If a value is not present and the option matches, + * we can return ok + */ + if (!reg_value) { + return (1); + } + + /* Write value into a string */ + switch (data_type) { + int size_available; + + case REG_SZ: + case REG_EXPAND_SZ: + snprintf(var_storage, MAX_VALUE_NAME, "%s", data_buffer); + break; + case REG_MULTI_SZ: + /* Printing multiple strings */ + size_available = MAX_VALUE_NAME - 3; + mt_data = data_buffer; + + while (*mt_data) { + if (size_available > 2) { + strncat(var_storage, mt_data, size_available); + strncat(var_storage, " ", 2); + size_available = MAX_VALUE_NAME - + (strlen(var_storage) + 2); + } + mt_data += strlen(mt_data) + 1; + } + + break; + case REG_DWORD: + snprintf(var_storage, MAX_VALUE_NAME, + "%x", (unsigned int)*data_buffer); + break; + default: + size_available = MAX_VALUE_NAME - 2; + for (j = 0; j < data_size; j++) { + char tmp_c[12]; + + snprintf(tmp_c, 12, "%02x", + (unsigned int)data_buffer[j]); + + if (size_available > 2) { + strncat(var_storage, tmp_c, size_available); + size_available = MAX_VALUE_NAME - + (strlen(var_storage) + 2); + } + } + break; + } + + /* Check if value matches */ + if (pt_matches(var_storage, reg_value)) { + return (1); + } + + return (0); + } + } + + return (0); +} + +/* Open the registry key */ +int __os_winreg_open_key(char *subkey, char *full_key_name, + char *reg_option, char *reg_value) +{ + int ret = 1; + HKEY oshkey; + + int REG64MASK = (KEY_READ | KEY_WOW64_64KEY); + int REG32MASK = (KEY_READ | KEY_WOW64_32KEY); + + if((RegOpenKeyEx(rk_sub_tree, subkey, 0, REG64MASK, &oshkey) || + (RegOpenKeyEx(rk_sub_tree, subkey, 0, REG32MASK, &oshkey)) + ) != ERROR_SUCCESS) + { + return(0); + } + + /* If option is set, return the value of query key */ + if (reg_option) { + ret = __os_winreg_querykey(oshkey, subkey, full_key_name, + reg_option, reg_value); + } + + RegCloseKey(oshkey); + return (ret); +} + +/* Check if the entry is present in the registry */ +int is_registry(char *entry_name, char *reg_option, char *reg_value) +{ + char *rk; + + rk = __os_winreg_getkey(entry_name); + if (rk_sub_tree == NULL || rk == NULL) { + merror(SK_INV_REG, ARGV0, entry_name); + return (0); + } + + if (__os_winreg_open_key(rk, entry_name, reg_option, reg_value) == 0) { + return (0); + } + + return (1); +} + +#else + +/* Non-Windows defs */ +int os_check_ads(__attribute__((unused)) const char *full_path) +{ + return (0); +} +int is_registry(__attribute__((unused)) char *entry_name, + __attribute__((unused)) char *reg_option, + __attribute__((unused)) char *reg_value) +{ + return (0); +} + +#endif /* !WIN32 */ + diff --git a/src/rootcheck/win-process.c b/src/rootcheck/win-process.c new file mode 100644 index 000000000..f6d50e761 --- /dev/null +++ b/src/rootcheck/win-process.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifdef WIN32 +#include "shared.h" +#include "rootcheck.h" + +#include +#include + + +/* Set Debug privilege + * See: "How to obtain a handle to any process with SeDebugPrivilege" + * http://support.microsoft.com/kb/131065/en-us + */ +int os_win32_setdebugpriv(HANDLE h, int en) +{ + TOKEN_PRIVILEGES tp; + TOKEN_PRIVILEGES tpPrevious; + LUID luid; + DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES); + + if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { + return (0); + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = 0; + + AdjustTokenPrivileges(h, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), + &tpPrevious, &cbPrevious); + + if (GetLastError() != ERROR_SUCCESS) { + return (0); + } + + tpPrevious.PrivilegeCount = 1; + tpPrevious.Privileges[0].Luid = luid; + + /* If en is set to true, we enable the privilege */ + if (en) { + tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED); + } else { + tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & + tpPrevious.Privileges[0].Attributes); + } + + AdjustTokenPrivileges(h, FALSE, &tpPrevious, cbPrevious, NULL, NULL); + if (GetLastError() != ERROR_SUCCESS) { + return (0); + } + + return (1); +} + +/* Get list of win32 processes */ +OSList *os_get_process_list() +{ + OSList *p_list = NULL; + HANDLE hsnap; + HANDLE hpriv; + PROCESSENTRY32 p_entry; + p_entry.dwSize = sizeof(PROCESSENTRY32); + + /* Get token to enable Debug privilege */ + if (!OpenThreadToken(GetCurrentThread(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hpriv)) { + if (GetLastError() == ERROR_NO_TOKEN) { + if (!ImpersonateSelf(SecurityImpersonation)) { + merror("%s: ERROR: os_get_win32_process_list -> " + "ImpersonateSelf", ARGV0); + return (NULL); + } + + if (!OpenThreadToken(GetCurrentThread(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + FALSE, &hpriv)) { + merror("%s: ERROR: os_get_win32_process_list -> " + "OpenThread", ARGV0); + return (NULL) ; + } + } else { + merror("%s: ERROR: os_get_win32_process_list -> OpenThread", ARGV0); + return (NULL); + } + } + + /* Enable debug privilege */ + if (!os_win32_setdebugpriv(hpriv, 1)) { + merror("%s: ERROR: os_win32_setdebugpriv", ARGV0); + CloseHandle(hpriv); + return (NULL); + } + + /* Make a snapshot of every process */ + hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hsnap == INVALID_HANDLE_VALUE) { + merror("%s: ERROR: CreateToolhelp32Snapshot", ARGV0); + return (NULL); + } + + /* Get first and second processes -- system entries */ + if (!Process32First(hsnap, &p_entry) && !Process32Next(hsnap, &p_entry )) { + merror("%s: ERROR: Process32First", ARGV0); + CloseHandle(hsnap); + return (NULL); + } + + /* Create process list */ + p_list = OSList_Create(); + if (!p_list) { + CloseHandle(hsnap); + merror(LIST_ERROR, ARGV0); + return (0); + } + + /* Get each process name and path */ + while (Process32Next( hsnap, &p_entry)) { + char *p_name; + char *p_path; + Proc_Info *p_info; + + /* Set process name */ + os_strdup(p_entry.szExeFile, p_name); + + /* Get additional information from modules */ + HANDLE hmod = INVALID_HANDLE_VALUE; + MODULEENTRY32 m_entry; + m_entry.dwSize = sizeof(MODULEENTRY32); + + /* Snapshot of the process */ + hmod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, p_entry.th32ProcessID); + + if (hmod == INVALID_HANDLE_VALUE) { + os_strdup(p_name, p_path); + } else if (!Module32First(hmod, &m_entry)) { + /* Get executable path (first entry in the module list) */ + CloseHandle(hmod); + os_strdup(p_name, p_path); + } else { + os_strdup(m_entry.szExePath, p_path); + CloseHandle(hmod); + } + + os_calloc(1, sizeof(Proc_Info), p_info); + p_info->p_name = p_name; + p_info->p_path = p_path; + OSList_AddData(p_list, p_info); + } + + /* Remove debug privileges */ + os_win32_setdebugpriv(hpriv, 0); + + CloseHandle(hsnap); + return (p_list); +} + +#endif /* WIN32 */ + diff --git a/src/shared/agent_op.c b/src/shared/agent_op.c new file mode 100644 index 000000000..ad07e33f2 --- /dev/null +++ b/src/shared/agent_op.c @@ -0,0 +1,245 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "agent_op.h" +#include "shared.h" + + +/* Check if syscheck is to be executed/restarted + * Returns 1 on success or 0 on failure (shouldn't be executed now) + */ +int os_check_restart_syscheck() +{ + /* If the restart is not present, return 0 */ + if (isChroot()) { + if (unlink(SYSCHECK_RESTART) == -1) { + return (0); + } + } else { + if (unlink(SYSCHECK_RESTART_PATH) == -1) { + return (0); + } + } + + return (1); +} + +/* Set syscheck to be restarted + * Returns 1 on success or 0 on failure + */ +int os_set_restart_syscheck() +{ + FILE *fp; + + fp = fopen(SYSCHECK_RESTART, "w"); + if (!fp) { + merror(FOPEN_ERROR, __local_name, SYSCHECK_RESTART, errno, strerror(errno)); + return (0); + } + + fprintf(fp, "%s\n", SYSCHECK_RESTART); + fclose(fp); + + return (1); +} + +/* Read the agent name for the current agent + * Returns NULL on error + */ +char *os_read_agent_name() +{ + char buf[1024 + 1]; + FILE *fp = NULL; + + debug2("%s: calling os_read_agent_name().", __local_name); + + if (isChroot()) { + fp = fopen(AGENT_INFO_FILE, "r"); + } else { + fp = fopen(AGENT_INFO_FILEP, "r"); + } + + /* We give 1 second for the file to be created */ + if (!fp) { + sleep(1); + + if (isChroot()) { + fp = fopen(AGENT_INFO_FILE, "r"); + } else { + fp = fopen(AGENT_INFO_FILEP, "r"); + } + } + + if (!fp) { + debug1(FOPEN_ERROR, __local_name, AGENT_INFO_FILE, errno, strerror(errno)); + return (NULL); + } + + buf[1024] = '\0'; + + /* Get name */ + if (fgets(buf, 1024, fp)) { + char *ret = NULL; + int len; + + // strip the newlines + len = strlen(buf) - 1; + while (len > 0 && buf[len] == '\n') + buf[len--] = '\0'; + + os_strdup(buf, ret); + fclose(fp); + + debug2("%s: os_read_agent_name returned (%s).", __local_name, ret); + + return (ret); + } + + fclose(fp); + return (NULL); +} + +/* Read the agent ip for the current agent + * Returns NULL on error + */ +char *os_read_agent_ip() +{ + char buf[1024 + 1]; + FILE *fp; + + debug2("%s: calling os_read_agent_ip().", __local_name); + + fp = fopen(AGENT_INFO_FILE, "r"); + if (!fp) { + merror(FOPEN_ERROR, __local_name, AGENT_INFO_FILE, errno, strerror(errno)); + return (NULL); + } + + buf[1024] = '\0'; + + /* Get IP */ + if (fgets(buf, 1024, fp) && fgets(buf, 1024, fp)) { + char *ret = NULL; + os_strdup(buf, ret); + fclose(fp); + + return (ret); + } + + fclose(fp); + return (NULL); +} + +/* Read the agent id for the current agent + * Returns NULL on error + */ +char *os_read_agent_id() +{ + char buf[1024 + 1]; + FILE *fp; + + debug2("%s: calling os_read_agent_id().", __local_name); + + fp = fopen(AGENT_INFO_FILE, "r"); + if (!fp) { + merror(FOPEN_ERROR, __local_name, AGENT_INFO_FILE, errno, strerror(errno)); + return (NULL); + } + + buf[1024] = '\0'; + + /* Get id */ + if (fgets(buf, 1024, fp) && fgets(buf, 1024, fp) && fgets(buf, 1024, fp)) { + char *ret = NULL; + os_strdup(buf, ret); + fclose(fp); + + return (ret); + } + + fclose(fp); + return (NULL); +} + +/* Read the agent profile name for the current agent + * Returns NULL on error + * + * Description: + * Comma separated list of strings that used to identify what type + * of configuration is used for this agent. + * The profile name is set in the agent's etc/openarmor.conf file + * It is matched with the openarmor manager's agent.conf file to read + * configuration only applicable to this profile name. + */ +char *os_read_agent_profile() +{ + char buf[1024 + 1]; + FILE *fp; + + debug2("%s: calling os_read_agent_profile().", __local_name); + + if (isChroot()) { + fp = fopen(AGENT_INFO_FILE, "r"); + } else { + fp = fopen(AGENT_INFO_FILEP, "r"); + } + + if (!fp) { + debug2("%s: Failed to open file. Errno=%d.", __local_name, errno); + merror(FOPEN_ERROR, __local_name, AGENT_INFO_FILE, errno, strerror(errno)); + return (NULL); + } + + buf[1024] = '\0'; + + /* Get profile */ + if (fgets(buf, 1024, fp) && fgets(buf, 1024, fp) && + fgets(buf, 1024, fp) && fgets(buf, 1024, fp)) { + char *ret = NULL; + + /* Trim the /n and/or /r at the end of the string */ + os_trimcrlf(buf); + + os_strdup(buf, ret); + debug2("%s: os_read_agent_profile() = [%s]", __local_name, ret); + + fclose(fp); + + return (ret); + } + + fclose(fp); + return (NULL); +} + +/* Write the agent info to the queue, for the other processes to read + * Returns 1 on success or <= 0 on failure + */ +int os_write_agent_info(const char *agent_name, __attribute__((unused)) const char *agent_ip, + const char *agent_id, const char *cfg_profile_name) +{ + FILE *fp; + + fp = fopen(AGENT_INFO_FILE, "w"); + if (!fp) { + merror(FOPEN_ERROR, __local_name, AGENT_INFO_FILE, errno, strerror(errno)); + return (0); + } + + fprintf( + fp, + "%s\n-\n%s\n%s\n", + agent_name, + agent_id, + (cfg_profile_name) ? cfg_profile_name : "-" + ); + fclose(fp); + return (1); +} + diff --git a/src/shared/custom_output_search_replace.c b/src/shared/custom_output_search_replace.c new file mode 100644 index 000000000..0a844b7d7 --- /dev/null +++ b/src/shared/custom_output_search_replace.c @@ -0,0 +1,116 @@ +#include "shared.h" + + +char *searchAndReplace(const char *orig, const char *search, const char *value) +{ + char *p; + const size_t orig_len = strlen(orig); + const size_t search_len = strlen(search); + const size_t value_len = strlen(value); + + size_t inx_start; + char *tmp = NULL; + size_t tmp_offset = 0; + size_t total_bytes_allocated = 1; + size_t from; + + /* Check for any match */ + p = strstr(orig, search); + if (p == NULL) { + os_strdup(orig, tmp); + + return tmp; + } + + inx_start = (size_t) (p - orig); + from = inx_start + search_len; + + /* Copy content before first match, if any */ + if (inx_start > 0) { + total_bytes_allocated = inx_start + 1; + tmp = (char *) malloc(sizeof(char) * total_bytes_allocated); + strncpy(tmp, orig, inx_start); + tmp_offset = inx_start; + } + + while (p != NULL) { + /* Copy replacement */ + total_bytes_allocated += value_len; + os_realloc(tmp, total_bytes_allocated, tmp); + + strncpy(tmp + tmp_offset, value, value_len); + tmp_offset += value_len; + + /* Search for further occurrences */ + p = strstr(orig + inx_start + search_len, search); + if (p != NULL) { + size_t inx_start2 = (size_t) (p - orig); + + /* Copy content between matches, if any */ + if (inx_start2 > from) { + size_t gap = inx_start2 - from; + total_bytes_allocated += gap; + os_realloc(tmp, total_bytes_allocated, tmp); + strncpy(tmp + tmp_offset, orig + from, gap); + tmp_offset += gap; + } + + inx_start = inx_start2; + } + + /* Set position for copying content after last match */ + from = inx_start + search_len; + } + + /* Copy content after last match, if any */ + if ((from < orig_len) && from > 0) { + total_bytes_allocated += orig_len - from; + os_realloc(tmp, total_bytes_allocated, tmp); + strncpy(tmp + tmp_offset, orig + from, orig_len - from); + } + + tmp[total_bytes_allocated - 1] = '\0'; + + return tmp; +} + +/* Escape newline characters. Returns a new allocated string. */ +char *escape_newlines(const char *orig) +{ + const char *ptr; + char *ret, *retptr; + size_t size; + + ptr = orig; + size = 1; + while (*ptr) { + if ((*ptr == '\n') || (*ptr == '\r')) { + size += 2; + } else { + size += 1; + } + ptr++; + } + + ret = (char *) malloc (size); + ptr = orig; + retptr = ret; + while (*ptr) { + if (*ptr == '\n') { + *retptr = '\\'; + *(retptr + 1) = 'n'; + retptr += 2; + } else if (*ptr == '\r') { + *retptr = '\\'; + *(retptr + 1) = 'n'; + retptr += 2; + } else { + *retptr = *ptr; + retptr ++; + } + ptr++; + } + *retptr = '\0'; + + return ret; +} diff --git a/src/shared/debug_op.c b/src/shared/debug_op.c new file mode 100644 index 000000000..6fba81c04 --- /dev/null +++ b/src/shared/debug_op.c @@ -0,0 +1,201 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "headers/shared.h" + +static int dbg_flag = 0; +static int chroot_flag = 0; +static int daemon_flag = 0; + +static void _log(const char *msg, va_list args) __attribute__((format(printf, 1, 0))) __attribute__((nonnull)); + +#ifdef WIN32 +void WinSetError(); +#endif + +/* For internal logs */ +#ifndef LOGFILE +#ifndef WIN32 +#define LOGFILE "/logs/openarmor.log" +#else +#define LOGFILE "openarmor.log" +#endif +#endif + + +static void _log(const char *msg, va_list args) +{ + time_t tm; + struct tm *p; + va_list args2; /* For the stderr print */ + FILE *fp; + + tm = time(NULL); + p = localtime(&tm); + /* Duplicate args */ + va_copy(args2, args); + + /* If under chroot, log directly to /logs/openarmor.log */ + if (chroot_flag == 1) { + fp = fopen(LOGFILE, "a"); + } else { + char _logfile[256]; +#ifndef WIN32 + snprintf(_logfile, 256, "%s%s", DEFAULTDIR, LOGFILE); +#else + snprintf(_logfile, 256, "%s", LOGFILE); +#endif + fp = fopen(_logfile, "a"); + } + + /* Maybe log to syslog if the log file is not available */ + if (fp) { + (void)fprintf(fp, "%d/%02d/%02d %02d:%02d:%02d ", + p->tm_year + 1900, p->tm_mon + 1, + p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + (void)vfprintf(fp, msg, args); +#ifdef WIN32 + (void)fprintf(fp, "\r\n"); +#else + (void)fprintf(fp, "\n"); +#endif + fflush(fp); + fclose(fp); + } + + /* Only if not in daemon mode */ + if (daemon_flag == 0) { + /* Print to stderr */ + (void)fprintf(stderr, "%d/%02d/%02d %02d:%02d:%02d ", + p->tm_year + 1900, p->tm_mon + 1 , p->tm_mday, + p->tm_hour, p->tm_min, p->tm_sec); + (void)vfprintf(stderr, msg, args2); +#ifdef WIN32 + (void)fprintf(stderr, "\r\n"); +#else + (void)fprintf(stderr, "\n"); +#endif + } + + /* args2 must be ended here */ + va_end(args2); +} + +void debug1(const char *msg, ...) +{ + if (dbg_flag >= 1) { + va_list args; + va_start(args, msg); + + _log(msg, args); + + va_end(args); + } +} + +void debug2(const char *msg, ...) +{ + if (dbg_flag >= 2) { + va_list args; + + va_start(args, msg); + _log(msg, args); + va_end(args); + } +} + +void merror(const char *msg, ... ) +{ + va_list args; + + va_start(args, msg); + _log(msg, args); + va_end(args); +} + +void verbose(const char *msg, ... ) +{ + va_list args; + + va_start(args, msg); + _log(msg, args); + va_end(args); +} + +/* Only logs to a file */ +void log2file(const char *msg, ... ) +{ + int dbg_tmp; + va_list args; + va_start(args, msg); + + /* We set daemon flag to 1, so nothing is printed to the terminal */ + dbg_tmp = daemon_flag; + daemon_flag = 1; + _log(msg, args); + + daemon_flag = dbg_tmp; + + va_end(args); +} + +void ErrorExit(const char *msg, ...) +{ + va_list args; + +#ifdef WIN32 + /* If not MA */ +#ifndef MA + WinSetError(); +#endif +#endif + + va_start(args, msg); + _log(msg, args); + va_end(args); + + exit(1); +} + +void nowChroot() +{ + chroot_flag = 1; +} + +void nowDaemon() +{ + daemon_flag = 1; +} + +void print_out(const char *msg, ...) +{ + va_list args; + va_start(args, msg); + + /* Print to stderr */ + (void)vfprintf(stderr, msg, args); + +#ifdef WIN32 + (void)fprintf(stderr, "\r\n"); +#else + (void)fprintf(stderr, "\n"); +#endif + + va_end(args); +} + +void nowDebug() +{ + dbg_flag++; +} + +int isChroot() +{ + return (chroot_flag); +} diff --git a/src/shared/dirtree_op.c b/src/shared/dirtree_op.c new file mode 100644 index 000000000..0d6daf8df --- /dev/null +++ b/src/shared/dirtree_op.c @@ -0,0 +1,234 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common API for dealing with directory trees */ + +#include "shared.h" + +static OSDirTree *_OSTreeNode_Add(OSDirTree *tree, const char *str, + void *data, char sep) __attribute__((nonnull(2))); + + +/* Create the tree + * Returns NULL on error + */ +OSDirTree *OSDirTree_Create() +{ + OSDirTree *my_tree; + + my_tree = (OSDirTree *) calloc(1, sizeof(OSDirTree)); + if (!my_tree) { + return (NULL); + } + + my_tree->first_node = NULL; + my_tree->last_node = NULL; + + return (my_tree); +} + +/* Get first node from tree (starting from parent) + * Returns null on invalid tree (not initialized) + */ +OSTreeNode *OSDirTree_GetFirstNode(OSDirTree *tree) +{ + return (tree->first_node); +} + +/* Look for an entry in the middle of the tree + * Should not be called directly + */ +static OSDirTree *_OSTreeNode_Add(OSDirTree *tree, const char *str, + void *data, char sep) +{ + char *tmp_str; + OSTreeNode *newnode; + OSTreeNode *curnode; + + /* Look for a next entry */ + tmp_str = strchr(str, sep); + if (tmp_str) { + *tmp_str = '\0'; + } + + /* Create new tree */ + if (!tree) { + tree = (OSDirTree *) calloc(1, sizeof(OSDirTree)); + if (!tree) { + return (NULL); + } + + tree->first_node = NULL; + tree->last_node = NULL; + } + + curnode = tree->first_node; + + /* Loop over all nodes */ + while (curnode) { + if (strcmp(curnode->value, str) == 0) { + /* If we have other elements, keep going */ + if (tmp_str) { + curnode->child = _OSTreeNode_Add(curnode->child, + tmp_str + 1, data, sep); + } + break; + } + curnode = curnode->next; + } + + /* Add a new entry, if not found */ + if (!curnode) { + os_calloc(1, sizeof(OSTreeNode), newnode); + + if (!tree->first_node && !tree->last_node) { + tree->last_node = newnode; + tree->first_node = newnode; + } else { + tree->last_node->next = newnode; + } + + newnode->next = NULL; + tree->last_node = newnode; + os_strdup(str, newnode->value); + + /* If we have other elements, keep going */ + if (tmp_str) { + newnode->child = _OSTreeNode_Add(newnode->child, + tmp_str + 1, data, sep); + newnode->data = NULL; + } + /* Otherwise, set the data in here */ + else { + newnode->data = data; + newnode->child = NULL; + } + } + + /* Fix the string back */ + if (tmp_str) { + *tmp_str = sep; + } + + return (tree); +} + +/* Add a new string to the tree, setting the data at the final leaf. + * The tree will be divided by the "separator", where each token + * will delimit the child. + * For example, /etc/my/name.conf will become: + * /etc/ + * -> /my + * -> /name.conf + * Str must not be NULL. + */ +void OSDirTree_AddToTree(OSDirTree *tree, const char *str, void *data, char sep) +{ + char *tmp_str; + OSTreeNode *newnode; + OSTreeNode *curnode; + + /* First character doesn't count as a separator */ + tmp_str = strchr(str + 1, sep); + if (tmp_str) { + *tmp_str = '\0'; + } + + curnode = tree->first_node; + while (curnode) { + if (strcmp(str, curnode->value) == 0) { + /* If we have other elements, keep going */ + if (tmp_str) { + curnode->child = _OSTreeNode_Add(curnode->child, + tmp_str + 1, data, sep); + } + break; + } + + curnode = curnode->next; + } + + /* If we didn't find an entry, create one */ + if (!curnode) { + os_calloc(1, sizeof(OSTreeNode), newnode); + printf("XX Adding MAIN node: %s\n", str); + + if (!tree->first_node && !tree->last_node) { + tree->last_node = newnode; + tree->first_node = newnode; + } else { + printf("XXX last new node: %s\n", tree->last_node->value); + tree->last_node->next = newnode; + tree->last_node = newnode; + } + + newnode->next = NULL; + os_strdup(str, newnode->value); + + /* If we have other elements, keep going */ + if (tmp_str) { + newnode->child = _OSTreeNode_Add(newnode->child, + tmp_str + 1, data, sep); + newnode->data = NULL; + } + /* Otherwise, set the data in here */ + else { + newnode->data = data; + newnode->child = NULL; + } + } + + /* Fix the string back */ + if (tmp_str) { + *tmp_str = sep; + } + + return; +} + +void *OSDirTree_SearchTree(const OSDirTree *tree, const char *str, char sep) +{ + void *ret = NULL; + char *tmp_str; + const OSTreeNode *curnode; + + /* First character doesn't count as a separator */ + tmp_str = strchr(str + 1, sep); + if (tmp_str) { + *tmp_str = '\0'; + } + + printf("looking for: %s\n", str); + + /* If our tree is not empty, look for the main entry */ + curnode = tree->first_node; + while (curnode) { + printf("comparing: '%s' and '%s'\n", str, curnode->value); + if (strcmp(str, curnode->value) == 0) { + printf("found node: %s\n", str); + + /* If we have other elements, keep going */ + if (tmp_str) { + ret = OSDirTree_SearchTree(curnode->child, tmp_str + 1, sep); + } else { + ret = curnode->data; + } + break; + } + + curnode = curnode->next; + } + + /* Fix the string back */ + if (tmp_str) { + *tmp_str = sep; + } + + return (ret); +} diff --git a/src/shared/file-queue.c b/src/shared/file-queue.c new file mode 100644 index 000000000..188ad5e3d --- /dev/null +++ b/src/shared/file-queue.c @@ -0,0 +1,186 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* File monitoring functions */ + +#include "shared.h" +#include "file-queue.h" + +static void file_sleep(void); +static void GetFile_Queue(file_queue *fileq) __attribute__((nonnull)); +static int Handle_Queue(file_queue *fileq, int flags) __attribute__((nonnull)); +/* To translate between month (int) to month (char) */ +static const char *(s_month[]) = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + +static void file_sleep() +{ +#ifndef WIN32 + struct timeval fp_timeout; + + fp_timeout.tv_sec = FQ_TIMEOUT; + fp_timeout.tv_usec = 0; + + /* Wait for the select timeout */ + select(0, NULL, NULL, NULL, &fp_timeout); + +#else + /* Windows does not like select that way */ + Sleep((FQ_TIMEOUT + 2) * 1000); +#endif + + return; +} + +/* Get the file queue for that specific hour */ +static void GetFile_Queue(file_queue *fileq) +{ + /* Create the logfile name */ + fileq->file_name[0] = '\0'; + fileq->file_name[MAX_FQUEUE] = '\0'; + + if (fileq->flags & CRALERT_FP_SET) { + snprintf(fileq->file_name, MAX_FQUEUE, + ""); + } else { + snprintf(fileq->file_name, MAX_FQUEUE, + "%s/%d/%s/openarmor-alerts-%02d.log", + isChroot() ? ALERTS : ALERTS_PATH, + fileq->year, + fileq->mon, + fileq->day); + } +} + +/* Re Handle the file queue */ +static int Handle_Queue(file_queue *fileq, int flags) +{ + /* Close if it is open */ + if (!(flags & CRALERT_FP_SET)) { + if (fileq->fp) { + fclose(fileq->fp); + fileq->fp = NULL; + } + + /* We must be able to open the file, fseek and get the + * time of change from it. + */ + fileq->fp = fopen(fileq->file_name, "r"); + if (!fileq->fp) { + /* Queue not available */ + return (0); + } + } + + /* Seek to the end of the file */ + if (!(flags & CRALERT_READ_ALL)) { + if (fseek(fileq->fp, 0, SEEK_END) < 0) { + merror(FSEEK_ERROR, __local_name, fileq->file_name, errno, strerror(errno)); + if (fileq->fp) { + fclose(fileq->fp); + fileq->fp = NULL; + } + return (-1); + } + } + + /* File change time */ + if (fstat(fileno(fileq->fp), &fileq->f_status) < 0) { + merror(FSTAT_ERROR, __local_name, fileq->file_name, errno, strerror(errno)); + fclose(fileq->fp); + fileq->fp = NULL; + return (-1); + } + + fileq->last_change = fileq->f_status.st_mtime; + + return (1); +} + +/* Initiates the file monitoring */ +int Init_FileQueue(file_queue *fileq, const struct tm *p, int flags) +{ + /* Initialize file_queue fields */ + if (!(flags & CRALERT_FP_SET)) { + fileq->fp = NULL; + } + fileq->last_change = 0; + fileq->flags = 0; + + fileq->day = p->tm_mday; + fileq->year = p->tm_year + 1900; + + strncpy(fileq->mon, s_month[p->tm_mon], 3); + memset(fileq->file_name, '\0', MAX_FQUEUE + 1); + + /* Set the supplied flags */ + fileq->flags = flags; + + /* Get latest file */ + GetFile_Queue(fileq); + + /* Always seek to the end when starting the queue */ + if (Handle_Queue(fileq, fileq->flags) < 0) { + return (-1); + } + + return (0); +} + +/* Reads from the monitored file */ +alert_data *Read_FileMon(file_queue *fileq, const struct tm *p, unsigned int timeout) +{ + unsigned int i = 0; + alert_data *al_data; + + /* If the file queue is not available, try to access it */ + if (!fileq->fp) { + if (Handle_Queue(fileq, 0) != 1) { + file_sleep(); + return (NULL); + } + } + + /* Get current file */ + if (p->tm_mday != fileq->day) { + /* If the day changes, get all remaining alerts */ + al_data = GetAlertData(fileq->flags, fileq->fp); + if (!al_data) { + fileq->day = p->tm_mday; + fileq->year = p->tm_year + 1900; + strncpy(fileq->mon, s_month[p->tm_mon], 3); + + /* Get latest file */ + GetFile_Queue(fileq); + + if (Handle_Queue(fileq, 0) != 1) { + file_sleep(); + return (NULL); + } + } else { + return (al_data); + } + } + + /* Try up to timeout times to get an event */ + while (i < timeout) { + al_data = GetAlertData(fileq->flags, fileq->fp); + if (al_data) { + return (al_data); + } + + i++; + file_sleep(); + } + + /* Return NULL if timeout expires */ + return (NULL); +} diff --git a/src/shared/file_op.c b/src/shared/file_op.c new file mode 100644 index 000000000..f6058486a --- /dev/null +++ b/src/shared/file_op.c @@ -0,0 +1,1604 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions to handle operation with files + */ + +#include +#include +#include +#include "shared.h" + +#ifndef WIN32 +#include +#else +#include +#endif + +/* Vista product information */ +#ifdef WIN32 +#ifndef PRODUCT_UNLICENSED +#define PRODUCT_UNLICENSED 0xABCDABCD +#endif +#ifndef PRODUCT_UNLICENSED_C +#define PRODUCT_UNLICENSED_C "Product Unlicensed " +#endif + +#ifndef PRODUCT_BUSINESS +#define PRODUCT_BUSINESS 0x00000006 +#endif +#ifndef PRODUCT_BUSINESS_C +#define PRODUCT_BUSINESS_C "Business Edition " +#endif + +#ifndef PRODUCT_BUSINESS_N +#define PRODUCT_BUSINESS_N 0x00000010 +#endif +#ifndef PRODUCT_BUSINESS_N_C +#define PRODUCT_BUSINESS_N_C "Business Edition " +#endif + +#ifndef PRODUCT_CLUSTER_SERVER +#define PRODUCT_CLUSTER_SERVER 0x00000012 +#endif +#ifndef PRODUCT_CLUSTER_SERVER_C +#define PRODUCT_CLUSTER_SERVER_C "Cluster Server Edition " +#endif + +#ifndef PRODUCT_DATACENTER_SERVER +#define PRODUCT_DATACENTER_SERVER 0x00000008 +#endif +#ifndef PRODUCT_DATACENTER_SERVER_C +#define PRODUCT_DATACENTER_SERVER_C "Datacenter Edition (full) " +#endif + +#ifndef PRODUCT_DATACENTER_SERVER_CORE +#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C +#endif +#ifndef PRODUCT_DATACENTER_SERVER_CORE_C +#define PRODUCT_DATACENTER_SERVER_CORE_C "Datacenter Edition (core) " +#endif + +#ifndef PRODUCT_DATACENTER_SERVER_CORE_V +#define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027 +#endif +#ifndef PRODUCT_DATACENTER_SERVER_CORE_V_C +#define PRODUCT_DATACENTER_SERVER_CORE_V_C "Datacenter Edition (core) " +#endif + +#ifndef PRODUCT_DATACENTER_SERVER_V +#define PRODUCT_DATACENTER_SERVER_V 0x00000025 +#endif +#ifndef PRODUCT_DATACENTER_SERVER_V_C +#define PRODUCT_DATACENTER_SERVER_V_C "Datacenter Edition (full) " +#endif + +#ifndef PRODUCT_ENTERPRISE +#define PRODUCT_ENTERPRISE 0x00000004 +#endif +#ifndef PRODUCT_ENTERPRISE_C +#define PRODUCT_ENTERPRISE_C "Enterprise Edition " +#endif + +#ifndef PRODUCT_ENTERPRISE_N +#define PRODUCT_ENTERPRISE_N 0x0000001B +#endif +#ifndef PRODUCT_ENTERPRISE_N_C +#define PRODUCT_ENTERPRISE_N_C "Enterprise Edition " +#endif + +#ifndef PRODUCT_ENTERPRISE_SERVER +#define PRODUCT_ENTERPRISE_SERVER 0x0000000A +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_C +#define PRODUCT_ENTERPRISE_SERVER_C "Enterprise Edition (full) " +#endif + +#ifndef PRODUCT_ENTERPRISE_SERVER_CORE +#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_CORE_C +#define PRODUCT_ENTERPRISE_SERVER_CORE_C "Enterprise Edition (core) " +#endif + +#ifndef PRODUCT_ENTERPRISE_SERVER_CORE_V +#define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029 +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_CORE_V_C +#define PRODUCT_ENTERPRISE_SERVER_CORE_V_C "Enterprise Edition (core) " +#endif + +#ifndef PRODUCT_ENTERPRISE_SERVER_IA64 +#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_IA64_C +#define PRODUCT_ENTERPRISE_SERVER_IA64_C "Enterprise Edition for Itanium-based Systems " +#endif + +#ifndef PRODUCT_ENTERPRISE_SERVER_V +#define PRODUCT_ENTERPRISE_SERVER_V 0x00000026 +#endif +#ifndef PRODUCT_ENTERPRISE_SERVER_V_C +#define PRODUCT_ENTERPRISE_SERVER_V_C "Enterprise Edition (full) " +#endif + +#ifndef PRODUCT_HOME_BASIC +#define PRODUCT_HOME_BASIC 0x00000002 +#endif +#ifndef PRODUCT_HOME_BASIC_C +#define PRODUCT_HOME_BASIC_C "Home Basic Edition " +#endif + +#ifndef PRODUCT_HOME_BASIC_N +#define PRODUCT_HOME_BASIC_N 0x00000005 +#endif +#ifndef PRODUCT_HOME_BASIC_N_C +#define PRODUCT_HOME_BASIC_N_C "Home Basic Edition " +#endif + +#ifndef PRODUCT_HOME_PREMIUM +#define PRODUCT_HOME_PREMIUM 0x00000003 +#endif +#ifndef PRODUCT_HOME_PREMIUM_C +#define PRODUCT_HOME_PREMIUM_C "Home Premium Edition " +#endif + +#ifndef PRODUCT_HOME_PREMIUM_N +#define PRODUCT_HOME_PREMIUM_N 0x0000001A +#endif +#ifndef PRODUCT_HOME_PREMIUM_N_C +#define PRODUCT_HOME_PREMIUM_N_C "Home Premium Edition " +#endif + +#ifndef PRODUCT_HOME_SERVER +#define PRODUCT_HOME_SERVER 0x00000013 +#endif +#ifndef PRODUCT_HOME_SERVER_C +#define PRODUCT_HOME_SERVER_C "Home Server Edition " +#endif + +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT +#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E +#endif +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C +#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C "Essential Business Server Management Server " +#endif + +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING +#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020 +#endif +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C +#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C "Essential Business Server Messaging Server " +#endif + +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY +#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F +#endif +#ifndef PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C +#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C "Essential Business Server Security Server " +#endif + +#ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS +#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 +#endif +#ifndef PRODUCT_SERVER_FOR_SMALLBUSINESS_C +#define PRODUCT_SERVER_FOR_SMALLBUSINESS_C "Small Business Edition " +#endif + +#ifndef PRODUCT_SMALLBUSINESS_SERVER +#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 +#endif +#ifndef PRODUCT_SMALLBUSINESS_SERVER_C +#define PRODUCT_SMALLBUSINESS_SERVER_C "Small Business Server " +#endif + +#ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 +#endif +#ifndef PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C "Small Business Server Premium Edition " +#endif + +#ifndef PRODUCT_STANDARD_SERVER +#define PRODUCT_STANDARD_SERVER 0x00000007 +#endif +#ifndef PRODUCT_STANDARD_SERVER_C +#define PRODUCT_STANDARD_SERVER_C "Standard Edition " +#endif + +#ifndef PRODUCT_STANDARD_SERVER_CORE +#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D +#endif +#ifndef PRODUCT_STANDARD_SERVER_CORE_C +#define PRODUCT_STANDARD_SERVER_CORE_C "Standard Edition (core) " +#endif + +#ifndef PRODUCT_STANDARD_SERVER_CORE_V +#define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028 +#endif +#ifndef PRODUCT_STANDARD_SERVER_CORE_V_C +#define PRODUCT_STANDARD_SERVER_CORE_V_C "Standard Edition " +#endif + +#ifndef PRODUCT_STANDARD_SERVER_V +#define PRODUCT_STANDARD_SERVER_V 0x00000024 +#endif +#ifndef PRODUCT_STANDARD_SERVER_V_C +#define PRODUCT_STANDARD_SERVER_V_C "Standard Edition " +#endif + +#ifndef PRODUCT_STARTER +#define PRODUCT_STARTER 0x0000000B +#endif +#ifndef PRODUCT_STARTER_C +#define PRODUCT_STARTER_C "Starter Edition " +#endif + +#ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER +#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 +#endif +#ifndef PRODUCT_STORAGE_ENTERPRISE_SERVER_C +#define PRODUCT_STORAGE_ENTERPRISE_SERVER_C "Storage Server Enterprise Edition " +#endif + +#ifndef PRODUCT_STORAGE_EXPRESS_SERVER +#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 +#endif +#ifndef PRODUCT_STORAGE_EXPRESS_SERVER_C +#define PRODUCT_STORAGE_EXPRESS_SERVER_C "Storage Server Express Edition " +#endif + +#ifndef PRODUCT_STORAGE_STANDARD_SERVER +#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 +#endif +#ifndef PRODUCT_STORAGE_STANDARD_SERVER_C +#define PRODUCT_STORAGE_STANDARD_SERVER_C "Storage Server Standard Edition " +#endif + +#ifndef PRODUCT_STORAGE_WORKGROUP_SERVER +#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 +#endif +#ifndef PRODUCT_STORAGE_WORKGROUP_SERVER_C +#define PRODUCT_STORAGE_WORKGROUP_SERVER_C "Storage Server Workgroup Edition " +#endif + +#ifndef PRODUCT_ULTIMATE +#define PRODUCT_ULTIMATE 0x00000001 +#endif +#ifndef PRODUCT_ULTIMATE_C +#define PRODUCT_ULTIMATE_C "Ultimate Edition " +#endif + +#ifndef PRODUCT_ULTIMATE_N +#define PRODUCT_ULTIMATE_N 0x0000001C +#endif +#ifndef PRODUCT_ULTIMATE_N_C +#define PRODUCT_ULTIMATE_N_C "Ultimate Edition " +#endif + +#ifndef PRODUCT_WEB_SERVER +#define PRODUCT_WEB_SERVER 0x00000011 +#endif +#ifndef PRODUCT_WEB_SERVER_C +#define PRODUCT_WEB_SERVER_C "Web Server Edition " +#endif + +#ifndef PRODUCT_WEB_SERVER_CORE +#define PRODUCT_WEB_SERVER_CORE 0x0000001D +#endif +#ifndef PRODUCT_WEB_SERVER_CORE_C +#define PRODUCT_WEB_SERVER_CORE_C "Web Server Edition " +#endif +#endif /* WIN32 */ + +#ifdef WIN32 +#define mkstemp(x) 0 +#endif + +const char *__local_name = "unset"; + +/* Set the name of the starting program */ +void OS_SetName(const char *name) +{ + __local_name = name; + return; +} + +time_t File_DateofChange(const char *file) +{ + struct stat file_status; + + if (stat(file, &file_status) < 0) { + return (-1); + } + + return (file_status.st_mtime); +} + +int IsDir(const char *file) +{ + struct stat file_status; + if (stat(file, &file_status) < 0) { + return (-1); + } + if (S_ISDIR(file_status.st_mode)) { + return (0); + } + return (-1); +} + +int CreatePID(const char *name, int pid) +{ + char file[256]; + FILE *fp; + + if (isChroot()) { + snprintf(file, 255, "%s/%s-%d.pid", OS_PIDFILE, name, pid); + } else { + snprintf(file, 255, "%s%s/%s-%d.pid", DEFAULTDIR, + OS_PIDFILE, name, pid); + } + + fp = fopen(file, "a"); + if (!fp) { + return (-1); + } + + fprintf(fp, "%d\n", pid); + + if (chmod(file, 0640) != 0) { + fclose(fp); + return (-1); + } + + fclose(fp); + + return (0); +} + +char *GetRandomNoise() +{ + FILE *fp; + char buf[2048 + 1]; + size_t frr = 0; + + /* Reading urandom */ + fp = fopen("/dev/urandom", "r"); + if(!fp) + { + return(NULL); + } + + buf[2048] = '\0'; + frr = fread(buf, 1, 2048, fp); + if(frr == 0) { + merror("ERROR: GetRandomNoise() fread() returned 0."); + fclose(fp); + return(NULL); + } + buf[2048] = '\0'; + fclose(fp); + return(strdup(buf)); +} + +int DeletePID(const char *name) +{ + char file[256]; + + if (isChroot()) { + snprintf(file, 255, "%s/%s-%d.pid", OS_PIDFILE, name, (int)getpid()); + } else { + snprintf(file, 255, "%s%s/%s-%d.pid", DEFAULTDIR, + OS_PIDFILE, name, (int)getpid()); + } + + if (File_DateofChange(file) < 0) { + return (-1); + } + + if (unlink(file)) { + log2file( + DELETE_ERROR, + __local_name, + file, + errno, + strerror(errno) + ); + } + + return (0); +} + +int UnmergeFiles(const char *finalpath, const char *optdir) +{ + int ret = 1; + size_t i = 0, n = 0, files_size = 0; + char *files; + char final_name[2048 + 1]; + char buf[2048 + 1]; + FILE *fp; + FILE *finalfp; + + finalfp = fopen(finalpath, "r"); + if (!finalfp) { + merror("%s: ERROR: Unable to read merged file: '%s'.", + __local_name, finalpath); + return (0); + } + + while (1) { + /* Read header portion */ + if (fgets(buf, sizeof(buf) - 1, finalfp) == NULL) { + break; + } + + /* Initiator */ + if (buf[0] != '!') { + continue; + } + + /* Get file size and name */ + files_size = (size_t) atol(buf + 1); + + files = strchr(buf, '\n'); + if (files) { + *files = '\0'; + } + + files = strchr(buf, ' '); + if (!files) { + ret = 0; + continue; + } + files++; + + if (optdir) { + snprintf(final_name, 2048, "%s/%s", optdir, files); + } else { + strncpy(final_name, files, 2048); + final_name[2048] = '\0'; + } + + /* Open filename */ + fp = fopen(final_name, "w"); + if (!fp) { + ret = 0; + merror("%s: ERROR: Unable to unmerge file '%s': %s", + __local_name, final_name, strerror(errno)); + } + + if (files_size < sizeof(buf) - 1) { + i = files_size; + files_size = 0; + } else { + i = sizeof(buf) - 1; + files_size -= sizeof(buf) - 1; + } + + while ((n = fread(buf, 1, i, finalfp)) > 0) { + buf[n] = '\0'; + + if (fp) { + fwrite(buf, n, 1, fp); + } + + if (files_size == 0) { + break; + } else { + if (files_size < sizeof(buf) - 1) { + i = files_size; + files_size = 0; + } else { + i = sizeof(buf) - 1; + files_size -= sizeof(buf) - 1; + } + } + } + + if (fp) { + fclose(fp); + } + } + + fclose(finalfp); + return (ret); +} + +int MergeAppendFile(const char *finalpath, const char *files) +{ + size_t n = 0; + long files_size = 0; + char buf[2048 + 1]; + const char *tmpfile; + FILE *fp; + FILE *finalfp; + + /* Create a new entry */ + if (files == NULL) { + finalfp = fopen(finalpath, "w"); + if (!finalfp) { + merror("%s: ERROR: Unable to create merged file: '%s'.", + __local_name, finalpath); + return (0); + } + fclose(finalfp); + + return (1); + } + + finalfp = fopen(finalpath, "a"); + if (!finalfp) { + merror("%s: ERROR: Unable to append merged file: '%s'.", + __local_name, finalpath); + return (0); + } + + fp = fopen(files, "r"); + if (!fp) { + merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files); + fclose(finalfp); + return (0); + } + + fseek(fp, 0, SEEK_END); + files_size = ftell(fp); + + tmpfile = strrchr(files, '/'); + if (tmpfile) { + tmpfile++; + } else { + tmpfile = files; + } + fprintf(finalfp, "!%ld %s\n", files_size, tmpfile); + + fseek(fp, 0, SEEK_SET); + + while ((n = fread(buf, 1, sizeof(buf) - 1, fp)) > 0) { + buf[n] = '\0'; + fwrite(buf, n, 1, finalfp); + } + + fclose(fp); + + fclose(finalfp); + return (1); +} + +int MergeFiles(const char *finalpath, char **files) +{ + int i = 0, ret = 1; + size_t n = 0; + long files_size = 0; + + char *tmpfile; + char buf[2048 + 1]; + FILE *fp; + FILE *finalfp; + + finalfp = fopen(finalpath, "w"); + if (!finalfp) { + merror("%s: ERROR: Unable to create merged file: '%s'.", + __local_name, finalpath); + return (0); + } + + while (files[i]) { + fp = fopen(files[i], "r"); + if (!fp) { + merror("%s: ERROR: Unable to merge file '%s'.", __local_name, files[i]); + i++; + ret = 0; + continue; + } + + fseek(fp, 0, SEEK_END); + files_size = ftell(fp); + + /* Remove last entry */ + tmpfile = strrchr(files[i], '/'); + if (tmpfile) { + tmpfile++; + } else { + tmpfile = files[i]; + } + + fprintf(finalfp, "!%ld %s\n", files_size, tmpfile); + + fseek(fp, 0, SEEK_SET); + while ((n = fread(buf, 1, sizeof(buf) - 1, fp)) > 0) { + buf[n] = '\0'; + fwrite(buf, n, 1, finalfp); + } + + fclose(fp); + i++; + } + + fclose(finalfp); + return (ret); +} + + +#ifndef WIN32 +/* Get basename of path */ +char *basename_ex(char *path) +{ + return (basename(path)); +} + +/* Rename file or directory */ +int rename_ex(const char *source, const char *destination) +{ + if (rename(source, destination)) { + log2file( + RENAME_ERROR, + __local_name, + source, + destination, + errno, + strerror(errno) + ); + + return (-1); + } + + return (0); +} + +/* Create a temporary file */ +int mkstemp_ex(char *tmp_path) +{ + int fd; + + fd = mkstemp(tmp_path); + + if (fd == -1) { + log2file( + MKSTEMP_ERROR, + __local_name, + tmp_path, + errno, + strerror(errno) + ); + + return (-1); + } + + /* mkstemp() only implicitly does this in POSIX 2008 */ + if (fchmod(fd, 0600) == -1) { + close(fd); + + log2file( + CHMOD_ERROR, + __local_name, + tmp_path, + errno, + strerror(errno) + ); + + if (unlink(tmp_path)) { + log2file( + DELETE_ERROR, + __local_name, + tmp_path, + errno, + strerror(errno) + ); + } + + return (-1); + } + + close(fd); + return (0); +} + + +/* Get uname. Memory must be freed after use */ +char *getuname() +{ + struct utsname uts_buf; + + if (uname(&uts_buf) >= 0) { + char *ret; + + ret = (char *) calloc(512, sizeof(char)); + if (ret == NULL) { + return (NULL); + } + + snprintf(ret, 511, "%s %s %s %s %s - %s %s", + uts_buf.sysname, + uts_buf.nodename, + uts_buf.release, + uts_buf.version, + uts_buf.machine, + __openarmor_name, __openarmor_version); + + return (ret); + } else { + char *ret; + ret = (char *) calloc(512, sizeof(char)); + if (ret == NULL) { + return (NULL); + } + + snprintf(ret, 511, "No system info available - %s %s", + __openarmor_name, __openarmor_version); + + return (ret); + } + + return (NULL); +} + +/* Daemonize a process without closing stdin/stdout/stderr */ +void goDaemonLight() +{ + pid_t pid; + + pid = fork(); + + if (pid < 0) { + merror(FORK_ERROR, __local_name, errno, strerror(errno)); + return; + } else if (pid) { + exit(0); + } + + /* Become session leader */ + if (setsid() < 0) { + merror(SETSID_ERROR, __local_name, errno, strerror(errno)); + return; + } + + /* Fork again */ + pid = fork(); + if (pid < 0) { + merror(FORK_ERROR, __local_name, errno, strerror(errno)); + return; + } else if (pid) { + exit(0); + } + + dup2(1, 2); + + /* Go to / */ + if (chdir("/") == -1) { + merror(CHDIR_ERROR, __local_name, "/", errno, strerror(errno)); + } + + return; +} + +/* Daemonize a process */ +void goDaemon() +{ + int fd; + pid_t pid; + + pid = fork(); + if (pid < 0) { + merror(FORK_ERROR, __local_name, errno, strerror(errno)); + return; + } else if (pid) { + exit(0); + } + + /* Become session leader */ + if (setsid() < 0) { + merror(SETSID_ERROR, __local_name, errno, strerror(errno)); + return; + } + + /* Fork again */ + pid = fork(); + if (pid < 0) { + merror(FORK_ERROR, __local_name, errno, strerror(errno)); + return; + } else if (pid) { + exit(0); + } + + /* Dup stdin, stdout and stderr to /dev/null */ + if ((fd = open("/dev/null", O_RDWR)) >= 0) { + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + + close(fd); + } + + /* Go to / */ + if (chdir("/") == -1) { + merror(CHDIR_ERROR, __local_name, "/", errno, strerror(errno)); + } + + return; +} + +#else /* WIN32 */ + +int checkVista() +{ + char *m_uname; + isVista = 0; + + m_uname = getuname(); + if (!m_uname) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (0); + } + + /* Check if the system is Vista (must be called during the startup) */ + if (strstr(m_uname, "Windows Server 2008") || + strstr(m_uname, "Vista") || + strstr(m_uname, "Windows 7") || + strstr(m_uname, "Windows 8") || + strstr(m_uname, "Windows Server 2012")) { + isVista = 1; + verbose("%s: INFO: System is Vista or newer (%s).", + __local_name, m_uname); + } else { + verbose("%s: INFO: System is older than Vista (%s).", + __local_name, m_uname); + } + + free(m_uname); + + return (isVista); +} + +/* Get basename of path */ +char *basename_ex(char *path) +{ + return (PathFindFileNameA(path)); +} + +/* Rename file or directory */ +int rename_ex(const char *source, const char *destination) +{ + if (!MoveFileEx(source, destination, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { + log2file( + "%s: ERROR: Could not move (%s) to (%s) which returned (%lu)", + __local_name, + source, + destination, + GetLastError() + ); + + return (-1); + } + + return (0); +} + +/* Create a temporary file */ +int mkstemp_ex(char *tmp_path) +{ + DWORD dwResult; + int result; + int status = -1; + + HANDLE h = NULL; + PACL pACL = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + EXPLICIT_ACCESS ea[2]; + SECURITY_ATTRIBUTES sa; + + PSID pAdminGroupSID = NULL; + PSID pSystemGroupSID = NULL; + SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY}; + +#if defined(_MSC_VER) && _MSC_VER >= 1500 + result = _mktemp_s(tmp_path, strlen(tmp_path) + 1); + + if (result != 0) { + log2file( + "%s: ERROR: Could not create temporary file (%s) which returned (%d)", + __local_name, + tmp_path, + result + ); + + return (-1); + } +#else + if (_mktemp(tmp_path) == NULL) { + log2file( + "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]", + __local_name, + tmp_path, + errno, + strerror(errno) + ); + + return (-1); + } +#endif + + /* Create SID for the BUILTIN\Administrators group */ + result = AllocateAndInitializeSid( + &SIDAuthNT, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &pAdminGroupSID + ); + + if (!result) { + log2file( + "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + /* Create SID for the SYSTEM group */ + result = AllocateAndInitializeSid( + &SIDAuthNT, + 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &pSystemGroupSID + ); + + if (!result) { + log2file( + "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + /* Initialize an EXPLICIT_ACCESS structure for an ACE */ + ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); + + /* Add Administrators group */ + ea[0].grfAccessPermissions = GENERIC_ALL; + ea[0].grfAccessMode = SET_ACCESS; + ea[0].grfInheritance = NO_INHERITANCE; + ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID; + + /* Add SYSTEM group */ + ea[1].grfAccessPermissions = GENERIC_ALL; + ea[1].grfAccessMode = SET_ACCESS; + ea[1].grfInheritance = NO_INHERITANCE; + ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID; + + /* Set entries in ACL */ + dwResult = SetEntriesInAcl(2, ea, NULL, &pACL); + + if (dwResult != ERROR_SUCCESS) { + log2file( + "%s: ERROR: Could not set ACL entries which returned (%lu)", + __local_name, + dwResult + ); + + goto cleanup; + } + + /* Initialize security descriptor */ + pSD = (PSECURITY_DESCRIPTOR)LocalAlloc( + LPTR, + SECURITY_DESCRIPTOR_MIN_LENGTH + ); + + if (pSD == NULL) { + log2file( + "%s: ERROR: Could not initialize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { + log2file( + "%s: ERROR: Could not initialize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + /* Set owner */ + if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) { + log2file( + "%s: ERROR: Could not set owner which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + /* Set group owner */ + if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) { + log2file( + "%s: ERROR: Could not set group owner which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + /* Add ACL to security descriptor */ + if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { + log2file( + "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)", + __local_name, + GetLastError() + ); + + goto cleanup; + } + + /* Initialize security attributes structure */ + sa.nLength = sizeof (SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + + h = CreateFileA( + tmp_path, + GENERIC_WRITE, + 0, + &sa, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + + if (h == INVALID_HANDLE_VALUE) { + log2file( + "%s: ERROR: Could not create temporary file (%s) which returned (%lu)", + __local_name, + tmp_path, + GetLastError() + ); + + goto cleanup; + } + + if (!CloseHandle(h)) { + log2file( + "%s: ERROR: Could not close file handle to (%s) which returned (%lu)", + __local_name, + tmp_path, + GetLastError() + ); + + goto cleanup; + } + + /* Success */ + status = 0; + +cleanup: + if (pAdminGroupSID) { + FreeSid(pAdminGroupSID); + } + + if (pSystemGroupSID) { + FreeSid(pSystemGroupSID); + } + + if (pACL) { + LocalFree(pACL); + } + + if (pSD) { + LocalFree(pSD); + } + + return (status); +} + +/* Get uname for Windows */ +char *getuname() +{ + int ret_size = OS_SIZE_1024 - 2; + char *ret = NULL; + char os_v[128 + 1]; + + typedef void (WINAPI * PGNSI)(LPSYSTEM_INFO); + typedef BOOL (WINAPI * PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); + + /* See http://msdn.microsoft.com/en-us/library/windows/desktop/ms724429%28v=vs.85%29.aspx */ + OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + PGNSI pGNSI; + PGPI pGPI; + BOOL bOsVersionInfoEx; + DWORD dwType; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if (!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi))) { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx((OSVERSIONINFO *)&osvi)) { + return (NULL); + } + } + + /* Allocate memory */ + os_calloc(OS_SIZE_1024 + 1, sizeof(char), ret); + ret[OS_SIZE_1024] = '\0'; + + switch (osvi.dwPlatformId) { + /* Test for the Windows NT product family */ + case VER_PLATFORM_WIN32_NT: + if (osvi.dwMajorVersion == 6) { + if (osvi.dwMinorVersion == 0) { + if (osvi.wProductType == VER_NT_WORKSTATION ) { + strncat(ret, "Microsoft Windows Vista ", ret_size - 1); + } else { + strncat(ret, "Microsoft Windows Server 2008 ", ret_size - 1); + } + } else if (osvi.dwMinorVersion == 1) { + if (osvi.wProductType == VER_NT_WORKSTATION ) { + strncat(ret, "Microsoft Windows 7 ", ret_size - 1); + } else { + strncat(ret, "Microsoft Windows Server 2008 R2 ", ret_size - 1); + } + } else if (osvi.dwMinorVersion == 2) { + if (osvi.wProductType == VER_NT_WORKSTATION ) { + strncat(ret, "Microsoft Windows 8 ", ret_size - 1); + } else { + strncat(ret, "Microsoft Windows Server 2012 ", ret_size - 1); + } + } else if (osvi.dwMinorVersion == 3) { + if (osvi.wProductType == VER_NT_WORKSTATION ) { + strncat(ret, "Microsoft Windows 8.1 ", ret_size - 1); + } else { + strncat(ret, "Microsoft Windows Server 2012 R2 ", ret_size - 1); + } + } + + ret_size -= strlen(ret) + 1; + + + /* Get product version */ + pGPI = (PGPI) GetProcAddress( + GetModuleHandle(TEXT("kernel32.dll")), + "GetProductInfo"); + + pGPI( 6, 0, 0, 0, &dwType); + + switch (dwType) { + case PRODUCT_UNLICENSED: + strncat(ret, PRODUCT_UNLICENSED_C, ret_size - 1); + break; + case PRODUCT_BUSINESS: + strncat(ret, PRODUCT_BUSINESS_C, ret_size - 1); + break; + case PRODUCT_BUSINESS_N: + strncat(ret, PRODUCT_BUSINESS_N_C, ret_size - 1); + break; + case PRODUCT_CLUSTER_SERVER: + strncat(ret, PRODUCT_CLUSTER_SERVER_C, ret_size - 1); + break; + case PRODUCT_DATACENTER_SERVER: + strncat(ret, PRODUCT_DATACENTER_SERVER_C, ret_size - 1); + break; + case PRODUCT_DATACENTER_SERVER_CORE: + strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_C, ret_size - 1); + break; + case PRODUCT_DATACENTER_SERVER_CORE_V: + strncat(ret, PRODUCT_DATACENTER_SERVER_CORE_V_C, ret_size - 1); + break; + case PRODUCT_DATACENTER_SERVER_V: + strncat(ret, PRODUCT_DATACENTER_SERVER_V_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE: + strncat(ret, PRODUCT_ENTERPRISE_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE_N: + strncat(ret, PRODUCT_ENTERPRISE_N_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE_SERVER: + strncat(ret, PRODUCT_ENTERPRISE_SERVER_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE_SERVER_CORE: + strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE_SERVER_CORE_V: + strncat(ret, PRODUCT_ENTERPRISE_SERVER_CORE_V_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE_SERVER_IA64: + strncat(ret, PRODUCT_ENTERPRISE_SERVER_IA64_C, ret_size - 1); + break; + case PRODUCT_ENTERPRISE_SERVER_V: + strncat(ret, PRODUCT_ENTERPRISE_SERVER_V_C, ret_size - 1); + break; + case PRODUCT_HOME_BASIC: + strncat(ret, PRODUCT_HOME_BASIC_C, ret_size - 1); + break; + case PRODUCT_HOME_BASIC_N: + strncat(ret, PRODUCT_HOME_BASIC_N_C, ret_size - 1); + break; + case PRODUCT_HOME_PREMIUM: + strncat(ret, PRODUCT_HOME_PREMIUM_C, ret_size - 1); + break; + case PRODUCT_HOME_PREMIUM_N: + strncat(ret, PRODUCT_HOME_PREMIUM_N_C, ret_size - 1); + break; + case PRODUCT_HOME_SERVER: + strncat(ret, PRODUCT_HOME_SERVER_C, ret_size - 1); + break; + case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT: + strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT_C, ret_size - 1); + break; + case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING: + strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING_C, ret_size - 1); + break; + case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY: + strncat(ret, PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY_C, ret_size - 1); + break; + case PRODUCT_SERVER_FOR_SMALLBUSINESS: + strncat(ret, PRODUCT_SERVER_FOR_SMALLBUSINESS_C, ret_size - 1); + break; + case PRODUCT_SMALLBUSINESS_SERVER: + strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_C, ret_size - 1); + break; + case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: + strncat(ret, PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_C, ret_size - 1); + break; + case PRODUCT_STANDARD_SERVER: + strncat(ret, PRODUCT_STANDARD_SERVER_C, ret_size - 1); + break; + case PRODUCT_STANDARD_SERVER_CORE: + strncat(ret, PRODUCT_STANDARD_SERVER_CORE_C, ret_size - 1); + break; + case PRODUCT_STANDARD_SERVER_CORE_V: + strncat(ret, PRODUCT_STANDARD_SERVER_CORE_V_C, ret_size - 1); + break; + case PRODUCT_STANDARD_SERVER_V: + strncat(ret, PRODUCT_STANDARD_SERVER_V_C, ret_size - 1); + break; + case PRODUCT_STARTER: + strncat(ret, PRODUCT_STARTER_C, ret_size - 1); + break; + case PRODUCT_STORAGE_ENTERPRISE_SERVER: + strncat(ret, PRODUCT_STORAGE_ENTERPRISE_SERVER_C, ret_size - 1); + break; + case PRODUCT_STORAGE_EXPRESS_SERVER: + strncat(ret, PRODUCT_STORAGE_EXPRESS_SERVER_C, ret_size - 1); + break; + case PRODUCT_STORAGE_STANDARD_SERVER: + strncat(ret, PRODUCT_STORAGE_STANDARD_SERVER_C, ret_size - 1); + break; + case PRODUCT_STORAGE_WORKGROUP_SERVER: + strncat(ret, PRODUCT_STORAGE_WORKGROUP_SERVER_C, ret_size - 1); + break; + case PRODUCT_ULTIMATE: + strncat(ret, PRODUCT_ULTIMATE_C, ret_size - 1); + break; + case PRODUCT_ULTIMATE_N: + strncat(ret, PRODUCT_ULTIMATE_N_C, ret_size - 1); + break; + case PRODUCT_WEB_SERVER: + strncat(ret, PRODUCT_WEB_SERVER_C, ret_size - 1); + break; + case PRODUCT_WEB_SERVER_CORE: + strncat(ret, PRODUCT_WEB_SERVER_CORE_C, ret_size - 1); + break; + } + + ret_size -= strlen(ret) + 1; + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { + pGNSI = (PGNSI) GetProcAddress( + GetModuleHandle("kernel32.dll"), + "GetNativeSystemInfo"); + if (NULL != pGNSI) { + pGNSI(&si); + } + + if ( GetSystemMetrics(89) ) + strncat(ret, "Microsoft Windows Server 2003 R2 ", + ret_size - 1); + else if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + strncat(ret, + "Microsoft Windows XP Professional x64 Edition ", + ret_size - 1 ); + } else { + strncat(ret, "Microsoft Windows Server 2003, ", ret_size - 1); + } + + ret_size -= strlen(ret) + 1; + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { + strncat(ret, "Microsoft Windows XP ", ret_size - 1); + + ret_size -= strlen(ret) + 1; + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { + strncat(ret, "Microsoft Windows 2000 ", ret_size - 1); + + ret_size -= strlen(ret) + 1; + } else if (osvi.dwMajorVersion <= 4) { + strncat(ret, "Microsoft Windows NT ", ret_size - 1); + + ret_size -= strlen(ret) + 1; + } else { + strncat(ret, "Microsoft Windows Unknown ", ret_size - 1); + + ret_size -= strlen(ret) + 1; + } + + /* Test for specific product on Windows NT 4.0 SP6 and later */ + if (bOsVersionInfoEx) { + /* Test for the workstation type */ + if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64) { + if ( osvi.dwMajorVersion == 4 ) { + strncat(ret, "Workstation 4.0 ", ret_size - 1); + } else if ( osvi.wSuiteMask & VER_SUITE_PERSONAL ) { + strncat(ret, "Home Edition ", ret_size - 1); + } else { + strncat(ret, "Professional ", ret_size - 1); + } + + /* Fix size */ + ret_size -= strlen(ret) + 1; + } + + /* Test for the server type */ + else if ( osvi.wProductType == VER_NT_SERVER || + osvi.wProductType == VER_NT_DOMAIN_CONTROLLER ) { + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { + if (si.wProcessorArchitecture == + PROCESSOR_ARCHITECTURE_IA64 ) { + if ( osvi.wSuiteMask & VER_SUITE_DATACENTER ) + strncat(ret, + "Datacenter Edition for Itanium-based Systems ", + ret_size - 1); + else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + strncat(ret, + "Enterprise Edition for Itanium-based Systems ", + ret_size - 1); + + ret_size -= strlen(ret) + 1; + } else if ( si.wProcessorArchitecture == + PROCESSOR_ARCHITECTURE_AMD64 ) { + if ( osvi.wSuiteMask & VER_SUITE_DATACENTER ) + strncat(ret, "Datacenter x64 Edition ", + ret_size - 1 ); + else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + strncat(ret, "Enterprise x64 Edition ", + ret_size - 1 ); + else + strncat(ret, "Standard x64 Edition ", + ret_size - 1 ); + + ret_size -= strlen(ret) + 1; + } else { + if ( osvi.wSuiteMask & VER_SUITE_DATACENTER ) + strncat(ret, "Datacenter Edition ", + ret_size - 1 ); + else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) { + strncat(ret, "Enterprise Edition ", ret_size - 1); + } else if ( osvi.wSuiteMask == VER_SUITE_BLADE ) { + strncat(ret, "Web Edition ", ret_size - 1 ); + } else { + strncat(ret, "Standard Edition ", ret_size - 1); + } + + ret_size -= strlen(ret) + 1; + } + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { + if ( osvi.wSuiteMask & VER_SUITE_DATACENTER ) { + strncat(ret, "Datacenter Server ", ret_size - 1); + } else if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) { + strncat(ret, "Advanced Server ", ret_size - 1 ); + } else { + strncat(ret, "Server ", ret_size - 1); + } + + ret_size -= strlen(ret) + 1; + } else if (osvi.dwMajorVersion <= 4) { /* Windows NT 4.0 */ + if ( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + strncat(ret, "Server 4.0, Enterprise Edition ", + ret_size - 1 ); + else { + strncat(ret, "Server 4.0 ", ret_size - 1); + } + + ret_size -= strlen(ret) + 1; + } + } + } + /* Test for specific product on Windows NT 4.0 SP5 and earlier */ + else { + HKEY hKey; + char szProductType[81]; + DWORD dwBufLen = 80; + LONG lRet; + + lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", + 0, KEY_QUERY_VALUE, &hKey ); + if (lRet == ERROR_SUCCESS) { + char __wv[32]; + + lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL, + (LPBYTE) szProductType, &dwBufLen); + RegCloseKey( hKey ); + + if ((lRet == ERROR_SUCCESS) && (dwBufLen < 80) ) { + if (lstrcmpi( "WINNT", szProductType) == 0 ) { + strncat(ret, "Workstation ", ret_size - 1); + } else if (lstrcmpi( "LANMANNT", szProductType) == 0 ) { + strncat(ret, "Server ", ret_size - 1); + } else if (lstrcmpi( "SERVERNT", szProductType) == 0 ) { + strncat(ret, "Advanced Server " , ret_size - 1); + } + + ret_size -= strlen(ret) + 1; + + memset(__wv, '\0', 32); + snprintf(__wv, 31, + "%d.%d ", + (int)osvi.dwMajorVersion, + (int)osvi.dwMinorVersion); + + strncat(ret, __wv, ret_size - 1); + ret_size -= strlen(__wv) + 1; + } + } + } + + /* Display service pack (if any) and build number */ + if ( osvi.dwMajorVersion == 4 && + lstrcmpi( osvi.szCSDVersion, "Service Pack 6" ) == 0 ) { + HKEY hKey; + LONG lRet; + char __wp[64]; + + memset(__wp, '\0', 64); + /* Test for SP6 versus SP6a */ + lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009", + 0, KEY_QUERY_VALUE, &hKey ); + if ( lRet == ERROR_SUCCESS ) + snprintf(__wp, 63, "Service Pack 6a (Build %d)", + (int)osvi.dwBuildNumber & 0xFFFF ); + else { /* Windows NT 4.0 prior to SP6a */ + snprintf(__wp, 63, "%s (Build %d)", + osvi.szCSDVersion, + (int)osvi.dwBuildNumber & 0xFFFF); + } + + strncat(ret, __wp, ret_size - 1); + ret_size -= strlen(__wp) + 1; + RegCloseKey( hKey ); + } else { + char __wp[64]; + + memset(__wp, '\0', 64); + + snprintf(__wp, 63, "%s (Build %d)", + osvi.szCSDVersion, + (int)osvi.dwBuildNumber & 0xFFFF); + + strncat(ret, __wp, ret_size - 1); + ret_size -= strlen(__wp) + 1; + } + break; + + /* Test for Windows Me/98/95 */ + case VER_PLATFORM_WIN32_WINDOWS: + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) { + strncat(ret, "Microsoft Windows 95 ", ret_size - 1); + ret_size -= strlen(ret) + 1; + } + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) { + strncat(ret, "Microsoft Windows 98 ", ret_size - 1); + ret_size -= strlen(ret) + 1; + } + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) { + strncat(ret, "Microsoft Windows Millennium Edition", + ret_size - 1); + + ret_size -= strlen(ret) + 1; + } + break; + + case VER_PLATFORM_WIN32s: + strncat(ret, "Microsoft Win32s", ret_size - 1); + ret_size -= strlen(ret) + 1; + break; + } + + /* Add openarmor-HIDS version */ + snprintf(os_v, 128, " - %s %s", __openarmor_name, __openarmor_version); + strncat(ret, os_v, ret_size - 1); + + return (ret); + +} + +#endif /* WIN32 */ + + +int w_ref_parent_folder(const char * path) { + const char * str; + char * ptr; + + switch (path[0]) { + case '\0': + return 0; + + case '.': + switch (path[1]) { + case '\0': + return 0; + + case '.': + switch (path[2]) { + case '\0': + return 1; + + case '/': +#ifdef WIN32 + case '\\': +#endif + return 1; + } + } + } + +#ifdef WIN32 + for (str = path; ptr = strstr(str, "/.."), ptr || (ptr = strstr(str, "\\.."), ptr); str = ptr + 3) { + if (ptr[3] == '\0' || ptr[3] == '/' || ptr[3] == '\\') { +#else + for (str = path; ptr = strstr(str, "/.."), ptr; str = ptr + 3) { + if (ptr[3] == '\0' || ptr[3] == '/') { +#endif + return 1; + } + } + + return 0; +} + +bool is_control_character(char c) { + return (c >= 0 && c <= 31) || c == 127 || c == '\n'; +} + +void remove_control_characters(char *str) { + int len = strlen(str); + int i, j; + + for (i = 0, j = 0; i < len; i++) { + if (!is_control_character(str[i])) { + str[j] = str[i]; + j++; + } else { + DEBUG_MSG("%s:DEBUG: control character removed: %d",ARGV0, str[i]); + } + } + + str[j] = '\0'; // Null-terminate the string after removing control characters +} \ No newline at end of file diff --git a/src/shared/fs_op.c b/src/shared/fs_op.c new file mode 100644 index 000000000..d1466da9c --- /dev/null +++ b/src/shared/fs_op.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + + +/* Functions to retrieve information about the filesystem + */ + + +#include "shared.h" +#ifndef ARGV0 +#define ARGV0 "fs_op" +#endif + +const struct file_system_type network_file_systems[] = { + {.name="NFS", .f_type=0x6969, .flag=1}, + {.name="CIFS", .f_type=0xFF534D42, .flag=1}, + + /* The last entry must be name=NULL */ + {.name=NULL, .f_type=0, .flag=0} +}; + +/* List of filesystem to skip the link count test */ +const struct file_system_type skip_file_systems[] = { + {.name="BTRFS", .f_type=0x9123683E, .flag=1}, + {.name="AUFS", .f_type=0x61756673, .flag=1}, + {.name="OVERLAYFS", .f_type=0x794c7630, .flag=1}, + + /* The last entry must be name=NULL */ + {.name=NULL, .f_type=0, .flag=0} +}; + +short IsNFS(const char *dir_name) +{ +#if !defined(WIN32) && (defined(Linux) || defined(FreeBSD) || defined(OpenBSD)) + struct statfs stfs; + + /* ignore NFS (0x6969) or CIFS (0xFF534D42) mounts */ + if ( ! statfs(dir_name, &stfs) ) + { + int i; + for ( i=0; network_file_systems[i].name != NULL; i++ ) { +#if __OpenBSD__ + if(strcasecmp(network_file_systems[i].name, stfs.f_fstypename) == 0) { +#else + if(network_file_systems[i].f_type == stfs.f_type ) { +#endif // __OpenBSD + return network_file_systems[i].flag; + } + } + return(0); + } + else + { + /* If the file exists, throw an error and retreat! If the file does not exist, there + * is no reason to spam the log with these errors. */ + if(errno != ENOENT) { + merror("ERROR: statfs('%s') produced error: %s", dir_name, strerror(errno)); + } + return(-1); + } +#else + verbose( + "INFO: Attempted to check NFS status for '%s', but we don't know how on this OS.", + dir_name + ); +#endif + return(0); +} + +short skipFS(const char *dir_name) +{ +#if !defined(WIN32) && (defined(Linux) || defined(FreeBSD) || defined(OpenBSD)) + struct statfs stfs; + + if ( ! statfs(dir_name, &stfs) ) + { + int i; + for ( i=0; skip_file_systems[i].name != NULL; i++ ) { +#if __OpenBSD__ + if(strcasecmp(skip_file_systems[i].name, stfs.f_fstypename) == 0) { +#else + if(skip_file_systems[i].f_type == stfs.f_type ) { +#endif // __OpenBSD__ + debug1("%s: Skipping dir (FS %s): %s ", ARGV0, skip_file_systems[i].name, dir_name); + return skip_file_systems[i].flag; + } + } + return(0); + } + else + { + /* If the file exists, throw an error and retreat! If the file does not exist, there + * is no reason to spam the log with these errors. */ + if(errno != ENOENT) { + merror("ERROR: statfs('%s') produced error: %s", dir_name, strerror(errno)); + } + return(-1); + } +#else +#ifndef WIN32 + debug2( + "INFO: Attempted to check FS status for '%s', but we don't know how on this OS.", + dir_name + ); +#endif +#endif + return(0); +} + + +/* EOF */ diff --git a/src/shared/hash_op.c b/src/shared/hash_op.c new file mode 100644 index 000000000..d438ac1b7 --- /dev/null +++ b/src/shared/hash_op.c @@ -0,0 +1,293 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Common API for dealing with hashes/maps */ + +#include "shared.h" + +static unsigned int _os_genhash(const OSHash *self, const char *key) __attribute__((nonnull)); + + +/* Create hash + * Returns NULL on error + */ +OSHash *OSHash_Create() +{ + unsigned int i = 0; + OSHash *self; + + /* Allocate memory for the hash */ + self = (OSHash *) calloc(1, sizeof(OSHash)); + if (!self) { + return (NULL); + } + + /* Set default row size */ + self->rows = os_getprime(1024); + if (self->rows == 0) { + free(self); + return (NULL); + } + + /* Create hashing table */ + self->table = (OSHashNode **)calloc(self->rows + 1, sizeof(OSHashNode *)); + if (!self->table) { + free(self); + return (NULL); + } + + /* Zero our tables */ + for (i = 0; i <= self->rows; i++) { + self->table[i] = NULL; + } + + /* Get seed */ + srandom((unsigned int)time(0)); + self->initial_seed = os_getprime((unsigned)random() % self->rows); + self->constant = os_getprime((unsigned)random() % self->rows); + + return (self); +} + +/* Free the memory used by the hash */ +void *OSHash_Free(OSHash *self) +{ + unsigned int i = 0; + OSHashNode *curr_node; + OSHashNode *next_node; + + /* Free each entry */ + while (i <= self->rows) { + curr_node = self->table[i]; + next_node = curr_node; + while (next_node) { + next_node = next_node->next; + free(curr_node->key); + free(curr_node); + curr_node = next_node; + } + i++; + } + + /* Free the hash table */ + free(self->table); + + free(self); + return (NULL); +} + +/* Generates hash for key */ +static unsigned int _os_genhash(const OSHash *self, const char *key) +{ + unsigned int hash_key = self->initial_seed; + + /* What we have here is a simple polynomial hash. + * x0 * a^k-1 .. xk * a^k-k +1 + */ + while (*key) { + hash_key *= self->constant; + hash_key += (unsigned int) * key; + key++; + } + + return (hash_key); +} + +/* Set new size for hash + * Returns 0 on error (out of memory) + */ +int OSHash_setSize(OSHash *self, unsigned int new_size) +{ + unsigned int i = 0; + + /* We can't decrease the size */ + if (new_size <= self->rows) { + return (1); + } + + /* Get next prime */ + self->rows = os_getprime(new_size); + if (self->rows == 0) { + return (0); + } + + /* If we fail, the hash should not be used anymore */ + self->table = (OSHashNode **) realloc(self->table, (self->rows + 1) * sizeof(OSHashNode *)); + if (!self->table) { + return (0); + } + + /* Zero our tables */ + for (i = 0; i <= self->rows; i++) { + self->table[i] = NULL; + } + + /* New seed */ + self->initial_seed = os_getprime((unsigned)random() % self->rows); + self->constant = os_getprime((unsigned)random() % self->rows); + + return (1); +} + + +/** int OSHash_Update(OSHash *self, char *key, void *data) + * Returns 0 on error (not found). + * Returns 1 on successduplicated key (not added) + * Key must not be NULL. + */ +int OSHash_Update(OSHash *self, const char *key, void *data) +{ + unsigned int hash_key; + unsigned int index; + OSHashNode *curr_node; + + /* Generate hash of the message */ + hash_key = _os_genhash(self, key); + + /* Get array index */ + index = hash_key % self->rows; + + /* Check for duplicated entries in the index */ + curr_node = self->table[index]; + while (curr_node) { + /* Checking for duplicated key -- not adding */ + if (strcmp(curr_node->key, key) == 0) { + curr_node->data = data; + return (1); + } + curr_node = curr_node->next; + } + return (0); +} + +/** int OSHash_Add(OSHash *self, char *key, void *data) + * Returns 0 on error. + * Returns 1 on duplicated key (not added) + * Returns 2 on success + * Key must not be NULL. + */ +int OSHash_Add(OSHash *self, const char *key, void *data) +{ + unsigned int hash_key; + unsigned int index; + OSHashNode *curr_node; + OSHashNode *new_node; + + /* Generate hash of the message */ + hash_key = _os_genhash(self, key); + + /* Get array index */ + index = hash_key % self->rows; + + /* Check for duplicated entries in the index */ + curr_node = self->table[index]; + while (curr_node) { + /* Checking for duplicated key -- not adding */ + if (strcmp(curr_node->key, key) == 0) { + /* Not adding */ + return (1); + } + curr_node = curr_node->next; + } + + /* Create new node */ + new_node = (OSHashNode *) calloc(1, sizeof(OSHashNode)); + if (!new_node) { + return (0); + } + new_node->next = NULL; + new_node->data = data; + new_node->key = strdup(key); + if ( new_node->key == NULL ) { + free(new_node); + debug1("hash_op: DEBUG: strdup() failed!"); + return (0); + } + + /* Add to table */ + if (!self->table[index]) { + self->table[index] = new_node; + } + /* If there is duplicated, add to the beginning */ + else { + new_node->next = self->table[index]; + self->table[index] = new_node; + } + + return (2); +} + +/** void *OSHash_Get(OSHash *self, char *key) + * Returns NULL on error (key not found). + * Returns the key otherwise. + * Key must not be NULL. + */ +void *OSHash_Get(const OSHash *self, const char *key) +{ + unsigned int hash_key; + unsigned int index; + const OSHashNode *curr_node; + + /* Generate hash of the message */ + hash_key = _os_genhash(self, key); + + /* Get array index */ + index = hash_key % self->rows; + + /* Get entry */ + curr_node = self->table[index]; + while (curr_node != NULL) { + + + /* We may have collisions, so double check with strcmp */ + if (curr_node->key != NULL && strcmp(curr_node->key, key) == 0) { + + return (curr_node->data); + } + + curr_node = curr_node->next; + } + + return (NULL); +} + +/* Return a pointer to a hash node if found, that hash node is removed from the table */ +void *OSHash_Delete(OSHash *self, const char *key) +{ + OSHashNode *curr_node; + OSHashNode *prev_node = 0; + unsigned int hash_key; + unsigned int index; + void *data; + + /* Generate hash of the message */ + hash_key = _os_genhash(self, key); + + /* Get array index */ + index = hash_key % self->rows; + + curr_node = self->table[index]; + while ( curr_node != NULL ) { + if (strcmp(curr_node->key, key) == 0) { + if ( prev_node == NULL ) { + self->table[index] = curr_node->next; + } else { + prev_node->next = curr_node->next; + } + free(curr_node->key); + data = curr_node->data; + free(curr_node); + return data; + } + prev_node = curr_node; + curr_node = curr_node->next; + } + + return NULL; +} diff --git a/src/shared/help.c b/src/shared/help.c new file mode 100644 index 000000000..ac2758e09 --- /dev/null +++ b/src/shared/help.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Help Function */ + +#include "shared.h" + + +void print_header() +{ + print_out(" "); + print_out("%s %s - %s (%s)", __openarmor_name, __openarmor_version, __author, __contact); + print_out("%s", __site); +} + +void print_version() +{ + print_out(" "); + print_out("%s %s - %s", __openarmor_name, __openarmor_version, __author); + print_out(" "); + print_out("%s", __license); + exit(1); +} diff --git a/src/shared/list_op.c b/src/shared/list_op.c new file mode 100644 index 000000000..ce6ef9620 --- /dev/null +++ b/src/shared/list_op.c @@ -0,0 +1,287 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Common API for dealing with lists */ + +#include "shared.h" + + +/* Create the list + * Returns NULL on error + */ +OSList *OSList_Create() +{ + OSList *my_list; + + my_list = (OSList *) calloc(1, sizeof(OSList)); + if (!my_list) { + return (NULL); + } + + my_list->first_node = NULL; + my_list->last_node = NULL; + my_list->cur_node = NULL; + my_list->currently_size = 0; + my_list->max_size = 0; + my_list->free_data_function = NULL; + + return (my_list); +} + +/* Set the maximum number of elements in the list + * Returns 0 on error or 1 on success + */ +int OSList_SetMaxSize(OSList *list, int max_size) +{ + if (!list) { + return (0); + } + + /* Minimum size is 1 */ + if (max_size <= 1) { + return (0); + } + + list->max_size = max_size; + + return (1); +} + +/* Set the pointer to the function to free the memory data */ +int OSList_SetFreeDataPointer(OSList *list, void (free_data_function)(void *)) +{ + if (!list) { + return (0); + } + + list->free_data_function = free_data_function; + return (1); +} + +/* Get first node from list + * Returns null on invalid list + */ +OSListNode *OSList_GetFirstNode(OSList *list) +{ + list->cur_node = list->first_node; + return (list->first_node); +} + +/* Get last node from list + * Returns null on invalid list + */ +OSListNode *OSList_GetLastNode(OSList *list) +{ + list->cur_node = list->last_node; + return (list->last_node); +} + +/* Get next node from list + * Returns null on invalid list or at the end of the list + */ +OSListNode *OSList_GetNextNode(OSList *list) +{ + if (list->cur_node == NULL) { + return (NULL); + } + + list->cur_node = list->cur_node->next; + + return (list->cur_node); +} + +/* Get the prev node from the list + * Returns NULL at the beginning + */ +OSListNode *OSList_GetPrevNode(OSList *list) +{ + if (list->cur_node == NULL) { + return (NULL); + } + + list->cur_node = list->cur_node->prev; + + return (list->cur_node); +} + +/* Get the currently node + * Returns null when no currently node is available + */ +OSListNode *OSList_GetCurrentlyNode(OSList *list) +{ + return (list->cur_node); +} + +/* Delete first node from list */ +void OSList_DeleteOldestNode(OSList *list) +{ + OSListNode *next; + + if (list->first_node) { + next = list->first_node->next; + if (next) { + next->prev = NULL; + } else { + list->last_node = next; + } + + free(list->first_node); + list->first_node = next; + } else { + merror("%s: No Oldest node to delete", __local_name); + } + + return; +} + +/* Delete this node from list + * Pointer goes to the next node available + */ +void OSList_DeleteThisNode(OSList *list, OSListNode *thisnode) +{ + OSListNode *prev; + OSListNode *next; + + if (thisnode == NULL) { + return; + } + + prev = thisnode->prev; + next = thisnode->next; + + /* Setting the previous node of the next one + * and the next node of the previous one.. :) + */ + if (prev && next) { + prev->next = next; + next->prev = prev; + } else if (prev) { + prev->next = NULL; + list->last_node = prev; + } else if (next) { + next->prev = NULL; + list->first_node = next; + } else { + list->last_node = NULL; + list->first_node = NULL; + } + + /* Free the node memory */ + free(thisnode); + + /* Set the currently node to the next one */ + list->cur_node = next; + + list->currently_size--; +} + +/* Delete current node from list + * Pointer goes to the next node available + */ +void OSList_DeleteCurrentlyNode(OSList *list) +{ + OSListNode *prev; + OSListNode *next; + + if (list->cur_node == NULL) { + return; + } + + prev = list->cur_node->prev; + next = list->cur_node->next; + + /* Setting the previous node of the next one + * and the next node of the previous one.. :) + */ + if (prev && next) { + prev->next = next; + next->prev = prev; + } else if (prev) { + prev->next = NULL; + list->last_node = prev; + } else if (next) { + next->prev = NULL; + list->first_node = next; + } else { + list->last_node = NULL; + list->first_node = NULL; + } + + /* Free the node memory */ + free(list->cur_node); + + /* Set the current node to the next one */ + list->cur_node = next; + + list->currently_size--; +} + +/* Add data to the list + * Returns 1 on success and 0 on failure + */ +int OSList_AddData(OSList *list, void *data) +{ + OSListNode *newnode; + + /* Allocate memory for new node */ + newnode = (OSListNode *) calloc(1, sizeof(OSListNode)); + if (!newnode) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (0); + } + + newnode->prev = list->last_node; + newnode->next = NULL; + newnode->data = data; + + /* If we don't have a first node, assign it */ + if (!list->first_node) { + list->first_node = newnode; + } + + /* If we have a last node, set the next to new node */ + if (list->last_node) { + list->last_node->next = newnode; + } + + /* newnode becomes last node */ + list->last_node = newnode; + + /* Increment list size */ + list->currently_size++; + + /* Ff currently_size higher than the maximum size, remove the + * oldest node (first one) + */ + if (list->max_size) { + if (list->currently_size > list->max_size && list->first_node->next) { + /* Remove first node */ + newnode = list->first_node->next; + + newnode->prev = NULL; + + /* Clear any internal memory using the pointer */ + if (list->free_data_function) { + list->free_data_function(list->first_node->data); + } + + /* Clear the memory */ + free(list->first_node); + + /* First node become the ex first->next */ + list->first_node = newnode; + + /* Reduce list size */ + list->currently_size--; + } + } + + return (1); +} + diff --git a/src/shared/math_op.c b/src/shared/math_op.c new file mode 100644 index 000000000..202a78523 --- /dev/null +++ b/src/shared/math_op.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" + + +/* Get the first available prime after the provided value + * Returns 0 on error + */ +unsigned int os_getprime(unsigned int val) +{ + unsigned int i; + unsigned int max_i; + + /* Value can't be even */ + if ((val % 2) == 0) { + val++; + } + + do { + /* We just need to check odd numbers up until half + * the size of the provided value + */ + i = 3; + max_i = val / 2; + while (i <= max_i) { + /* Not prime */ + if ((val % i) == 0) { + break; + } + i += 2; + } + + /* Prime */ + if (i >= max_i) { + return (val); + } + } while (val += 2); + + return (0); +} + diff --git a/src/shared/mem_op.c b/src/shared/mem_op.c new file mode 100644 index 000000000..9e39355a5 --- /dev/null +++ b/src/shared/mem_op.c @@ -0,0 +1,140 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "mem_op.h" +#include "shared.h" + + +/* Add pointer to array */ +void **os_AddPtArray(void *pt, void **array) +{ + size_t i = 0; + void **ret = NULL; + + if (array) { + while (array[i]) { + i++; + } + } + + os_realloc(array, (i + 2)*sizeof(void *), ret); + ret[i] = pt; + ret[i + 1] = NULL; + + return (ret); +} + +/* Add a string to an array */ +char **os_AddStrArray(const char *str, char **array) +{ + size_t i = 0; + char **ret = NULL; + if (array) { + while (array[i]) { + i++; + } + } + + os_realloc(array, (i + 2)*sizeof(char *), ret); + os_strdup(str, ret[i]); + ret[i + 1] = NULL; + + return (ret); +} + +/* Check if String is on array (Must be NULL terminated) */ +int os_IsStrOnArray(const char *str, char **array) +{ + if (!str || !array) { + return (0); + } + + while (*array) { + if (strcmp(*array, str) == 0) { + return (1); + } + array++; + } + return (0); +} + +/* Clear the memory of one char and one char** */ +void os_FreeArray(char *ch1, char **ch2) +{ + /* Clean char * */ + if (ch1) { + free(ch1); + ch1 = NULL; + } + + /* Clean chat ** */ + if (ch2) { + char **nch2 = ch2; + + while (*ch2 != NULL) { + free(*ch2); + ch2++; + } + + free(nch2); + nch2 = NULL; + } + + return; +} + +/* Allocate memory at "*at" and copy *str to it + * If *at already exist, realloc the memory and strcat str on it + * It will return the new string on success or NULL on memory error + */ +char *os_LoadString(char *at, const char *str) +{ + if (at == NULL) { + at = strdup(str); + if (!at) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + } + return (at); + } else { /* at is not null. Need to reallocate its memory and copy str to it */ + char *newat; + size_t strsize = strlen(str); + size_t finalsize = strsize + strlen(at) + 1; + + newat = (char *) realloc(at, finalsize * sizeof(char)); + if (newat == NULL) { + free(at); + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (NULL); + } + at = newat; + + strncat(at, str, strsize); + at[finalsize - 1] = '\0'; + + return (at); + } + + return (NULL); +} + +/* Clear memory regardless of compiler optimizations + * v = memory to clear + * c = character to set + * n = memory size to clear + */ +void *memset_secure(void *v, int c, size_t n) +{ + volatile unsigned char *p = (volatile unsigned char *)v; + while (n--) { + *p++ = (unsigned char) c; + } + + return v; +} + diff --git a/src/shared/mq_op.c b/src/shared/mq_op.c new file mode 100644 index 000000000..5915e4658 --- /dev/null +++ b/src/shared/mq_op.c @@ -0,0 +1,143 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_net/os_net.h" + + +#ifndef WIN32 + +/* Start the Message Queue. type: WRITE||READ */ +int StartMQ(const char *path, short int type) +{ + if (type == READ) { + return (OS_BindUnixDomain(path, 0660, OS_MAXSTR + 512)); + } + + /* We give up to 21 seconds for the other end to start */ + else { + int rc = 0; + if (File_DateofChange(path) < 0) { + sleep(1); + if (File_DateofChange(path) < 0) { + sleep(5); + if (File_DateofChange(path) < 0) { + sleep(15); + if (File_DateofChange(path) < 0) { + merror(QUEUE_ERROR, __local_name, path, "Queue not found"); + return (-1); + } + } + } + } + + /* Wait up to 3 seconds to connect to the unix domain. + * After three errors, exit. + */ + if ((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0) { + sleep(1); + if ((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0) { + sleep(2); + if ((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0) { + merror(QUEUE_ERROR, __local_name, path, + strerror(errno)); + return (-1); + } + } + } + + debug1(MSG_SOCKET_SIZE, __local_name, OS_getsocketsize(rc)); + return (rc); + } +} + +/* Send a message to the queue */ +int SendMSG(int queue, const char *message, const char *locmsg, char loc) +{ + int __mq_rcode; + char tmpstr[OS_MAXSTR + 1]; + + tmpstr[OS_MAXSTR] = '\0'; + + /* Check for global locks */ + os_wait(); + + if (loc == SECURE_MQ) { + loc = message[0]; + message++; + + if (message[0] != ':') { + merror(FORMAT_ERROR, __local_name); + return (0); + } + message++; /* Pointing now to the location */ + + if (strncmp(message, "keepalive", 9) == 0) { + return (0); + } + + snprintf(tmpstr, OS_MAXSTR, "%c:%s->%s", loc, locmsg, message); + } else { + snprintf(tmpstr, OS_MAXSTR, "%c:%s:%s", loc, locmsg, message); + } + + /* Queue not available */ + if (queue < 0) { + return (-1); + } + + /* We attempt 5 times to send the message if + * the receiver socket is busy. + * After the first error, we wait 1 second. + * After the second error, we wait more 3 seconds. + * After the third error, we wait 5 seconds. + * After the fourth error, we wait 10 seconds. + * If we failed again, the message is not going + * to be delivered and an error is sent back. + */ + if ((__mq_rcode = OS_SendUnix(queue, tmpstr, 0)) < 0) { + /* Error on the socket */ + if (__mq_rcode == OS_SOCKTERR) { + merror("%s: socketerr (not available).", __local_name); + close(queue); + return (-1); + } + + /* Unable to send. Socket busy */ + sleep(1); + if (OS_SendUnix(queue, tmpstr, 0) < 0) { + /* When the socket is to busy, we may get some + * error here. Just sleep 2 second and try + * again. + */ + sleep(3); + /* merror("%s: socket busy", __local_name); */ + if (OS_SendUnix(queue, tmpstr, 0) < 0) { + sleep(5); + merror("%s: socket busy ..", __local_name); + if (OS_SendUnix(queue, tmpstr, 0) < 0) { + sleep(10); + merror("%s: socket busy ..", __local_name); + if (OS_SendUnix(queue, tmpstr, 0) < 0) { + /* Message is going to be lost + * if the application does not care + * about checking the error + */ + close(queue); + return (-1); + } + } + } + } + } + + return (0); +} + +#endif /* !WIN32 */ diff --git a/src/shared/privsep_op.c b/src/shared/privsep_op.c new file mode 100644 index 000000000..b2ac25cea --- /dev/null +++ b/src/shared/privsep_op.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions for privilege separation */ + +#ifndef WIN32 + +#include +#include +#include +#include +#include + +#include "privsep_op.h" +#include "headers/os_err.h" + + +uid_t Privsep_GetUser(const char *name) +{ + struct passwd *pw; + pw = getpwnam(name); + if (pw == NULL) { + return ((uid_t)OS_INVALID); + } + + return (pw->pw_uid); +} + +gid_t Privsep_GetGroup(const char *name) +{ + struct group *grp; + grp = getgrnam(name); + if (grp == NULL) { + return ((gid_t)OS_INVALID); + } + + return (grp->gr_gid); +} + +int Privsep_SetUser(uid_t uid) +{ + if (setuid(uid) < 0) { + return (OS_INVALID); + } + +#ifndef HPUX + if (seteuid(uid) < 0) { + return (OS_INVALID); + } +#endif + + return (OS_SUCCESS); +} + +int Privsep_SetGroup(gid_t gid) +{ + if (setgroups(1, &gid) == -1) { + return (OS_INVALID); + } + +#ifndef HPUX + if (setegid(gid) < 0) { + return (OS_INVALID); + } +#endif + + if (setgid(gid) < 0) { + return (OS_INVALID); + } + + return (OS_SUCCESS); +} + +int Privsep_Chroot(const char *path) +{ + if (chdir(path) < 0) { + return (OS_INVALID); + } + + if (chroot(path) < 0) { + return (OS_INVALID); + } + + if (chdir("/") < 0) { + return (OS_INVALID); + } + + return (OS_SUCCESS); +} + +#endif /* !WIN32 */ + diff --git a/src/shared/pthreads_op.c b/src/shared/pthreads_op.c new file mode 100644 index 000000000..482fbe6b0 --- /dev/null +++ b/src/shared/pthreads_op.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 +#include "shared.h" +#include + + +/* Create a new thread and give the argument passed to the function + * Returns 0 on success or -1 on error + */ +int CreateThread(void *function_pointer(void *data), void *data) +{ + pthread_t lthread; + int ret = 0; + + ret = pthread_create(<hread, NULL, function_pointer, (void *)data); + if (ret != 0) { + merror(THREAD_ERROR, __local_name); + return (-1); + } + + if (pthread_detach(lthread) != 0) { + merror(THREAD_ERROR, __local_name); + return (-1); + } + + return (0); +} + +#endif /* !WIN32 */ + diff --git a/src/shared/randombytes.c b/src/shared/randombytes.c new file mode 100644 index 000000000..2a72138cf --- /dev/null +++ b/src/shared/randombytes.c @@ -0,0 +1,56 @@ +#ifndef WIN32 +#include +#include +#endif + +#include +#include + +#include "shared.h" + + +void randombytes(void *ptr, size_t length) +{ + char failed = 0; + +#ifdef WIN32 + static HCRYPTPROV prov = 0; + if (prov == 0) { + if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) { + failed = 1; + } + } + if (!failed && !CryptGenRandom(prov, length, ptr)) { + failed = 1; + } +#else + static int fh = -1; + + if (fh >= 0 || (fh = open("/dev/urandom", O_RDONLY)) >= 0 || (fh = open("/dev/random", O_RDONLY)) >= 0) { + const ssize_t ret = read(fh, ptr, length); + if (ret < 0 || (size_t) ret != length) { + failed = 1; + } + } else { + failed = 1; + } +#endif + + if (failed) { + ErrorExit("%s: ERROR: randombytes failed for all possible methods for accessing random data", __local_name); + } +} + +void srandom_init(void) +{ +#ifndef WIN32 +#ifdef __OpenBSD__ + srandomdev(); +#else + unsigned int seed; + randombytes(&seed, sizeof seed); + srandom(seed); +#endif /* !__OpenBSD__ */ +#endif /* !WIN32 */ +} + diff --git a/src/shared/read-agents.c b/src/shared/read-agents.c new file mode 100644 index 000000000..6a2814be3 --- /dev/null +++ b/src/shared/read-agents.c @@ -0,0 +1,1344 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "read-agents.h" +#include "os_net/os_net.h" + +#ifndef WIN32 +static int _do_print_attrs_syscheck(const char *prev_attrs, const char *attrs, int csv_output, cJSON *json_output, + int is_win, int number_of_changes) __attribute__((nonnull(2))); +static int _do_print_file_syscheck(FILE *fp, const char *fname, int update_counter, + int csv_output, cJSON *json_output) __attribute__((nonnull(1))); +static int _do_print_syscheck(FILE *fp, int all_files, int csv_output, cJSON *json_output) __attribute__((nonnull(1))); +static int _do_get_rootcheckscan(FILE *fp) __attribute__((nonnull)); +static int _do_print_rootcheck(FILE *fp, int resolved, time_t time_last_scan, + int csv_output, cJSON *json_output, int show_last) __attribute__((nonnull(1))); + +#endif /* !WIN32*/ + +static int _get_time_rkscan(const char *agent_name, const char *agent_ip, agent_info *agt_info) __attribute__((nonnull(2, 3))); +static char *_get_agent_keepalive(const char *agent_name, const char *agent_ip) __attribute__((nonnull(2))); +static int _get_agent_os(const char *agent_name, const char *agent_ip, agent_info *agt_info) __attribute__((nonnull(2, 3))); + + +/* Free the agent list in memory */ +void free_agents(char **agent_list) +{ + int i; + if (!agent_list) { + return; + } + + for (i = 0;; i++) { + if (agent_list[i] == NULL) { + break; + } + + free(agent_list[i]); + agent_list[i] = NULL; + } + + free(agent_list); + agent_list = NULL; +} + +#ifndef WIN32 + +/* Print syscheck attributes */ +#define sk_strchr(x,y,z) z = strchr(x, y); if(z == NULL) return(0); else { *z = '\0'; z++; } + +static int _do_print_attrs_syscheck(const char *prev_attrs, const char *attrs, __attribute__((unused)) int csv_output, + cJSON *json_output, int is_win, int number_of_changes) +{ + const char *p_size, *size; + char *p_perm, *p_uid, *p_gid, *p_md5, *p_sha1; + char *perm, *uid, *gid, *md5, *sha1; + char perm_str[36]; + + + /* A deleted file has no attributes */ + if (strcmp(attrs, "-1") == 0) { + if (json_output) + cJSON_AddStringToObject(json_output, "event", "deleted"); + else + printf("File deleted.\n"); + return (0); + } + + /* Set each value */ + size = attrs; + sk_strchr(size, ':', perm); + sk_strchr(perm, ':', uid); + sk_strchr(uid, ':', gid); + sk_strchr(gid, ':', md5); + sk_strchr(md5, ':', sha1); + + p_size = size; + p_perm = perm; + p_uid = uid; + p_gid = gid; + p_md5 = md5; + p_sha1 = sha1; + + if (prev_attrs && (strcmp(prev_attrs, "-1") == 0)) { + if (json_output) + cJSON_AddStringToObject(json_output, "event", "restored"); + else + printf("File restored. "); + } else if (prev_attrs) { + if (json_output) + cJSON_AddStringToObject(json_output, "event", "modified"); + else + printf("File changed. "); + + p_size = prev_attrs; + sk_strchr(p_size, ':', p_perm); + sk_strchr(p_perm, ':', p_uid); + sk_strchr(p_uid, ':', p_gid); + sk_strchr(p_gid, ':', p_md5); + sk_strchr(p_md5, ':', p_sha1); + } else { + if (json_output) + cJSON_AddStringToObject(json_output, "event", "added"); + else + printf("File added to the database. "); + } + + if (!json_output) { + /* Fix number of changes */ + if (prev_attrs && !number_of_changes) { + number_of_changes = 1; + } + + if (number_of_changes) { + switch (number_of_changes) { + case 1: + printf("- 1st time modified.\n"); + break; + case 2: + printf("- 2nd time modified.\n"); + break; + case 3: + printf("- 3rd time modified.\n"); + break; + default: + printf("- Being ignored (3 or more changes).\n"); + break; + } + } else { + printf("\n"); + } + } + + perm_str[35] = '\0'; + snprintf(perm_str, 35, "%9.9s", agent_file_perm(perm)); + + if (json_output) { + cJSON_AddStringToObject(json_output, "size", size); + // Legacy + //cJSON_AddNumberToObject(json_output, "mode", is_win ? 0 : perm_int); + cJSON_AddStringToObject(json_output, "perm", is_win ? "" : perm_str); + cJSON_AddStringToObject(json_output, "uid", is_win ? "" : uid); + cJSON_AddStringToObject(json_output, "gid", is_win ? "" : gid); + cJSON_AddStringToObject(json_output, "md5", md5); + cJSON_AddStringToObject(json_output, "sha1", sha1); + + } else{ + printf("Integrity checking values:\n"); + printf(" Size:%s%s\n", (strcmp(size, p_size) == 0) ? " " : " >", size); + if (!is_win) { + printf(" Perm:%s%s\n", (strcmp(perm, p_perm) == 0) ? " " : " >", perm_str); + printf(" Uid: %s%s\n", (strcmp(uid, p_uid) == 0) ? " " : " >", uid); + printf(" Gid: %s%s\n", (strcmp(gid, p_gid) == 0) ? " " : " >", gid); + } + printf(" Md5: %s%s\n", (strcmp(md5, p_md5) == 0) ? " " : " >", md5); + printf(" Sha1:%s%s\n", (strcmp(sha1, p_sha1) == 0) ? " " : " >", sha1); + } + + /* Fix entries */ + perm[-1] = ':'; + uid[-1] = ':'; + gid[-1] = ':'; + md5[-1] = ':'; + sha1[-1] = ':'; + + return (0); +} + +/* Print information about a specific file */ +static int _do_print_file_syscheck(FILE *fp, const char *fname, int update_counter, + int csv_output, cJSON *json_output) +{ + int f_found = 0; + struct tm *tm_time; + char read_day[24 + 1]; + char buf[OS_MAXSTR + 1]; + OSMatch reg; + OSStore *files_list = NULL; + fpos_t init_pos; + cJSON *json_entry = NULL, *json_attrs = NULL; + + buf[OS_MAXSTR] = '\0'; + read_day[24] = '\0'; + + /* If the compilation failed, we don't need to free anything */ + if (!OSMatch_Compile(fname, ®, 0)) { + if (!(csv_output || json_output)) + printf("\n** ERROR: Invalid file name: '%s'\n", fname); + return (0); + } + + /* Create list with files */ + files_list = OSStore_Create(); + if (!files_list) { + OSMatch_FreePattern(®); + goto cleanup; + } + + /* Get initial position */ + if (fgetpos(fp, &init_pos) != 0) { + if (!(csv_output || json_output)) + printf("\n** ERROR: fgetpos failed.\n"); + goto cleanup; + } + + while (fgets(buf, OS_MAXSTR, fp) != NULL) { + if (buf[0] == '!' || buf[0] == '#' || buf[0] == '+') { + int number_changes = 0; + time_t change_time = 0; + char *changed_file_name; + char *changed_attrs; + char *prev_attrs; + + if (strlen(buf) < 16) { + fgetpos(fp, &init_pos); + continue; + } + + /* Remove newline */ + buf[strlen(buf) - 1] = '\0'; + + /* With update counter, we only modify the last entry */ + if (update_counter && buf[0] == '#') { + fgetpos(fp, &init_pos); + continue; + } + + /* Check the number of changes */ + if (buf[1] == '!') { + number_changes = 2; + if (buf[2] == '!') { + number_changes = 3; + } else if (buf[2] == '?') { + number_changes = 4; + } + } + + changed_attrs = buf + 3; + + changed_file_name = strchr(changed_attrs, '!'); + if (!changed_file_name) { + fgetpos(fp, &init_pos); + continue; + } + + /* Get time of change */ + changed_file_name[-1] = '\0'; + changed_file_name++; + change_time = (time_t)atoi(changed_file_name); + + changed_file_name = strchr(changed_file_name, ' '); + if (!changed_file_name) { + if (!(csv_output || json_output)) + printf("\n** ERROR: Invalid line: '%s'.\n", buf); + goto cleanup; + } + changed_file_name++; + + /* Check if the name should be printed */ + if (!OSMatch_Execute(changed_file_name, strlen(changed_file_name), + ®)) { + fgetpos(fp, &init_pos); + continue; + } + + f_found = 1; + + /* Reset the values */ + if (update_counter) { + if (fsetpos(fp, &init_pos) != 0) { + if (!(csv_output || json_output)) + printf("\n** ERROR: fsetpos failed (unable to update " + "counter).\n"); + goto cleanup; + } + + if (update_counter == 2) { + if (fprintf(fp, "!!?") <= 0) { + if (!(csv_output || json_output)) + printf("\n** ERROR: fputs failed (unable to update " + "counter).\n"); + goto cleanup; + } + } + + else { + if (fprintf(fp, "!++") <= 0) { + if (!(csv_output || json_output)) + printf("\n** ERROR: fputs failed (unable to update " + "counter).\n"); + goto cleanup; + } + } + + if (!(csv_output || json_output)) + printf("\n**Counter updated for file '%s'\n\n", + changed_file_name); + goto cleanup; + } + + tm_time = localtime(&change_time); + strftime(read_day, 23, "%Y %h %d %T", tm_time); + + if (json_output) { + json_entry = cJSON_CreateObject(); + json_attrs = cJSON_CreateObject(); + + cJSON_AddStringToObject(json_entry, "readDay", read_day); + cJSON_AddStringToObject(json_entry, "file", changed_file_name); + cJSON_AddNumberToObject(json_entry, "changes", number_changes); + + } else if (csv_output) + printf("%s,%s,%d\n", read_day, changed_file_name, + number_changes); + else + printf("\n%s,%d - %s\n", read_day, number_changes, + changed_file_name); + + prev_attrs = (char *) OSStore_Get(files_list, changed_file_name); + + if (prev_attrs) { + char *new_attrs; + os_strdup(changed_attrs, new_attrs); + _do_print_attrs_syscheck(prev_attrs, changed_attrs, + csv_output, json_attrs, + changed_file_name[0] == '/' ? 0 : 1, + number_changes); + + free(files_list->cur_node->data); + files_list->cur_node->data = new_attrs; + } else { + char *new_attrs; + + os_strdup(changed_attrs, new_attrs); + OSStore_Put(files_list, changed_file_name, new_attrs); + _do_print_attrs_syscheck(NULL, + changed_attrs, csv_output, json_attrs, + changed_file_name[0] == '/' ? 0 : 1, + number_changes); + } + + if (json_output) { + cJSON_AddItemToObject(json_entry, "attrs", json_attrs); + cJSON_AddItemToArray(json_output, json_entry); + } + + fgetpos(fp, &init_pos); + } + } + + if (!f_found) { + printf("\n** No entries found.\n"); + } + +cleanup: + OSMatch_FreePattern(®); + if (files_list) { + OSStore_Free(files_list); + } + + return (0); +} + +/* Print syscheck db (of modified files) */ +static int _do_print_syscheck(FILE *fp, __attribute__((unused)) int all_files, int csv_output, cJSON *json_output) +{ + int f_found = 0; + struct tm *tm_time; + + char read_day[24 + 1]; + char saved_read_day[24 + 1]; + char buf[OS_MAXSTR + 1]; + + buf[OS_MAXSTR] = '\0'; + read_day[24] = '\0'; + saved_read_day[0] = '\0'; + saved_read_day[24] = '\0'; + + while (fgets(buf, OS_MAXSTR, fp) != NULL) { + if (buf[0] == '!' || buf[0] == '#') { + int number_changes = 0; + time_t change_time = 0; + char *changed_file_name; + + if (strlen(buf) < 16) { + continue; + } + + /* Remove newline */ + buf[strlen(buf) - 1] = '\0'; + + /* Check the number of changes */ + if (buf[1] == '!') { + number_changes = 2; + if (buf[2] == '!') { + number_changes = 3; + } else if (buf[2] == '?') { + number_changes = 4; + } + } + + changed_file_name = strchr(buf + 3, '!'); + if (!changed_file_name) { + continue; + } + + f_found = 1; + + /* Get time of change */ + changed_file_name++; + change_time = atoi(changed_file_name); + + changed_file_name = strchr(changed_file_name, ' '); + if (!changed_file_name) { + if (!(csv_output || json_output)) + printf("\n** ERROR: Invalid line: '%s'.\n", buf); + return (-1); + } + changed_file_name++; + + tm_time = localtime(&change_time); + strftime(read_day, 23, "%Y %h %d", tm_time); + if (strcmp(read_day, saved_read_day) != 0) { + if (!(csv_output || json_output)) { + printf("\nChanges for %s:\n", read_day); + } + strncpy(saved_read_day, read_day, 23); + } + strftime(read_day, 23, "%Y %h %d %T", tm_time); + + if (json_output) { + cJSON *entry = cJSON_CreateObject(); + cJSON_AddStringToObject(entry, "readDay", read_day); + cJSON_AddStringToObject(entry, "file", changed_file_name); + cJSON_AddNumberToObject(entry, "changes", number_changes); + cJSON_AddItemToArray(json_output, entry); + } else if (csv_output) + printf("%s,%s,%d\n", read_day, changed_file_name, + number_changes); + else + printf("%s,%d - %s\n", read_day, number_changes, + changed_file_name); + } + } + + if (!(f_found || csv_output || json_output)) { + printf("\n** No entries found.\n"); + } + + return (0); +} + +/* Print syscheck db (of modified files) */ +int print_syscheck(const char *sk_name, const char *sk_ip, const char *fname, + int print_registry, int all_files, int csv_output, + cJSON *json_output, int update_counter) +{ + FILE *fp; + char tmp_file[513]; + + tmp_file[512] = '\0'; + + if (sk_name == NULL) { + /* Print database */ + snprintf(tmp_file, 512, "%s/syscheck", + SYSCHECK_DIR); + + fp = fopen(tmp_file, "r+"); + } + + else if (sk_ip == NULL) { + /* Print database */ + snprintf(tmp_file, 512, "%s/%s->syscheck", SYSCHECK_DIR, sk_name); + + fp = fopen(tmp_file, "r+"); + } + + else if (!print_registry) { + /* Print database */ + snprintf(tmp_file, 512, "%s/(%s) %s->syscheck", + SYSCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "r+"); + } + + else { + /* Print database for the Windows registry */ + snprintf(tmp_file, 512, "%s/(%s) %s->syscheck-registry", + SYSCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "r+"); + } + + if (fp) { + if (!fname) { + _do_print_syscheck(fp, all_files, csv_output, json_output); + } else { + _do_print_file_syscheck(fp, fname, update_counter, csv_output, json_output); + } + fclose(fp); + } + + return (0); +} + +static int _do_get_rootcheckscan(FILE *fp) +{ + char *tmp_str; + char buf[OS_MAXSTR + 1]; + + while (fgets(buf, OS_MAXSTR, fp) != NULL) { + tmp_str = strstr(buf, "Starting rootcheck scan"); + if (tmp_str) { + time_t s_time = 0; + tmp_str = buf + 1; + + s_time = (time_t)atoi(tmp_str); + + return ((int)s_time); + } + } + + return ((int)time(NULL)); +} + +/* Print syscheck db (of modified files) */ +static int _do_print_rootcheck(FILE *fp, int resolved, time_t time_last_scan, + int csv_output, cJSON *json_output, int show_last) +{ + int i = 0; + int f_found = 0; + + /* Time from the message */ + time_t s_time = 0; + time_t i_time = 0; + struct tm *tm_time; + + char old_day[24 + 1]; + char read_day[24 + 1]; + char buf[OS_MAXSTR + 1]; + char *tmp_str; + + const char *(ig_events[]) = {"Starting rootcheck scan", + "Ending rootcheck scan", + "Starting syscheck scan", + "Ending syscheck scan", + NULL + }; + + const char *(ns_events[]) = {"Application Found:", + "Windows Audit:", + "Windows Malware:", + NULL + }; + + buf[OS_MAXSTR] = '\0'; + old_day[24] = '\0'; + read_day[24] = '\0'; + + fseek(fp, 0, SEEK_SET); + + if (!(csv_output || json_output)) { + if (show_last) { + tm_time = localtime(&time_last_scan); + strftime(read_day, 23, "%Y %h %d %T", tm_time); + + printf("\nLast scan: %s\n\n", read_day); + } else if (resolved) { + printf("\nResolved events: \n\n"); + } else { + printf("\nOutstanding events: \n\n"); + } + } + + while (fgets(buf, OS_MAXSTR, fp) != NULL) { + /* Remove first ! */ + tmp_str = buf + 1; + s_time = (time_t)atoi(tmp_str); + + /* Remove newline */ + tmp_str = strchr(buf, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + /* Get initial time */ + tmp_str = strchr(buf + 1, '!'); + if (!tmp_str) { + continue; + } + tmp_str++; + + i_time = (time_t)atoi(tmp_str); + + /* Get the actual message */ + tmp_str = strchr(tmp_str, ' '); + if (!tmp_str) { + continue; + } + tmp_str++; + + /* Check for resolved */ + if (time_last_scan > (s_time + 86400)) { + if (!resolved) { + continue; + } + } else { + if (resolved) { + continue; + } + } + + /* Check events to ignore */ + i = 0; + while (ig_events[i]) { + if (strncmp(tmp_str, ig_events[i], strlen(ig_events[i]) - 1) == 0) { + break; + } + i++; + } + if (ig_events[i]) { + continue; + } + + /* Check events that are not system audit */ + i = 0; + while (ns_events[i]) { + if (strncmp(tmp_str, ns_events[i], strlen(ns_events[i]) - 1) == 0) { + break; + } + i++; + } + + tm_time = localtime((time_t *)&s_time); + strftime(read_day, 23, "%Y %h %d %T", tm_time); + tm_time = localtime((time_t *)&i_time); + strftime(old_day, 23, "%Y %h %d %T", tm_time); + + if (json_output) { + cJSON *event = cJSON_CreateObject(); + cJSON_AddStringToObject(event, "status", resolved == 0 ? "outstanding" : "resolved"); + cJSON_AddStringToObject(event, "readDay", read_day); + cJSON_AddStringToObject(event, "oldDay", old_day); + + if (ns_events[i]) + cJSON_AddStringToObject(event, "event", tmp_str); + else { + char json_buffer[OS_MAXSTR + 1]; + snprintf(json_buffer, OS_MAXSTR, "%s%s", ns_events[i], tmp_str); + cJSON_AddStringToObject(event, "event", json_buffer); + } + + cJSON_AddItemToArray(json_output, event); + } else if (csv_output) { + printf("%s,%s,%s,%s%s\n", resolved == 0 ? "outstanding" : "resolved", + read_day, old_day, + ns_events[i] != NULL ? "" : "System Audit: ", + tmp_str); + } else { + if (!show_last) { + printf("%s (first time detected: %s)\n", read_day, old_day); + } + + if (ns_events[i]) { + printf("%s\n\n", tmp_str); + } else { + printf("System Audit: %s\n\n", tmp_str); + } + } + + f_found++; + } + + if (!f_found && !(csv_output || json_output)) { + printf("** No entries found.\n"); + } + + return (0); +} + +/* Print rootcheck db */ +int print_rootcheck(const char *sk_name, const char *sk_ip, const char *fname, + int resolved, int csv_output, cJSON *json_output, int show_last) +{ + int ltime = 0; + FILE *fp; + char tmp_file[513]; + + tmp_file[512] = '\0'; + + if (sk_name == NULL) { + /* Print database */ + snprintf(tmp_file, 512, "%s/rootcheck", + ROOTCHECK_DIR); + + fp = fopen(tmp_file, "r+"); + } else { + /* Print database */ + snprintf(tmp_file, 512, "%s/(%s) %s->rootcheck", + ROOTCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "r+"); + } + + if (fp) { + /* Get last time of scan */ + ltime = _do_get_rootcheckscan(fp); + if (!fname) { + if (resolved == 1) { + _do_print_rootcheck(fp, 1, ltime, csv_output, json_output, 0); + } else if (resolved == 2) { + _do_print_rootcheck(fp, 0, ltime, csv_output, json_output, show_last); + } else { + _do_print_rootcheck(fp, 1, ltime, csv_output, json_output, 0); + _do_print_rootcheck(fp, 0, ltime, csv_output, json_output, show_last); + + } + } + fclose(fp); + } + + return (0); +} + +#endif + +/* Delete syscheck db */ +int delete_syscheck(const char *sk_name, const char *sk_ip, int full_delete) +{ + FILE *fp; + char tmp_file[513]; + + tmp_file[512] = '\0'; + + /* Delete related files */ + snprintf(tmp_file, 512, "%s/(%s) %s->syscheck", + SYSCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "w"); + if (fp) { + fclose(fp); + } + + if (full_delete) { + if ((unlink(tmp_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, tmp_file, strerror(errno)); + } + } + + /* Delete cpt files */ + snprintf(tmp_file, 512, "%s/.(%s) %s->syscheck.cpt", + SYSCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "w"); + if (fp) { + fclose(fp); + } + if ((unlink(tmp_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, tmp_file, strerror(errno)); + } + + /* Delete registry entries */ + snprintf(tmp_file, 512, "%s/(%s) %s->syscheck-registry", + SYSCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "w"); + if (fp) { + fclose(fp); + } + if (full_delete) { + if ((unlink(tmp_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, tmp_file, strerror(errno)); + } + } + + /* Delete cpt files */ + snprintf(tmp_file, 512, "%s/.(%s) %s->syscheck-registry.cpt", + SYSCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "w"); + if (fp) { + fclose(fp); + } + if ((unlink(tmp_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, tmp_file, strerror(errno)); + } + + return (1); +} + +/* Delete rootcheck db */ +int delete_rootcheck(const char *sk_name, const char *sk_ip, int full_delete) +{ + FILE *fp; + char tmp_file[513]; + + tmp_file[512] = '\0'; + + /* Delete related files */ + snprintf(tmp_file, 512, "%s/(%s) %s->rootcheck", + ROOTCHECK_DIR, + sk_name, + sk_ip); + + fp = fopen(tmp_file, "w"); + if (fp) { + fclose(fp); + } + + if (full_delete) { + if ((unlink(tmp_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, tmp_file, strerror(errno)); + } + } + + return (1); +} + +/* Delete agent */ +int delete_agentinfo(const char *name) +{ + const char *sk_name; + char *sk_ip; + char tmp_file[513]; + + tmp_file[512] = '\0'; + + /* Delete agent info */ + snprintf(tmp_file, 512, "%s/%s", AGENTINFO_DIR, name); + if ((unlink(tmp_file)) < 0) { + merror("%s: ERROR: Cannot unlink %s: %s", __local_name, tmp_file, strerror(errno)); + } + + /* Delete syscheck */ + sk_name = name; + sk_ip = strrchr(name, '-'); + if (!sk_ip) { + return (0); + } + + *sk_ip = '\0'; + sk_ip++; + + /* Delete syscheck */ + delete_syscheck(sk_name, sk_ip, 1); + + /* Delete rootcheck */ + delete_rootcheck(sk_name, sk_ip, 1); + + return (1); +} + +/* Print the text representation of the agent status */ +const char *print_agent_status(int status) +{ + const char *status_str = "Never connected"; + + if (status == GA_STATUS_ACTIVE) { + status_str = "Active"; + } else if (status == GA_STATUS_NACTIVE) { + status_str = "Disconnected"; + } + + return (status_str); +} + +#ifndef WIN32 +/* Non-windows functions from now on */ + +/* Send a message to an agent + * Returns -1 on error + */ +int send_msg_to_agent(int msocket, const char *msg, const char *agt_id, const char *exec) +{ + int rc; + char agt_msg[OS_SIZE_1024 + 1]; + + agt_msg[OS_SIZE_1024] = '\0'; + + if (!exec) { + snprintf(agt_msg, OS_SIZE_1024, + "%s %c%c%c %s %s", + "(msg_to_agent) []", + (agt_id == NULL) ? ALL_AGENTS_C : NONE_C, + NO_AR_C, + (agt_id != NULL) ? SPECIFIC_AGENT_C : NONE_C, + agt_id != NULL ? agt_id : "(null)", + msg); + } else { + snprintf(agt_msg, OS_SIZE_1024, + "%s %c%c%c %s %s - %s (from_the_server) (no_rule_id)", + "(msg_to_agent) []", + (agt_id == NULL) ? ALL_AGENTS_C : NONE_C, + NONE_C, + (agt_id != NULL) ? SPECIFIC_AGENT_C : NONE_C, + agt_id != NULL ? agt_id : "(null)", + msg, exec); + + } + + if ((rc = OS_SendUnix(msocket, agt_msg, 0)) < 0) { + if (rc == OS_SOCKBUSY) { + merror("%s: ERROR: Remoted socket busy.", __local_name); + } else { + merror("%s: ERROR: Remoted socket error.", __local_name); + } + merror("%s: Error communicating with remoted queue (%d).", + __local_name, rc); + + return (-1); + } + + return (0); +} + +/* Connect to remoted to be able to send messages to the agents + * Returns the socket on success or -1 on failure + */ +int connect_to_remoted() +{ + int arq = -1; + + if ((arq = StartMQ(ARQUEUE, WRITE)) < 0) { + merror(ARQ_ERROR, __local_name); + return (-1); + } + + return (arq); +} + +const char *agent_file_perm(char *perm) +{ + /* rwxrwxrwx0 -> 10 */ + static char permissions[10]; + mode_t mode = 0; + + /* octal or decimal */ + mode = (mode_t) strtoul(perm, 0, strlen(perm) == 3 ? 8 : 10); + + permissions[0] = (mode & S_IRUSR) ? 'r' : '-'; + permissions[1] = (mode & S_IWUSR) ? 'w' : '-'; + permissions[2] = (mode & S_ISUID) ? 's' : (mode & S_IXUSR) ? 'x' : '-'; + permissions[3] = (mode & S_IRGRP) ? 'r' : '-'; + permissions[4] = (mode & S_IWGRP) ? 'w' : '-'; + permissions[5] = (mode & S_ISGID) ? 's' : (mode & S_IXGRP) ? 'x' : '-'; + permissions[6] = (mode & S_IROTH) ? 'r' : '-'; + permissions[7] = (mode & S_IWOTH) ? 'w' : '-'; + permissions[8] = (mode & S_ISVTX) ? 't' : (mode & S_IXOTH) ? 'x' : '-'; + permissions[9] = '\0'; + + return &permissions[0]; +} + +#endif /* !WIN32 */ + +/* Internal function. Extract last time of scan from rootcheck/syscheck. */ +static int _get_time_rkscan(const char *agent_name, const char *agent_ip, agent_info *agt_info) +{ + FILE *fp; + char buf[1024 + 1]; + + /* Agent name of null, means it is the server info */ + if (agent_name == NULL) { + snprintf(buf, 1024, "%s/rootcheck", + ROOTCHECK_DIR); + } else { + snprintf(buf, 1024, "%s/(%s) %s->rootcheck", + ROOTCHECK_DIR, agent_name, agent_ip); + } + + /* If file is not there, set to unknown */ + fp = fopen(buf, "r"); + if (!fp) { + os_strdup("Unknown", agt_info->rootcheck_time); + os_strdup("Unknown", agt_info->rootcheck_endtime); + os_strdup("Unknown", agt_info->syscheck_time); + os_strdup("Unknown", agt_info->syscheck_endtime); + return (0); + } + + while (fgets(buf, 1024, fp) != NULL) { + char *tmp_str = NULL; + + /* Remove newline */ + tmp_str = strchr(buf, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + tmp_str = strstr(buf, "Starting syscheck scan"); + if (tmp_str) { + time_t s_time = 0; + tmp_str = buf + 1; + + s_time = (time_t)atoi(tmp_str); + os_strdup(ctime(&s_time), agt_info->syscheck_time); + + /* Remove newline */ + tmp_str = strchr(agt_info->syscheck_time, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + continue; + } + + tmp_str = strstr(buf, "Ending syscheck scan"); + if (tmp_str) { + time_t s_time = 0; + tmp_str = buf + 1; + + s_time = (time_t)atoi(tmp_str); + + os_strdup(ctime(&s_time), agt_info->syscheck_endtime); + + /* Remove newline */ + tmp_str = strchr(agt_info->syscheck_endtime, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + continue; + } + + tmp_str = strstr(buf, "Starting rootcheck scan"); + if (tmp_str) { + time_t s_time = 0; + tmp_str = buf + 1; + + s_time = (time_t)atoi(tmp_str); + + os_strdup(ctime(&s_time), agt_info->rootcheck_time); + + /* Remove newline */ + tmp_str = strchr(agt_info->rootcheck_time, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + continue; + } + + tmp_str = strstr(buf, "Ending rootcheck scan"); + if (tmp_str) { + time_t s_time = 0; + tmp_str = buf + 1; + s_time = (time_t)atoi(tmp_str); + os_strdup(ctime(&s_time), agt_info->rootcheck_endtime); + + /* Remove newline */ + tmp_str = strchr(agt_info->rootcheck_endtime, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + continue; + } + } + + /* Set unknown values */ + if (!agt_info->rootcheck_time) { + os_strdup("Unknown", agt_info->rootcheck_time); + } + if (!agt_info->rootcheck_endtime) { + os_strdup("Unknown", agt_info->rootcheck_endtime); + } + if (!agt_info->syscheck_time) { + os_strdup("Unknown", agt_info->syscheck_time); + } + if (!agt_info->syscheck_endtime) { + os_strdup("Unknown", agt_info->syscheck_endtime); + } + + fclose(fp); + return (0); +} + +/* Internal function. Extract last time of scan from rootcheck/syscheck. */ +static char *_get_agent_keepalive(const char *agent_name, const char *agent_ip) +{ + char buf[1024 + 1]; + struct stat file_status; + + /* No keepalive for the server */ + if (!agent_name) { + return (strdup("Not available")); + } + + snprintf(buf, 1024, "%s/%s-%s", AGENTINFO_DIR, agent_name, agent_ip); + if (stat(buf, &file_status) < 0) { + return (strdup("Unknown")); + } + + return (strdup(ctime(&file_status.st_mtime))); +} + +/* Internal function. Extract operating system. */ +static int _get_agent_os(const char *agent_name, const char *agent_ip, agent_info *agt_info) +{ + FILE *fp; + char buf[1024 + 1]; + + /* Get server info */ + if (!agent_name) { + char *openarmor_version = NULL; + agt_info->os = getuname(); + os_strdup(__openarmor_name " " __openarmor_version, agt_info->version); + + /* Remove newline */ + openarmor_version = strchr(agt_info->os, '\n'); + if (openarmor_version) { + *openarmor_version = '\0'; + } + + openarmor_version = strstr(agt_info->os, " - "); + if (openarmor_version) { + *openarmor_version = '\0'; + } + + return (0); + } + + snprintf(buf, 1024, "%s/%s-%s", AGENTINFO_DIR, agent_name, agent_ip); + fp = fopen(buf, "r"); + if (!fp) { + os_strdup("Unknown", agt_info->os); + os_strdup("Unknown", agt_info->version); + return (0); + } + + if (fgets(buf, 1024, fp)) { + char *openarmor_version = NULL; + + /* Remove newline */ + openarmor_version = strchr(buf, '\n'); + if (openarmor_version) { + *openarmor_version = '\0'; + } + + openarmor_version = strstr(buf, " - "); + if (openarmor_version) { + *openarmor_version = '\0'; + openarmor_version += 3; + + os_calloc(1024 + 1, sizeof(char), agt_info->version); + strncpy(agt_info->version, openarmor_version, 1024); + } + + os_strdup(buf, agt_info->os); + fclose(fp); + + return (1); + } + + fclose(fp); + + os_strdup("Unknown", agt_info->os); + os_strdup("Unknown", agt_info->version); + + return (0); +} + +/* Get information from an agent */ +agent_info *get_agent_info(const char *agent_name, const char *agent_ip) +{ + char *agent_ip_pt = NULL; + char *tmp_str = NULL; + + agent_info *agt_info = NULL; + + /* Remove the "/", since it is not present on the file */ + if ((agent_ip_pt = strchr(agent_ip, '/'))) { + *agent_ip_pt = '\0'; + } + + /* Allocate memory for the info structure */ + os_calloc(1, sizeof(agent_info), agt_info); + + /* Zero the values */ + agt_info->rootcheck_time = NULL; + agt_info->rootcheck_endtime = NULL; + agt_info->syscheck_time = NULL; + agt_info->syscheck_endtime = NULL; + agt_info->os = NULL; + agt_info->version = NULL; + agt_info->last_keepalive = NULL; + + /* Get information about the OS */ + _get_agent_os(agent_name, agent_ip, agt_info); + _get_time_rkscan(agent_name, agent_ip, agt_info); + agt_info->last_keepalive = _get_agent_keepalive(agent_name, agent_ip); + + /* Remove newline from keepalive */ + tmp_str = strchr(agt_info->last_keepalive, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } + + /* Set back the IP address */ + if (agent_ip_pt) { + *agent_ip_pt = '/'; + } + + return (agt_info); +} + +/* Gets the status of an agent, based on the name / IP address */ +int get_agent_status(const char *agent_name, const char *agent_ip) +{ + char tmp_file[513]; + char *agent_ip_pt = NULL; + struct stat file_status; + + tmp_file[512] = '\0'; + + /* Server info */ + if (agent_name == NULL) { + return (GA_STATUS_ACTIVE); + } + + /* Remove the "/", since it is not present on the file */ + if ((agent_ip_pt = strchr(agent_ip, '/'))) { + *agent_ip_pt = '\0'; + } + + snprintf(tmp_file, 512, "%s/%s-%s", AGENTINFO_DIR, agent_name, agent_ip); + + /* Set back the IP address */ + if (agent_ip_pt) { + *agent_ip_pt = '/'; + } + + if (stat(tmp_file, &file_status) < 0) { + return (GA_STATUS_INV); + } + + if (file_status.st_mtime > (time(0) - (3 * NOTIFY_TIME + 30))) { + return (GA_STATUS_ACTIVE); + } + + return (GA_STATUS_NACTIVE); +} + +/* List available agents with specified timeout */ +char **get_agents_with_timeout(int flag, int timeout) +{ + size_t f_size = 0; + char **f_files = NULL; + DIR *dp; + struct dirent *entry; + + /* Open the directory */ + dp = opendir(AGENTINFO_DIR); + if (!dp) { + merror("%s: Error opening directory: '%s': %s ", + __local_name, + AGENTINFO_DIR, + strerror(errno)); + return (NULL); + } + + /* Read directory */ + while ((entry = readdir(dp)) != NULL) { + int status = 0; + char tmp_file[513]; + tmp_file[512] = '\0'; + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + snprintf(tmp_file, 512, "%s/%s", AGENTINFO_DIR, entry->d_name); + + if (flag != GA_ALL) { + struct stat file_status; + + if (stat(tmp_file, &file_status) < 0) { + continue; + } + + if (file_status.st_mtime > (time(0) - (3 * timeout + 30))) { + status = 1; + if (flag == GA_NOTACTIVE) { + continue; + } + } else { + if (flag == GA_ACTIVE) { + continue; + } + } + } + + f_files = (char **)realloc(f_files, (f_size + 2) * sizeof(char *)); + if (!f_files) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + + /* Add agent entry */ + if (flag == GA_ALL_WSTATUS) { + char agt_stat[512]; + + snprintf(agt_stat, sizeof(agt_stat) - 1, "%s %s", + entry->d_name, status == 1 ? "active" : "disconnected"); + + os_strdup(agt_stat, f_files[f_size]); + } else { + os_strdup(entry->d_name, f_files[f_size]); + } + + f_files[f_size + 1] = NULL; + + f_size++; + } + + closedir(dp); + return (f_files); +} + +/* List available agents */ +char **get_agents(int flag) { + return get_agents_with_timeout(flag, NOTIFY_TIME); +} diff --git a/src/shared/read-alert.c b/src/shared/read-alert.c new file mode 100644 index 000000000..43afe5808 --- /dev/null +++ b/src/shared/read-alert.c @@ -0,0 +1,663 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* File monitoring functions */ + +#include "shared.h" +#include "read-alert.h" + +/* ** Alert xyz: email active-response ** */ + +#define ALERT_BEGIN "** Alert" +#define ALERT_BEGIN_SZ 8 +#define RULE_BEGIN "Rule: " +#define RULE_BEGIN_SZ 6 +#define SRCIP_BEGIN "Src IP: " +#define SRCIP_BEGIN_SZ 8 + +#ifdef LIBGEOIP_ENABLED +#define GEOIP_BEGIN_SRC "Src Location: " +#define GEOIP_BEGIN_SRC_SZ 14 +#define GEOIP_BEGIN_DST "Dst Location: " +#define GEOIP_BEGIN_DST_SZ 14 +#endif /* LIBGEOIP_ENABLED */ + +#define SRCPORT_BEGIN "Src Port: " +#define SRCPORT_BEGIN_SZ 10 +#define DSTIP_BEGIN "Dst IP: " +#define DSTIP_BEGIN_SZ 8 +#define DSTPORT_BEGIN "Dst Port: " +#define DSTPORT_BEGIN_SZ 10 +#define USER_BEGIN "User: " +#define USER_BEGIN_SZ 6 +#define ALERT_MAIL "mail" +#define ALERT_MAIL_SZ 4 +#define OLDMD5_BEGIN "Old md5sum was: " +#define OLDMD5_BEGIN_SZ 16 +#define NEWMD5_BEGIN "New md5sum is : " +#define NEWMD5_BEGIN_SZ 16 +#define OLDSHA1_BEGIN "Old sha1sum was: " +#define OLDSHA1_BEGIN_SZ 17 +#define NEWSHA1_BEGIN "New sha1sum is : " +#define NEWSHA1_BEGIN_SZ 17 +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ +#define SIZE_BEGIN "Size changed from " +#define SIZE_BEGIN_SZ 18 +#define OWNER_BEGIN "Ownership was " +#define OWNER_BEGIN_SZ 14 +#define GROUP_BEGIN "Group ownership was " +#define GROUP_BEGIN_SZ 20 +#define PERM_BEGIN "Permissions changed from " +#define PERM_BEGIN_SZ 25 +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + + +void FreeAlertData(alert_data *al_data) +{ + char **p; + + if (al_data->alertid) { + free(al_data->alertid); + al_data->alertid = NULL; + } + if (al_data->date) { + free(al_data->date); + al_data->date = NULL; + } + if (al_data->location) { + free(al_data->location); + al_data->location = NULL; + } + if (al_data->comment) { + free(al_data->comment); + al_data->comment = NULL; + } + if (al_data->group) { + free(al_data->group); + al_data->group = NULL; + } + if (al_data->srcip) { + free(al_data->srcip); + al_data->srcip = NULL; + } + if (al_data->dstip) { + free(al_data->dstip); + al_data->dstip = NULL; + } + if (al_data->user) { + free(al_data->user); + al_data->user = NULL; + } + if (al_data->filename) { + free(al_data->filename); + al_data->filename = NULL; + } + if (al_data->old_md5) { + free(al_data->old_md5); + al_data->old_md5 = NULL; + } + if (al_data->new_md5) { + free(al_data->new_md5); + al_data->new_md5 = NULL; + } + if (al_data->old_sha1) { + free(al_data->old_sha1); + al_data->old_sha1 = NULL; + } + if (al_data->new_sha1) { + free(al_data->new_sha1); + al_data->new_sha1 = NULL; + } +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + if(al_data->file_size) + { + free(al_data->file_size); + al_data->file_size = NULL; + } + if(al_data->owner_chg) + { + free(al_data->owner_chg); + al_data->owner_chg = NULL; + } + if(al_data->group_chg) + { + free(al_data->group_chg); + al_data->group_chg = NULL; + } + if(al_data->perm_chg) + { + free(al_data->perm_chg); + al_data->perm_chg = NULL; + } +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + if (al_data->log) { + p = al_data->log; + + while (*(p)) { + free(*(p)); + *(p) = NULL; + p++; + } + free(al_data->log); + al_data->log = NULL; + } +#ifdef LIBGEOIP_ENABLED + if (al_data->srcgeoip) { + free(al_data->srcgeoip); + al_data->srcgeoip = NULL; + } + if (al_data->dstgeoip) { + free(al_data->dstgeoip); + al_data->dstgeoip = NULL; + } +#endif + free(al_data); + al_data = NULL; +} + +/* Return alert data for the file specified */ +alert_data *GetAlertData(int flag, FILE *fp) +{ + int _r = 0, issyscheck = 0; + size_t log_size = 0; + char *p; + + char *alertid = NULL; + char *date = NULL; + char *comment = NULL; + char *location = NULL; + char *srcip = NULL; + char *dstip = NULL; + char *user = NULL; + char *group = NULL; + char *filename = NULL; + char *old_md5 = NULL; + char *new_md5 = NULL; + char *old_sha1 = NULL; + char *new_sha1 = NULL; + char **log = NULL; +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + char *file_size = NULL; + char *owner_chg = NULL; + char *group_chg = NULL; + char *perm_chg = NULL; +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ +#ifdef LIBGEOIP_ENABLED + char *srcgeoip = NULL; + char *dstgeoip = NULL; +#endif + int level = 0, rule = 0, srcport = 0, dstport = 0; + + char str[OS_BUFFER_SIZE + 1]; + str[OS_BUFFER_SIZE] = '\0'; + + while (fgets(str, OS_BUFFER_SIZE, fp) != NULL) { + /* End of alert */ + if (strcmp(str, "\n") == 0 && log_size > 0) { + /* Found in here */ + if (_r == 2) { + alert_data *al_data; + os_calloc(1, sizeof(alert_data), al_data); + al_data->alertid = alertid; + al_data->level = level; + al_data->rule = rule; + al_data->location = location; + al_data->comment = comment; + al_data->group = group; + al_data->log = log; + al_data->srcip = srcip; + al_data->srcport = srcport; + al_data->dstip = dstip; + al_data->dstport = dstport; + al_data->user = user; + al_data->date = date; + al_data->filename = filename; +#ifdef LIBGEOIP_ENABLED + al_data->srcgeoip = srcgeoip ; + al_data->dstgeoip = dstgeoip; +#endif + al_data->old_md5 = old_md5; + al_data->new_md5 = new_md5; + al_data->old_sha1 = old_sha1; + al_data->new_sha1 = new_sha1; + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + al_data->file_size = file_size; + al_data->owner_chg = owner_chg; + al_data->group_chg = group_chg; + al_data->perm_chg = perm_chg; + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + + + return (al_data); + } + _r = 0; + } + + /* Check for the header */ + if (strncmp(ALERT_BEGIN, str, ALERT_BEGIN_SZ) == 0) { + char *m; + size_t z = 0; + p = str + ALERT_BEGIN_SZ + 1; + + m = strstr(p, ":"); + if (!m) { + continue; + } + + z = strlen(p) - strlen(m); + os_realloc(alertid, (z + 1)*sizeof(char), alertid); + strncpy(alertid, p, z); + alertid[z] = '\0'; + + /* Search for email flag */ + p = strchr(p, ' '); + if (!p) { + continue; + } + + p++; + + /* Check for the flags */ + if ((flag & CRALERT_MAIL_SET) && + (strncmp(ALERT_MAIL, p, ALERT_MAIL_SZ) != 0)) { + continue; + } + + p = strchr(p, '-'); + if (p) { + p++; + free(group); + os_strdup(p, group); + + /* Clean newline from group */ + os_clearnl(group, p); + if (group != NULL && strstr(group, "syscheck") != NULL) { + issyscheck = 1; + } + } + + /* Search for active-response flag */ + _r = 1; + continue; + } + + if (_r < 1) { + continue; + } + + /*** Extract information from the event ***/ + + /* r1 means: 2006 Apr 13 16:15:17 /var/log/auth.log */ + if (_r == 1) { + /* Clear newline */ + os_clearnl(str, p); + + p = strchr(str, ':'); + if (p) { + p = strchr(p, ' '); + if (p) { + *p = '\0'; + p++; + } else { + /* If p is null it is because strchr failed */ + merror("%s: ERROR: date or location not NULL", __local_name); + goto l_error; + } + } + + /* If not, str is date and p is the location */ + if (date || location || !p) { + merror("%s: ERROR: date or location not NULL or p is NULL", __local_name); + goto l_error; + } + + os_strdup(str, date); + os_strdup(p, location); + _r = 2; + log_size = 0; + continue; + } else if (_r == 2) { + /* Rule begin */ + if (strncmp(RULE_BEGIN, str, RULE_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + RULE_BEGIN_SZ; + rule = atoi(p); + + p = strchr(p, ' '); + if (p) { + p++; + p = strchr(p, ' '); + if (p) { + p++; + } + } + + if (!p) { + goto l_error; + } + + level = atoi(p); + + /* Get the comment */ + p = strchr(p, '\''); + if (!p) { + goto l_error; + } + + p++; + free(comment); + os_strdup(p, comment); + + /* Must have the closing \' */ + p = strrchr(comment, '\''); + if (p) { + *p = '\0'; + } else { + goto l_error; + } + } + + /* srcip */ + else if (strncmp(SRCIP_BEGIN, str, SRCIP_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + SRCIP_BEGIN_SZ; + free(srcip); + os_strdup(p, srcip); + } +#ifdef LIBGEOIP_ENABLED + /* GeoIP Source Location */ + else if (strncmp(GEOIP_BEGIN_SRC, str, GEOIP_BEGIN_SRC_SZ) == 0) { + os_clearnl(str, p); + p = str + GEOIP_BEGIN_SRC_SZ; + free(srcgeoip); + os_strdup(p, srcgeoip); + } +#endif + /* srcport */ + else if (strncmp(SRCPORT_BEGIN, str, SRCPORT_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + SRCPORT_BEGIN_SZ; + srcport = atoi(p); + } + /* dstip */ + else if (strncmp(DSTIP_BEGIN, str, DSTIP_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + DSTIP_BEGIN_SZ; + free(dstip); + os_strdup(p, dstip); + } +#ifdef LIBGEOIP_ENABLED + /* GeoIP Destination Location */ + else if (strncmp(GEOIP_BEGIN_DST, str, GEOIP_BEGIN_DST_SZ) == 0) { + os_clearnl(str, p); + p = str + GEOIP_BEGIN_DST_SZ; + free(dstgeoip); + os_strdup(p, dstgeoip); + } +#endif + /* dstport */ + else if (strncmp(DSTPORT_BEGIN, str, DSTPORT_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + DSTPORT_BEGIN_SZ; + dstport = atoi(p); + } + /* username */ + else if (strncmp(USER_BEGIN, str, USER_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + USER_BEGIN_SZ; + free(user); + os_strdup(p, user); + } + /* Old MD5 */ + else if (strncmp(OLDMD5_BEGIN, str, OLDMD5_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + OLDMD5_BEGIN_SZ; + free(old_md5); + os_strdup(p, old_md5); + } + /* New MD5 */ + else if (strncmp(NEWMD5_BEGIN, str, NEWMD5_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + NEWMD5_BEGIN_SZ; + free(new_md5); + os_strdup(p, new_md5); + } + /* Old SHA-1 */ + else if (strncmp(OLDSHA1_BEGIN, str, OLDSHA1_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + OLDSHA1_BEGIN_SZ; + free(old_sha1); + os_strdup(p, old_sha1); + } + /* New SHA-1 */ + else if (strncmp(NEWSHA1_BEGIN, str, NEWSHA1_BEGIN_SZ) == 0) { + os_clearnl(str, p); + + p = str + NEWSHA1_BEGIN_SZ; + free(new_sha1); + os_strdup(p, new_sha1); + } + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + /* File Size */ + else if(strncmp(SIZE_BEGIN, str, SIZE_BEGIN_SZ) == 0) + { + os_clearnl(str,p); + + p = str + SIZE_BEGIN_SZ; + if(file_size) { + free(file_size); + } + os_strdup(p, file_size); + } + /* File Ownership */ + else if(strncmp(OWNER_BEGIN, str, OWNER_BEGIN_SZ) == 0) + { + os_clearnl(str,p); + + p = str + OWNER_BEGIN_SZ; + if(owner_chg) { + free(owner_chg); + } + os_strdup(p, owner_chg); + } + /* File Group Ownership */ + else if(strncmp(GROUP_BEGIN, str, GROUP_BEGIN_SZ) == 0) + { + os_clearnl(str,p); + + p = str + GROUP_BEGIN_SZ; + if(group_chg) { + free(group_chg); + } + os_strdup(p, group_chg); + } + /* File Permissions */ + else if(strncmp(PERM_BEGIN, str, PERM_BEGIN_SZ) == 0) + { + os_clearnl(str,p); + + p = str + PERM_BEGIN_SZ; + if(perm_chg) { + free(perm_chg); + } + os_strdup(p, perm_chg); + } + /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + /* It is a log message */ + else if (log_size < 20) { + os_clearnl(str, p); + + if (issyscheck == 1) { + if (strncmp(str, "Integrity checksum changed for: '", 33) == 0) { + filename = strdup(str + 33); + if (filename) { + filename[strlen(filename) - 1] = '\0'; + } + } + issyscheck = 0; + } + + os_realloc(log, (log_size + 2)*sizeof(char *), log); + os_strdup(str, log[log_size]); + log_size++; + log[log_size] = NULL; + } + } + + continue; +l_error: + /* Free the memory */ + _r = 0; + if (date) { + free(date); + date = NULL; + } + if (location) { + free(location); + location = NULL; + } + if (comment) { + free(comment); + comment = NULL; + } + if (srcip) { + free(srcip); + srcip = NULL; + } +#ifdef LIBGEOIP_ENABLED + if (srcgeoip) { + free(srcgeoip); + srcgeoip = NULL; + } + if (dstgeoip) { + free(dstgeoip); + dstgeoip = NULL; + } +#endif + if (user) { + free(user); + user = NULL; + } + if (filename) { + free(filename); + filename = NULL; + } + if (group) { + free(group); + group = NULL; + } + if (old_md5) { + free(old_md5); + old_md5 = NULL; + } + + if (new_md5) { + free(new_md5); + new_md5 = NULL; + } + + if (old_sha1) { + free(old_sha1); + old_sha1 = NULL; + } + + if (new_sha1) { + free(new_sha1); + new_sha1 = NULL; + } +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + if(file_size) + { + free(file_size); + file_size = NULL; + } + if(owner_chg) + { + free(owner_chg); + owner_chg = NULL; + } + if(group_chg) + { + free(group_chg); + group_chg = NULL; + } + if(perm_chg) + { + free(perm_chg); + perm_chg = NULL; + } +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + while (log_size > 0) { + log_size--; + if (log[log_size]) { + free(log[log_size]); + log[log_size] = NULL; + } + } + } + + if (alertid) { + free(alertid); + alertid = NULL; + } + if (group) { + free(group); + group = NULL; + } + if (location) { + free(location); + location = NULL; + } + if (date) { + free(date); + date = NULL; + } + + while (log_size > 0) { + log_size--; + if (log[log_size]) { + free(log[log_size]); + log[log_size] = NULL; + } + } + + free(log); + free(comment); + free(srcip); + free(dstip); + free(user); + free(old_md5); + free(new_md5); + free(old_sha1); + free(new_sha1); + free(filename); +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ + free(file_size); + free(owner_chg); + free(group_chg); + free(perm_chg); +/* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ +#ifdef LIBGEOIP_ENABLED + free(srcgeoip); + free(dstgeoip); +#endif + + /* We need to clean end of file before returning */ + clearerr(fp); + return (NULL); +} diff --git a/src/shared/regex_op.c b/src/shared/regex_op.c new file mode 100644 index 000000000..fe273816e --- /dev/null +++ b/src/shared/regex_op.c @@ -0,0 +1,43 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef WIN32 +#include + +#include "shared.h" + + +/* Compile a POSIX regex, returning NULL on error + * Returns 1 if matches, 0 if not + */ +int OS_PRegex(const char *str, const char *regex) +{ + regex_t preg; + + if (!str || !regex) { + return (0); + } + + if (regcomp(&preg, regex, REG_EXTENDED | REG_NOSUB) != 0) { + merror("%s: Posix Regex compile error (%s).", __local_name, regex); + return (0); + } + + if (regexec(&preg, str, strlen(str), NULL, 0) != 0) { + /* Didn't match */ + regfree(&preg); + return (0); + } + + regfree(&preg); + return (1); + +} + +#endif /* !WIN32 */ diff --git a/src/shared/report_op.c b/src/shared/report_op.c new file mode 100644 index 000000000..813bc74c3 --- /dev/null +++ b/src/shared/report_op.c @@ -0,0 +1,746 @@ +/* Copyright (C) 2019 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" + +/* Helper functions */ +static void l_print_out(const char *msg, ...) __attribute__((format(printf, 1, 2))) __attribute__((nonnull)); +static void *_os_report_sort_compare(void *d1, void *d2) __attribute__((nonnull)); +static void _os_header_print(int t, const char *hname) __attribute__((nonnull)); +static int _os_report_str_int_compare(const char *str, int id) __attribute__((nonnull)); +static int _os_report_check_filters(const alert_data *al_data, const report_filter *r_filter) __attribute__((nonnull)); +static int _report_filter_value(const char *filter_by, int prev_filter) __attribute__((nonnull)); +static int _os_report_print_related(int print_related, OSList *st_data) __attribute__((nonnull)); +static int _os_report_add_tostore(const char *key, OSStore *top, void *data) __attribute__((nonnull(1, 2))); +static FILE *__g_rtype = NULL; + + +static void l_print_out(const char *msg, ...) +{ + va_list args; + va_start(args, msg); + + if (__g_rtype) { + (void)vfprintf(__g_rtype, msg, args); + (void)fprintf(__g_rtype, "\r\n"); + } else { + (void)vfprintf(stderr, msg, args); + (void)fprintf(stderr, "\r\n"); + } + va_end(args); +} + +/* Sort function used by OSStore sort + * Returns if d1 > d2 + */ +static void *_os_report_sort_compare(void *d1, void *d2) +{ + OSList *d1l = (OSList *)d1; + OSList *d2l = (OSList *)d2; + + if (d1l->currently_size > d2l->currently_size) { + return (d1l); + } + + return (NULL); +} + +/* Print output header */ +static void _os_header_print(int t, const char *hname) +{ + if (!t) { + l_print_out("Top entries for '%s':", hname); + l_print_out("------------------------------------------------"); + } else { + l_print_out("Related entries for '%s':", hname); + l_print_out("------------------------------------------------"); + } +} + +/* Compare if the id is present in the string */ +static int _os_report_str_int_compare(const char *str, int id) +{ + int pt_check = 0; + + do { + if ((*str == ',') || (*str == ' ')) { + pt_check = 0; + continue; + } else if (*str == '\0') { + break; + } else if (isdigit((int)*str)) { + if (pt_check == 0) { + if (id == atoi(str)) { + return (1); + } + } + pt_check = 1; + } else { + return (-1); + } + } while (*str++ != '\0'); + + return (0); +} + +/* Check if the al_data should be filtered */ +static int _os_report_check_filters(const alert_data *al_data, const report_filter *r_filter) +{ + /* Check for the filters */ + if (r_filter->group) { + if (al_data->group) { /* Probably unnecessary, all (?) alerts should have groups) */ + if (!strstr(al_data->group, r_filter->group)) { + return (0); + } + } + } + if (r_filter->rule) { + if (_os_report_str_int_compare(r_filter->rule, al_data->rule) != 1) { + return (0); + } + } + if (r_filter->location) { + if (!OS_Match(r_filter->location, al_data->location)) { + return (0); + } + } + if (r_filter->level) { + if (al_data->level < (unsigned int) atoi(r_filter->level)) { + return (0); + } + } + if (r_filter->srcip) { + if(!al_data->srcip) { + return(0); + } + if (al_data->srcip) { + if (!strstr(al_data->srcip, r_filter->srcip)) { + return (0); + } + } else { + return (0); + } + } + if (r_filter->user) { + if(!al_data->user) { + return(0); + } + if (al_data->user) { + if (!strstr(al_data->user, r_filter->user)) { + return (0); + } + } else { + return (0); + } + } + if (r_filter->files) { + if(!al_data->filename) { + return(0); + } + if (al_data->filename) { + if (!strstr(al_data->filename, r_filter->files)) { + return (0); + } + } else { + return (0); + } + } + return (1); +} + +/* Set the proper value for the related entries */ +static int _report_filter_value(const char *filter_by, int prev_filter) +{ + if (strcmp(filter_by, "group") == 0) { + if (!(prev_filter & REPORT_REL_GROUP)) { + prev_filter |= REPORT_REL_GROUP; + } + return (prev_filter); + } else if (strcmp(filter_by, "rule") == 0) { + if (!(prev_filter & REPORT_REL_RULE)) { + prev_filter |= REPORT_REL_RULE; + } + return (prev_filter); + } else if (strcmp(filter_by, "level") == 0) { + if (!(prev_filter & REPORT_REL_LEVEL)) { + prev_filter |= REPORT_REL_LEVEL; + } + return (prev_filter); + } else if (strcmp(filter_by, "location") == 0) { + if (!(prev_filter & REPORT_REL_LOCATION)) { + prev_filter |= REPORT_REL_LOCATION; + } + return (prev_filter); + } else if (strcmp(filter_by, "srcip") == 0) { + if (!(prev_filter & REPORT_REL_SRCIP)) { + prev_filter |= REPORT_REL_SRCIP; + } + return (prev_filter); + } else if (strcmp(filter_by, "user") == 0) { + if (!(prev_filter & REPORT_REL_USER)) { + prev_filter |= REPORT_REL_USER; + } + return (prev_filter); + } else if (strcmp(filter_by, "filename") == 0) { + if (!(prev_filter & REPORT_REL_FILE)) { + prev_filter |= REPORT_REL_FILE; + } + return (prev_filter); + } else { + merror("%s: ERROR: Invalid relation '%s'.", __local_name, filter_by); + return (-1); + } +} + +/* Print related entries */ +static int _os_report_print_related(int print_related, OSList *st_data) +{ + OSListNode *list_entry; + alert_data *list_aldata; + alert_data *saved_aldata; + + list_entry = OSList_GetFirstNode(st_data); + while (list_entry) { + saved_aldata = (alert_data *)list_entry->data; + + /* Remove duplicates */ + list_entry = list_entry->prev; + while (list_entry) { + if (print_related & REPORT_REL_LOCATION) { + list_aldata = (alert_data *)list_entry->data; + if (strcmp(list_aldata->location, saved_aldata->location) == 0) { + break; + } + } + + else if (print_related & REPORT_REL_GROUP) { + list_aldata = (alert_data *)list_entry->data; + if (strcmp(list_aldata->group, saved_aldata->group) == 0) { + break; + } + } + + else if (print_related & REPORT_REL_RULE) { + list_aldata = (alert_data *)list_entry->data; + if (list_aldata->rule == saved_aldata->rule) { + break; + } + } + + else if (print_related & REPORT_REL_USER) { + list_aldata = (alert_data *)list_entry->data; + if (list_aldata->user == NULL || saved_aldata->user == NULL) { + } else if (strcmp(list_aldata->user, saved_aldata->user) == 0) { + break; + } + } + + else if (print_related & REPORT_REL_SRCIP) { + list_aldata = (alert_data *)list_entry->data; + if (list_aldata->srcip == NULL || saved_aldata->srcip == NULL) { + } else if (strcmp(list_aldata->srcip, saved_aldata->srcip) == 0) { + break; + } + } + + else if (print_related & REPORT_REL_LEVEL) { + list_aldata = (alert_data *)list_entry->data; + if (list_aldata->level == saved_aldata->level) { + break; + } + } else if (print_related & REPORT_REL_FILE) { + list_aldata = (alert_data *)list_entry->data; + if (list_aldata->filename == NULL || saved_aldata->filename == NULL) { + } else if (strcmp(list_aldata->filename, saved_aldata->filename) == 0) { + break; + } + } + list_entry = list_entry->prev; + } + + if (!list_entry) { + if (print_related & REPORT_REL_LOCATION) { + l_print_out(" location: '%s'", saved_aldata->location); + } else if (print_related & REPORT_REL_GROUP) { + l_print_out(" group: '%s'", saved_aldata->group); + } else if (print_related & REPORT_REL_RULE) { + l_print_out(" rule: '%d'", saved_aldata->rule); + } else if ((print_related & REPORT_REL_SRCIP) && saved_aldata->srcip) { + l_print_out(" srcip: '%s'", saved_aldata->srcip); + } else if ((print_related & REPORT_REL_USER) && saved_aldata->user) { + l_print_out(" user: '%s'", saved_aldata->user); + } else if (print_related & REPORT_REL_LEVEL) { + l_print_out(" level: '%d'", saved_aldata->level); + } else if ((print_related & REPORT_REL_FILE) && saved_aldata->filename) { + l_print_out(" filename: '%s'", saved_aldata->filename); + } + } + + list_entry = OSList_GetNextNode(st_data); + } + + return (0); +} + +/* Add the entry to the hash */ +static int _os_report_add_tostore(const char *key, OSStore *top, void *data) +{ + OSList *top_list; + + /* Add data to the hash */ + top_list = (OSList *) OSStore_Get(top, key); + if (top_list) { + OSList_AddData(top_list, data); + } else { + top_list = OSList_Create(); + if (!top_list) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (0); + } + OSList_AddData(top_list, data); + + OSStore_Put(top, key, top_list); + } + + return (1); +} + +void os_report_printtop(void *topstore_pt, const char *hname, int print_related) +{ + int dopdout = 0; + OSStore *topstore = (OSStore *)topstore_pt; + OSStoreNode *next_node; + + next_node = OSStore_GetFirstNode(topstore); + while (next_node) { + OSList *st_data = (OSList *)next_node->data; + char *lkey = (char *)next_node->key; + + /* With location we leave more space to be clearer */ + if (!print_related) { + if (strlen(lkey) > 76) { + lkey[74] = '.'; + lkey[75] = '.'; + lkey[76] = '\0'; + } + + if (!dopdout) { + _os_header_print(print_related, hname); + dopdout = 1; + } + l_print_out("%-78s|%-8d|", (char *)next_node->key, st_data->currently_size); + } + + /* Print each destination */ + else { + if (!dopdout) { + _os_header_print(print_related, hname); + dopdout = 1; + } + l_print_out("%-78s|%-8d|", (char *)next_node->key, st_data->currently_size); + + if (print_related & REPORT_REL_LOCATION) { + _os_report_print_related(REPORT_REL_LOCATION, st_data); + } + if (print_related & REPORT_REL_SRCIP) { + _os_report_print_related(REPORT_REL_SRCIP, st_data); + } + if (print_related & REPORT_REL_USER) { + _os_report_print_related(REPORT_REL_USER, st_data); + } + if (print_related & REPORT_REL_RULE) { + _os_report_print_related(REPORT_REL_RULE, st_data); + } + if (print_related & REPORT_REL_GROUP) { + _os_report_print_related(REPORT_REL_GROUP, st_data); + } + if (print_related & REPORT_REL_LEVEL) { + _os_report_print_related(REPORT_REL_LEVEL, st_data); + } + if (print_related & REPORT_REL_FILE) { + _os_report_print_related(REPORT_REL_FILE, st_data); + } + } + + next_node = next_node->next; + } + + if (dopdout == 1) { + l_print_out(" "); + l_print_out(" "); + } + return; +} + +void os_ReportdStart(report_filter *r_filter) +{ + int alerts_processed = 0; + int alerts_filtered = 0; + char *first_alert = NULL; + char *last_alert = NULL; + alert_data **data_to_clean = NULL; + + time_t tm; + struct tm *p; + + file_queue *fileq; + alert_data *al_data; + + /* Get current time before starting */ + tm = time(NULL); + p = localtime(&tm); + + /* Initiate file queue - to read the alerts */ + os_calloc(1, sizeof(file_queue), fileq); + + if (r_filter->report_type == REPORT_TYPE_DAILY && r_filter->filename) { + fileq->fp = fopen(r_filter->filename, "r"); + if (!fileq->fp) { + merror("%s: ERROR: Unable to open alerts file to generate report.", __local_name); + goto cleanup; + } + if (r_filter->fp) { + __g_rtype = r_filter->fp; + } + } else { + fileq->fp = stdin; + } + + /* Create top hashes */ + r_filter->top_user = OSStore_Create(); + r_filter->top_srcip = OSStore_Create(); + r_filter->top_level = OSStore_Create(); + r_filter->top_rule = OSStore_Create(); + r_filter->top_group = OSStore_Create(); + r_filter->top_location = OSStore_Create(); + r_filter->top_files = OSStore_Create(); + + if (!r_filter->top_user || !r_filter->top_srcip || !r_filter->top_level || !r_filter->top_rule + || !r_filter->top_group || !r_filter->top_location || !r_filter->top_files) { + merror(MEM_ERROR, __local_name, errno, strerror((errno))); + + if (r_filter->top_user) { + OSStore_Free(r_filter->top_user); + } + if (r_filter->top_srcip) { + OSStore_Free(r_filter->top_srcip); + } + if (r_filter->top_level) { + OSStore_Free(r_filter->top_level); + } + if (r_filter->top_rule) { + OSStore_Free(r_filter->top_rule); + } + if (r_filter->top_group) { + OSStore_Free(r_filter->top_group); + } + if (r_filter->top_location) { + OSStore_Free(r_filter->top_location); + } + if (r_filter->top_files) { + OSStore_Free(r_filter->top_files); + } + + goto cleanup; + } + + + + Init_FileQueue(fileq, p, CRALERT_READ_ALL | CRALERT_FP_SET); + + /* Read the alerts */ + while (1) { + /* Get message if available */ + al_data = Read_FileMon(fileq, p, 1); + if (!al_data) { + break; + } + + alerts_processed++; + + /* Check the filters */ + if (!_os_report_check_filters(al_data, r_filter)) { + FreeAlertData(al_data); + continue; + } + + alerts_filtered++; + data_to_clean = (alert_data **) os_AddPtArray(al_data, (void **)data_to_clean); + + /* Set first and last alert for summary */ + if (!first_alert) { + first_alert = al_data->date; + } + last_alert = al_data->date; + + /* Add source IP if it is set properly */ + if (al_data->srcip != NULL && strcmp(al_data->srcip, "(none)") != 0) { + _os_report_add_tostore(al_data->srcip, r_filter->top_srcip, al_data); + } + + /* Add user if it is set properly */ + if (al_data->user != NULL && strcmp(al_data->user, "(none)") != 0) { + _os_report_add_tostore(al_data->user, r_filter->top_user, al_data); + } + + /* Add level and severity */ + { + char mlevel[16]; + char mrule[76 + 1]; + mrule[76] = '\0'; + snprintf(mlevel, 16, "Severity %d" , al_data->level); + snprintf(mrule, 76, "%d - %s" , al_data->rule, al_data->comment); + + _os_report_add_tostore(mlevel, r_filter->top_level, + al_data); + _os_report_add_tostore(mrule, r_filter->top_rule, + al_data); + } + + /* Deal with the group */ + { + char *tmp_str; + char **mgroup; + + mgroup = OS_StrBreak(',', al_data->group, 32); + if (mgroup) { + while (*mgroup) { + tmp_str = *mgroup; + while (*tmp_str == ' ') { + tmp_str++; + } + if (*tmp_str == '\0') { + free(*mgroup); + mgroup++; + continue; + } + + _os_report_add_tostore(tmp_str, r_filter->top_group, + al_data); + + free(*mgroup); + mgroup++; + } + + //free(mgroup); + } else { + tmp_str = al_data->group; + while (*tmp_str == ' ') { + tmp_str++; + } + if (*tmp_str != '\0') { + _os_report_add_tostore(tmp_str, r_filter->top_group, + al_data); + } + } + } + + /* Add to the location top filter */ + _os_report_add_tostore(al_data->location, r_filter->top_location, + al_data); + + if (al_data->filename != NULL) { + _os_report_add_tostore(al_data->filename, r_filter->top_files, + al_data); + } + } + + + + /* No report available */ + if (alerts_filtered == 0) { + if (!r_filter->report_name) { + merror("%s: INFO: Report completed and zero alerts post-filter.", __local_name); + } else { + merror("%s: INFO: Report '%s' completed and zero alerts post-filter.", __local_name, r_filter->report_name); + } + + goto cleanup; + } + + if (r_filter->report_name) { + verbose("%s: INFO: Report '%s' completed. Creating output...", __local_name, r_filter->report_name); + } else { + verbose("%s: INFO: Report completed. Creating output...", __local_name); + } + + l_print_out(" "); + if (r_filter->report_name) { + l_print_out("Report '%s' completed.", r_filter->report_name); + } else { + l_print_out("Report completed. =="); + } + l_print_out("------------------------------------------------"); + + l_print_out("->Processed alerts: %d", alerts_processed); + l_print_out("->Post-filtering alerts: %d", alerts_filtered); + l_print_out("->First alert: %s", first_alert); + l_print_out("->Last alert: %s", last_alert); + l_print_out(" "); + l_print_out(" "); + + OSStore_Sort(r_filter->top_srcip, _os_report_sort_compare); + OSStore_Sort(r_filter->top_user, _os_report_sort_compare); + OSStore_Sort(r_filter->top_level, _os_report_sort_compare); + OSStore_Sort(r_filter->top_group, _os_report_sort_compare); + OSStore_Sort(r_filter->top_location, _os_report_sort_compare); + OSStore_Sort(r_filter->top_rule, _os_report_sort_compare); + OSStore_Sort(r_filter->top_files, _os_report_sort_compare); + + os_report_printtop(r_filter->top_srcip, "Source ip", 0); + os_report_printtop(r_filter->top_user, "Username", 0); + os_report_printtop(r_filter->top_level, "Level", 0); + os_report_printtop(r_filter->top_group, "Group", 0); + os_report_printtop(r_filter->top_location, "Location", 0); + os_report_printtop(r_filter->top_rule, "Rule", 0); + os_report_printtop(r_filter->top_files, "Filenames", 0); + + /* Print related events */ + if (r_filter->related_srcip) + os_report_printtop(r_filter->top_srcip, "Source ip", + r_filter->related_srcip); + + if (r_filter->related_user) + os_report_printtop(r_filter->top_user, "Username", + r_filter->related_user); + + if (r_filter->related_level) + os_report_printtop(r_filter->top_level, "Level", + r_filter->related_level); + + if (r_filter->related_group) + os_report_printtop(r_filter->top_group, "Group", + r_filter->related_group); + + if (r_filter->related_location) + os_report_printtop(r_filter->top_location, "Location", + r_filter->related_location); + + if (r_filter->related_rule) + os_report_printtop(r_filter->top_rule, "Rule", + r_filter->related_rule); + + if (r_filter->related_file) + os_report_printtop(r_filter->top_files, "Filename", + r_filter->related_file); + + /* If we have to dump the alerts */ + if (data_to_clean) { + int i = 0; + + if (r_filter->show_alerts) { + l_print_out("Log dump:"); + l_print_out("------------------------------------------------"); + } + while (data_to_clean[i]) { + alert_data *md = data_to_clean[i]; + if (r_filter->show_alerts) { + l_print_out("%s %s\nRule: %d (level %d) -> '%s'\n%s\n\n", md->date, md->location, md->rule, md->level, md->comment, md->log[0]); + } + FreeAlertData(md); + i++; + } + free(data_to_clean); + data_to_clean = NULL; + } + + cleanup: + if (fileq->fp && fileq->fp != stdin) { + fclose(fileq->fp); + } + + free(fileq); +} + +/* Check the configuration filters */ +int os_report_configfilter(const char *filter_by, const char *filter_value, + report_filter *r_filter, int arg_type) +{ + if (!filter_by || !filter_value) { + return (-1); + } + + if (arg_type == REPORT_FILTER) { + if (strcmp(filter_by, "group") == 0) { + r_filter->group = filter_value; + } else if (strcmp(filter_by, "rule") == 0) { + r_filter->rule = filter_value; + } else if (strcmp(filter_by, "level") == 0) { + r_filter->level = filter_value; + } else if (strcmp(filter_by, "location") == 0) { + r_filter->location = filter_value; + } else if (strcmp(filter_by, "user") == 0) { + r_filter->user = filter_value; + } else if (strcmp(filter_by, "srcip") == 0) { + r_filter->srcip = filter_value; + } else if (strcmp(filter_by, "filename") == 0) { + r_filter->files = filter_value; + } else { + merror("%s: ERROR: Invalid filter '%s'.", __local_name, filter_by); + return (-1); + } + } else { + if (strcmp(filter_by, "group") == 0) { + r_filter->related_group = + _report_filter_value(filter_value, r_filter->related_group); + + if (r_filter->related_group == -1) { + return (-1); + } + } else if (strcmp(filter_by, "rule") == 0) { + r_filter->related_rule = + _report_filter_value(filter_value, r_filter->related_rule); + + if (r_filter->related_rule == -1) { + return (-1); + } + } else if (strcmp(filter_by, "level") == 0) { + r_filter->related_level = + _report_filter_value(filter_value, r_filter->related_level); + + if (r_filter->related_level == -1) { + return (-1); + } + } else if (strcmp(filter_by, "location") == 0) { + r_filter->related_location = + _report_filter_value(filter_value, r_filter->related_location); + + if (r_filter->related_location == -1) { + return (-1); + } + } else if (strcmp(filter_by, "srcip") == 0) { + r_filter->related_srcip = + _report_filter_value(filter_value, r_filter->related_srcip); + + if (r_filter->related_srcip == -1) { + return (-1); + } + } else if (strcmp(filter_by, "user") == 0) { + r_filter->related_user = + _report_filter_value(filter_value, r_filter->related_user); + + if (r_filter->related_user == -1) { + return (-1); + } + } else if (strcmp(filter_by, "filename") == 0) { + r_filter->related_file = + _report_filter_value(filter_value, r_filter->related_file); + + if (r_filter->related_file == -1) { + return (-1); + } + } else { + merror("%s: ERROR: Invalid related entry '%s'.", __local_name, filter_by); + return (-1); + } + } + + return (0); +} + diff --git a/src/shared/rules_op.c b/src/shared/rules_op.c new file mode 100644 index 000000000..1c00f4364 --- /dev/null +++ b/src/shared/rules_op.c @@ -0,0 +1,1084 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "rules_op.h" + +/* Change path for test rule */ +#ifdef TESTRULE +#undef RULEPATH +#define RULEPATH "rules/" +#endif + +/* Prototypes */ +static int _OS_GetRulesAttributes(char **attributes, + char **values, + RuleInfo *ruleinfo_pt) __attribute__((nonnull)); +static RuleInfo *_OS_AllocateRule(void); + + +/* Read the log rules */ +int OS_ReadXMLRules(const char *rulefile, + void *(*ruleact_function)(RuleInfo *rule_1, void *data_1), + void *data) +{ + OS_XML xml; + XML_NODE node = NULL; + + /** XML variables **/ + /* These are the available options for the rule configuration */ + + const char *xml_group = "group"; + const char *xml_rule = "rule"; + + const char *xml_regex = "regex"; + const char *xml_match = "match"; + const char *xml_decoded = "decoded_as"; + const char *xml_category = "category"; + const char *xml_cve = "cve"; + const char *xml_info = "info"; + const char *xml_day_time = "time"; + const char *xml_week_day = "weekday"; + const char *xml_comment = "description"; + const char *xml_ignore = "ignore"; + const char *xml_check_if_ignored = "check_if_ignored"; + + const char *xml_srcip = "srcip"; + const char *xml_srcport = "srcport"; + const char *xml_dstip = "dstip"; + const char *xml_dstport = "dstport"; + const char *xml_user = "user"; + const char *xml_url = "url"; + const char *xml_id = "id"; + const char *xml_data = "extra_data"; + const char *xml_hostname = "hostname"; + const char *xml_program_name = "program_name"; + const char *xml_status = "status"; + const char *xml_action = "action"; + const char *xml_compiled = "compiled_rule"; + + const char *xml_if_sid = "if_sid"; + const char *xml_if_group = "if_group"; + const char *xml_if_level = "if_level"; + const char *xml_fts = "if_fts"; + + const char *xml_if_matched_regex = "if_matched_regex"; + const char *xml_if_matched_group = "if_matched_group"; + const char *xml_if_matched_sid = "if_matched_sid"; + + const char *xml_same_source_ip = "same_source_ip"; + const char *xml_same_src_port = "same_src_port"; + const char *xml_same_dst_port = "same_dst_port"; + const char *xml_same_user = "same_user"; + const char *xml_same_location = "same_location"; + const char *xml_same_id = "same_id"; + const char *xml_dodiff = "check_diff"; + + const char *xml_different_url = "different_url"; + + const char *xml_notsame_source_ip = "not_same_source_ip"; + const char *xml_notsame_user = "not_same_user"; + const char *xml_notsame_agent = "not_same_agent"; + const char *xml_notsame_id = "not_same_id"; + + const char *xml_options = "options"; + + char *rulepath; + + size_t i; + + /* If no directory in the rulefile, add the default */ + if ((strchr(rulefile, '/')) == NULL) { + /* Build the rule file name + path */ + i = strlen(RULEPATH) + strlen(rulefile) + 2; + rulepath = (char *)calloc(i, sizeof(char)); + if (!rulepath) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + snprintf(rulepath, i, "%s/%s", RULEPATH, rulefile); + } else { + os_strdup(rulefile, rulepath); + debug1("%s is the rulefile", rulefile); + debug1("Not modifing the rule path"); + } + + /* Read the XML */ + if (OS_ReadXML(rulepath, &xml) < 0) { + merror(XML_ERROR, __local_name, rulepath, xml.err, xml.err_line); + free(rulepath); + return (-1); + } + debug1("%s: DEBUG: read xml for rule '%s'.", __local_name, rulepath); + + /* Apply any variables found */ + if (OS_ApplyVariables(&xml) != 0) { + merror(XML_ERROR_VAR, __local_name, rulepath, xml.err); + if (rulepath) { + free(rulepath); + } + return (-1); + } + debug1("%s: DEBUG: XML Variables applied.", __local_name); + + /* Get the root elements */ + node = OS_GetElementsbyNode(&xml, NULL); + if (!node) { + merror(CONFIG_ERROR, __local_name, rulepath); + OS_ClearXML(&xml); + if (rulepath) { + free(rulepath); + } + return (-1); + } + + /* Zero the rule memory -- not used anymore */ + free(rulepath); + + /* Check if there is any invalid global option */ + i = 0; + while (node[i]) { + if (node[i]->element) { + /* Verify group */ + if (strcasecmp(node[i]->element, xml_group) != 0) { + merror(RL_INV_ROOT, __local_name, node[i]->element); + OS_ClearXML(&xml); + return (-1); + } + /* Check group attribute -- only name is allowed */ + if ((!node[i]->attributes) || (!node[i]->values) || + (!node[i]->values[0]) || (!node[i]->attributes[0]) || + (strcasecmp(node[i]->attributes[0], "name") != 0) || + (node[i]->attributes[1])) { + merror(RL_INV_ROOT, __local_name, node[i]->element); + OS_ClearXML(&xml); + return (-1); + } + } else { + merror(XML_READ_ERROR, __local_name); + OS_ClearXML(&xml); + return (-1); + } + i++; + } + + /* Get the rules */ + i = 0; + while (node[i]) { + int j = 0; + XML_NODE rule = NULL; + + /* Get all rules for a global group */ + rule = OS_GetElementsbyNode(&xml, node[i]); + if (rule == NULL) { + i++; + continue; + } + + /* Loop over the rules node */ + while (rule[j]) { + /* Rules options */ + int k = 0; + char *regex = NULL, *match = NULL, *url = NULL, + *if_matched_regex = NULL, *if_matched_group = NULL, + *user = NULL, *id = NULL, *srcport = NULL, + *dstport = NULL, *status = NULL, *hostname = NULL, + *extra_data = NULL, *program_name = NULL; + + RuleInfo *config_ruleinfo = NULL; + XML_NODE rule_opt = NULL; + + /* Check if the rule element is correct */ + if ((!rule[j]->element) || + (strcasecmp(rule[j]->element, xml_rule) != 0)) { + merror(RL_INV_RULE, __local_name, node[i]->element); + OS_ClearXML(&xml); + return (-1); + } + + /* Check for the attributes of the rule */ + if ((!rule[j]->attributes) || (!rule[j]->values)) { + merror(RL_INV_RULE, __local_name, rulefile); + OS_ClearXML(&xml); + return (-1); + } + + /* Attribute block */ + config_ruleinfo = _OS_AllocateRule(); + + if (_OS_GetRulesAttributes(rule[j]->attributes, rule[j]->values, + config_ruleinfo) < 0) { + merror(RL_INV_ATTR, __local_name, rulefile); + OS_ClearXML(&xml); + return (-1); + } + + /* We must have an id or level */ + if ((config_ruleinfo->sigid == -1) || (config_ruleinfo->level == -1)) { + merror(RL_INV_ATTR, __local_name, rulefile); + OS_ClearXML(&xml); + return (-1); + } + + /* Assign the group name to the rule. The level is correct so + * the rule is probably going to be fine. + */ + os_strdup(node[i]->values[0], config_ruleinfo->group); + + /* Get rules options */ + rule_opt = OS_GetElementsbyNode(&xml, rule[j]); + if (rule_opt == NULL) { + merror(RL_NO_OPT, __local_name, config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + + /* Read the whole rule block */ + while (rule_opt[k]) { + if ((!rule_opt[k]->element) || (!rule_opt[k]->content)) { + break; + } else if (strcasecmp(rule_opt[k]->element, xml_regex) == 0) { + regex = + os_LoadString(regex, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_match) == 0) { + match = + os_LoadString(match, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_decoded) == 0) { + } else if (strcasecmp(rule_opt[k]->element, xml_info) == 0) { + config_ruleinfo->info = + os_LoadString(config_ruleinfo->info, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_day_time) == 0) { + config_ruleinfo->day_time = + OS_IsValidTime(rule_opt[k]->content); + if (!config_ruleinfo->day_time) { + merror(INVALID_CONFIG, __local_name, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_week_day) == 0) { + config_ruleinfo->week_day = + OS_IsValidDay(rule_opt[k]->content); + + if (!config_ruleinfo->week_day) { + merror(INVALID_CONFIG, __local_name, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_group) == 0) { + config_ruleinfo->group = + os_LoadString(config_ruleinfo->group, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_cve) == 0) { + config_ruleinfo->cve = + os_LoadString(config_ruleinfo->cve, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_comment) == 0) { + char *newline; + + newline = strchr(rule_opt[k]->content, '\n'); + if (newline) { + *newline = ' '; + } + config_ruleinfo->comment = + os_LoadString(config_ruleinfo->comment, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcip) == 0) { + size_t ip_s = 0; + + /* Get size of source IP list */ + while (config_ruleinfo->srcip && + config_ruleinfo->srcip[ip_s]) { + ip_s++; + } + + config_ruleinfo->srcip = (os_ip **) + realloc(config_ruleinfo->srcip, + (ip_s + 2) * sizeof(os_ip *)); + + /* Allocate memory for the individual entries */ + os_calloc(1, sizeof(os_ip), + config_ruleinfo->srcip[ip_s]); + config_ruleinfo->srcip[ip_s + 1] = NULL; + + /* Check if the IP is valid */ + if (!OS_IsValidIP(rule_opt[k]->content, + config_ruleinfo->srcip[ip_s])) { + merror(INVALID_IP, __local_name, rule_opt[k]->content); + return (-1); + } + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstip) == 0) { + size_t ip_s = 0; + + /* Get size of destination IP list */ + while (config_ruleinfo->dstip && + config_ruleinfo->dstip[ip_s]) { + ip_s++; + } + + config_ruleinfo->dstip = (os_ip **) + realloc(config_ruleinfo->dstip, + (ip_s + 2) * sizeof(os_ip *)); + + /* Allocate memory for the individual entries */ + os_calloc(1, sizeof(os_ip), + config_ruleinfo->dstip[ip_s]); + config_ruleinfo->dstip[ip_s + 1] = NULL; + + /* Checking if the IP is valid */ + if (!OS_IsValidIP(rule_opt[k]->content, + config_ruleinfo->dstip[ip_s])) { + merror(INVALID_IP, __local_name, rule_opt[k]->content); + return (-1); + } + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_user) == 0) { + user = os_LoadString(user, rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_id) == 0) { + id = os_LoadString(id, rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_srcport) == 0) { + srcport = os_LoadString(srcport, rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_dstport) == 0) { + dstport = os_LoadString(dstport, rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_PACKETINFO)) { + config_ruleinfo->alert_opts |= DO_PACKETINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_status) == 0) { + status = os_LoadString(status, rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_hostname) == 0) { + hostname = os_LoadString(hostname, rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, xml_data) == 0) { + extra_data = os_LoadString(extra_data, rule_opt[k]->content); + + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_program_name) == 0) { + program_name = os_LoadString(program_name, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_action) == 0) { + config_ruleinfo->action = + os_LoadString(config_ruleinfo->action, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_url) == 0) { + url = os_LoadString(url, rule_opt[k]->content); + } + + else if (strcasecmp(rule_opt[k]->element, xml_compiled) == 0) { + /* Not using this in here */ + } + + /* We allow these categories so far */ + else if (strcasecmp(rule_opt[k]->element, xml_category) == 0) { + if (strcmp(rule_opt[k]->content, "firewall") == 0) { + config_ruleinfo->category = FIREWALL; + } else if (strcmp(rule_opt[k]->content, "ids") == 0) { + config_ruleinfo->category = IDS; + } else if (strcmp(rule_opt[k]->content, "syslog") == 0) { + config_ruleinfo->category = SYSLOG; + } else if (strcmp(rule_opt[k]->content, "web-log") == 0) { + config_ruleinfo->category = WEBLOG; + } else if (strcmp(rule_opt[k]->content, "squid") == 0) { + config_ruleinfo->category = SQUID; + } else if (strcmp(rule_opt[k]->content, "windows") == 0) { + config_ruleinfo->category = DECODER_WINDOWS; + } else if (strcmp(rule_opt[k]->content, "openarmor") == 0) { + config_ruleinfo->category = openarmor_RL; + } else { + merror(INVALID_CAT, __local_name, rule_opt[k]->content); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, xml_if_sid) == 0) { + config_ruleinfo->if_sid = + os_LoadString(config_ruleinfo->if_sid, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_if_level) == 0) { + if (!OS_StrIsNum(rule_opt[k]->content)) { + merror(INVALID_CONFIG, __local_name, + xml_if_level, + rule_opt[k]->content); + return (-1); + } + + config_ruleinfo->if_level = + os_LoadString(config_ruleinfo->if_level, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, xml_if_group) == 0) { + config_ruleinfo->if_group = + os_LoadString(config_ruleinfo->if_group, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_regex) == 0) { + config_ruleinfo->context = 1; + if_matched_regex = + os_LoadString(if_matched_regex, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_group) == 0) { + config_ruleinfo->context = 1; + if_matched_group = + os_LoadString(if_matched_group, + rule_opt[k]->content); + } else if (strcasecmp(rule_opt[k]->element, + xml_if_matched_sid) == 0) { + config_ruleinfo->context = 1; + if (!OS_StrIsNum(rule_opt[k]->content)) { + merror(INVALID_CONFIG, __local_name, + rule_opt[k]->element, + rule_opt[k]->content); + return (-1); + } + config_ruleinfo->if_matched_sid = + atoi(rule_opt[k]->content); + + } else if (strcasecmp(rule_opt[k]->element, + xml_same_source_ip) == 0) { + config_ruleinfo->context_opts |= SAME_SRCIP; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_src_port) == 0) { + config_ruleinfo->context_opts |= SAME_SRCPORT; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_dodiff) == 0) { + config_ruleinfo->context++; + config_ruleinfo->context_opts |= SAME_DODIFF; + if (!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) { + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_same_dst_port) == 0) { + config_ruleinfo->context_opts |= SAME_DSTPORT; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_source_ip) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_SRCIP; + } else if (strcmp(rule_opt[k]->element, xml_same_id) == 0) { + config_ruleinfo->context_opts |= SAME_ID; + } else if (strcmp(rule_opt[k]->element, + xml_different_url) == 0) { + config_ruleinfo->context_opts |= DIFFERENT_URL; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcmp(rule_opt[k]->element, xml_notsame_id) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_ID; + } else if (strcasecmp(rule_opt[k]->element, + xml_fts) == 0) { + config_ruleinfo->alert_opts |= DO_FTS; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_user) == 0) { + config_ruleinfo->context_opts |= SAME_USER; + + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_user) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_USER; + } else if (strcasecmp(rule_opt[k]->element, + xml_same_location) == 0) { + config_ruleinfo->context_opts |= SAME_LOCATION; + if (!(config_ruleinfo->alert_opts & SAME_EXTRAINFO)) { + config_ruleinfo->alert_opts |= SAME_EXTRAINFO; + } + } else if (strcasecmp(rule_opt[k]->element, + xml_notsame_agent) == 0) { + config_ruleinfo->context_opts &= NOT_SAME_AGENT; + } else if (strcasecmp(rule_opt[k]->element, + xml_options) == 0) { + if (strcmp("alert_by_email", + rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & DO_MAILALERT)) { + config_ruleinfo->alert_opts |= DO_MAILALERT; + } + } else if (strcmp("no_email_alert", + rule_opt[k]->content) == 0) { + if (config_ruleinfo->alert_opts & DO_MAILALERT) { + config_ruleinfo->alert_opts &= 0xfff - DO_MAILALERT; + } + } else if (strcmp("log_alert", + rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & DO_LOGALERT)) { + config_ruleinfo->alert_opts |= DO_LOGALERT; + } + } else if (strcmp("no_log", rule_opt[k]->content) == 0) { + if (config_ruleinfo->alert_opts & DO_LOGALERT) { + config_ruleinfo->alert_opts &= 0xfff - DO_LOGALERT; + } + } else if (strcmp("no_ar", rule_opt[k]->content) == 0) { + if (!(config_ruleinfo->alert_opts & NO_AR)) { + config_ruleinfo->alert_opts |= NO_AR; + } + } else { + merror(XML_VALUEERR, __local_name, xml_options, + rule_opt[k]->content); + + merror(INVALID_ELEMENT, __local_name, + rule_opt[k]->element, + rule_opt[k]->content); + OS_ClearXML(&xml); + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, + xml_ignore) == 0) { + if (strstr(rule_opt[k]->content, "user") != NULL) { + config_ruleinfo->ignore |= FTS_USER; + } + if (strstr(rule_opt[k]->content, "srcip") != NULL) { + config_ruleinfo->ignore |= FTS_SRCIP; + } + if (strstr(rule_opt[k]->content, "dstip") != NULL) { + config_ruleinfo->ignore |= FTS_DSTIP; + } + if (strstr(rule_opt[k]->content, "id") != NULL) { + config_ruleinfo->ignore |= FTS_ID; + } + if (strstr(rule_opt[k]->content, "location") != NULL) { + config_ruleinfo->ignore |= FTS_LOCATION; + } + if (strstr(rule_opt[k]->content, "data") != NULL) { + config_ruleinfo->ignore |= FTS_DATA; + } + if (strstr(rule_opt[k]->content, "name") != NULL) { + config_ruleinfo->ignore |= FTS_NAME; + + } + if (!config_ruleinfo->ignore) { + merror(INVALID_ELEMENT, __local_name, + rule_opt[k]->element, + rule_opt[k]->content); + + return (-1); + } + } else if (strcasecmp(rule_opt[k]->element, + xml_check_if_ignored) == 0) { + if (strstr(rule_opt[k]->content, "user") != NULL) { + config_ruleinfo->ckignore |= FTS_USER; + } + if (strstr(rule_opt[k]->content, "srcip") != NULL) { + config_ruleinfo->ckignore |= FTS_SRCIP; + } + if (strstr(rule_opt[k]->content, "dstip") != NULL) { + config_ruleinfo->ckignore |= FTS_DSTIP; + } + if (strstr(rule_opt[k]->content, "id") != NULL) { + config_ruleinfo->ckignore |= FTS_ID; + } + if (strstr(rule_opt[k]->content, "location") != NULL) { + config_ruleinfo->ckignore |= FTS_LOCATION; + } + if (strstr(rule_opt[k]->content, "data") != NULL) { + config_ruleinfo->ckignore |= FTS_DATA; + } + if (strstr(rule_opt[k]->content, "name") != NULL) { + config_ruleinfo->ckignore |= FTS_NAME; + + } + if (!config_ruleinfo->ckignore) { + merror(INVALID_ELEMENT, __local_name, + rule_opt[k]->element, + rule_opt[k]->content); + + return (-1); + } + } + /* XXX As new features are added into ../analysisd/rules.c + * This code needs to be updated to match, but is out of date + * it's become a nightmare to correct with out just make the + * problem for someone later. + * + * This hack will allow any crap xml to pass without an + * error. The correct fix is to refactor the code so that + * ../analysisd/rules* and this code are not duplicates + * + else + { + merror(XML_INVELEM, __local_name, rule_opt[k]->element); + OS_ClearXML(&xml); + return(-1); + } + */ + + k++; + } + + /* Check for a valid use of frequency */ + if ((config_ruleinfo->context_opts || + config_ruleinfo->frequency) && + !config_ruleinfo->context) { + merror("%s: Invalid use of frequency/context options. " + "Missing if_matched on rule '%d'.", + __local_name, config_ruleinfo->sigid); + OS_ClearXML(&xml); + return (-1); + } + + /* If if_matched_group we must have a if_sid or if_group */ + if (if_matched_group) { + if (!config_ruleinfo->if_sid && !config_ruleinfo->if_group) { + os_strdup(if_matched_group, config_ruleinfo->if_group); + } + } + + /* If_matched_sid, we need to get the if_sid */ + if (config_ruleinfo->if_matched_sid && + !config_ruleinfo->if_sid && + !config_ruleinfo->if_group) { + os_calloc(16, sizeof(char), config_ruleinfo->if_sid); + snprintf(config_ruleinfo->if_sid, 15, "%d", + config_ruleinfo->if_matched_sid); + } + + /* Check the regexes */ + if (regex) { + os_calloc(1, sizeof(OSRegex), config_ruleinfo->regex); + if (!OSRegex_Compile(regex, config_ruleinfo->regex, 0)) { + merror(REGEX_COMPILE, __local_name, regex, + config_ruleinfo->regex->error); + if (regex) { + free(regex); + } + return (-1); + } + free(regex); + regex = NULL; + } + + /* Add match */ + if (match) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->match); + if (!OSMatch_Compile(match, config_ruleinfo->match, 0)) { + merror(REGEX_COMPILE, __local_name, match, + config_ruleinfo->match->error); + if (match) { + free(match); + } + return (-1); + } + free(match); + match = NULL; + } + + /* Add id */ + if (id) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->id); + if (!OSMatch_Compile(id, config_ruleinfo->id, 0)) { + merror(REGEX_COMPILE, __local_name, id, + config_ruleinfo->id->error); + if (id) { + free(id); + } + return (-1); + } + free(id); + id = NULL; + } + + /* Add srcport */ + if (srcport) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->srcport); + if (!OSMatch_Compile(srcport, config_ruleinfo->srcport, 0)) { + merror(REGEX_COMPILE, __local_name, srcport, + config_ruleinfo->id->error); + if (srcport) { + free(srcport); + } + return (-1); + } + free(srcport); + srcport = NULL; + } + + /* Add dstport */ + if (dstport) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->dstport); + if (!OSMatch_Compile(dstport, config_ruleinfo->dstport, 0)) { + merror(REGEX_COMPILE, __local_name, dstport, + config_ruleinfo->id->error); + if (dstport) { + free(dstport); + } + return (-1); + } + free(dstport); + dstport = NULL; + } + + /* Add status */ + if (status) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->status); + if (!OSMatch_Compile(status, config_ruleinfo->status, 0)) { + merror(REGEX_COMPILE, __local_name, status, + config_ruleinfo->status->error); + if (status) { + free(status); + } + return (-1); + } + free(status); + status = NULL; + } + + /* Add hostname */ + if (hostname) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->hostname); + if (!OSMatch_Compile(hostname, config_ruleinfo->hostname, 0)) { + merror(REGEX_COMPILE, __local_name, hostname, + config_ruleinfo->hostname->error); + if (hostname) { + free(hostname); + } + return (-1); + } + free(hostname); + hostname = NULL; + } + + /* Add extra data */ + if (extra_data) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->extra_data); + if (!OSMatch_Compile(extra_data, + config_ruleinfo->extra_data, 0)) { + merror(REGEX_COMPILE, __local_name, extra_data, + config_ruleinfo->extra_data->error); + if (extra_data) { + free(extra_data); + } + return (-1); + } + free(extra_data); + extra_data = NULL; + } + + /* Add in program name */ + if (program_name) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->program_name); + if (!OSMatch_Compile(program_name, + config_ruleinfo->program_name, 0)) { + merror(REGEX_COMPILE, __local_name, program_name, + config_ruleinfo->program_name->error); + if (program_name) { + free(program_name); + } + return (-1); + } + free(program_name); + program_name = NULL; + } + + /* Add user */ + if (user) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->user); + if (!OSMatch_Compile(user, config_ruleinfo->user, 0)) { + merror(REGEX_COMPILE, __local_name, user, + config_ruleinfo->user->error); + if (user) { + free(user); + } + return (-1); + } + free(user); + user = NULL; + } + + /* Add URL */ + if (url) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->url); + if (!OSMatch_Compile(url, config_ruleinfo->url, 0)) { + merror(REGEX_COMPILE, __local_name, url, + config_ruleinfo->url->error); + if (url) { + free(url); + } + return (-1); + } + free(url); + url = NULL; + } + + /* Add matched_group */ + if (if_matched_group) { + os_calloc(1, sizeof(OSMatch), config_ruleinfo->if_matched_group); + + if (!OSMatch_Compile(if_matched_group, + config_ruleinfo->if_matched_group, 0)) { + merror(REGEX_COMPILE, __local_name, if_matched_group, + config_ruleinfo->if_matched_group->error); + return (-1); + } + free(if_matched_group); + if_matched_group = NULL; + } + + /* Add matched_regex */ + if (if_matched_regex) { + os_calloc(1, sizeof(OSRegex), + config_ruleinfo->if_matched_regex); + if (!OSRegex_Compile(if_matched_regex, + config_ruleinfo->if_matched_regex, 0)) { + merror(REGEX_COMPILE, __local_name, if_matched_regex, + config_ruleinfo->if_matched_regex->error); + if (if_matched_regex) { + free(if_matched_regex); + } + return (-1); + } + free(if_matched_regex); + if_matched_regex = NULL; + } + + /* Call the function provided */ + ruleact_function(config_ruleinfo, data); + + j++; /* Next rule */ + + } /* while(rule[j]) */ + OS_ClearNode(rule); + i++; + + } /* while (node[i]) */ + + /* Clean global node */ + OS_ClearNode(node); + OS_ClearXML(&xml); + + return (0); +} + +/* Allocate memory for a rule */ +static RuleInfo *_OS_AllocateRule() +{ + RuleInfo *ruleinfo_pt = NULL; + + /* Allocate memory for structure */ + ruleinfo_pt = (RuleInfo *)calloc(1, sizeof(RuleInfo)); + if (ruleinfo_pt == NULL) { + ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); + } + + /* Default values */ + ruleinfo_pt->level = -1; + + /* Default category is syslog */ + ruleinfo_pt->category = SYSLOG; + + ruleinfo_pt->ar = NULL; + + ruleinfo_pt->context = 0; + + /* Default sigid of -1 */ + ruleinfo_pt->sigid = -1; + ruleinfo_pt->firedtimes = 0; + ruleinfo_pt->maxsize = 0; + ruleinfo_pt->frequency = 0; + ruleinfo_pt->ignore_time = 0; + ruleinfo_pt->timeframe = 0; + ruleinfo_pt->time_ignored = 0; + + ruleinfo_pt->context_opts = 0; + ruleinfo_pt->alert_opts = 0; + ruleinfo_pt->ignore = 0; + ruleinfo_pt->ckignore = 0; + + ruleinfo_pt->day_time = NULL; + ruleinfo_pt->week_day = NULL; + + ruleinfo_pt->group = NULL; + ruleinfo_pt->regex = NULL; + ruleinfo_pt->match = NULL; + ruleinfo_pt->decoded_as = 0; + + ruleinfo_pt->comment = NULL; + ruleinfo_pt->info = NULL; + ruleinfo_pt->cve = NULL; + + ruleinfo_pt->if_sid = NULL; + ruleinfo_pt->if_group = NULL; + ruleinfo_pt->if_level = NULL; + + ruleinfo_pt->if_matched_regex = NULL; + ruleinfo_pt->if_matched_group = NULL; + ruleinfo_pt->if_matched_sid = 0; + + ruleinfo_pt->user = NULL; + ruleinfo_pt->srcip = NULL; + ruleinfo_pt->srcport = NULL; + ruleinfo_pt->dstip = NULL; + ruleinfo_pt->dstport = NULL; + ruleinfo_pt->url = NULL; + ruleinfo_pt->id = NULL; + ruleinfo_pt->status = NULL; + ruleinfo_pt->hostname = NULL; + ruleinfo_pt->program_name = NULL; + ruleinfo_pt->action = NULL; + + /* Zero last matched events */ + ruleinfo_pt->__frequency = 0; + ruleinfo_pt->last_events = NULL; + + /* Zero the list of previous matches */ + ruleinfo_pt->sid_prev_matched = NULL; + ruleinfo_pt->group_prev_matched = NULL; + + ruleinfo_pt->sid_search = NULL; + ruleinfo_pt->group_search = NULL; + + ruleinfo_pt->event_search = NULL; + + return (ruleinfo_pt); +} + +/* Reads the rules attributes and assign them */ +static int _OS_GetRulesAttributes(char **attributes, char **values, + RuleInfo *ruleinfo_pt) +{ + int k = 0; + + const char *xml_id = "id"; + const char *xml_level = "level"; + const char *xml_maxsize = "maxsize"; + const char *xml_timeframe = "timeframe"; + const char *xml_frequency = "frequency"; + const char *xml_accuracy = "accuracy"; + const char *xml_noalert = "noalert"; + const char *xml_ignore_time = "ignore"; + const char *xml_overwrite = "overwrite"; + + /* Get attributes */ + while (attributes[k]) { + if (!values[k]) { + merror(RL_EMPTY_ATTR, __local_name, attributes[k]); + return (-1); + } + /* Get rule Id */ + else if (strcasecmp(attributes[k], xml_id) == 0) { + if (OS_StrIsNum(values[k]) && (strlen(values[k]) <= 6 )) { + ruleinfo_pt->sigid = atoi(values[k]); + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } + /* Get level */ + else if (strcasecmp(attributes[k], xml_level) == 0) { + if (OS_StrIsNum(values[k]) && (strlen(values[k]) <= 3)) { + ruleinfo_pt->level = atoi(values[k]); + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } + /* Get maxsize */ + else if (strcasecmp(attributes[k], xml_maxsize) == 0) { + if (OS_StrIsNum(values[k]) && (strlen(values[k]) <= 4)) { + ruleinfo_pt->maxsize = atoi(values[k]); + + /* Add EXTRAINFO options */ + if (ruleinfo_pt->maxsize > 0 && + !(ruleinfo_pt->alert_opts & DO_EXTRAINFO)) { + ruleinfo_pt->alert_opts |= DO_EXTRAINFO; + } + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } + /* Get timeframe */ + else if (strcasecmp(attributes[k], xml_timeframe) == 0) { + if (OS_StrIsNum(values[k]) && (strlen(values[k]) <= 5)) { + ruleinfo_pt->timeframe = atoi(values[k]); + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } + /* Get frequency */ + else if (strcasecmp(attributes[k], xml_frequency) == 0) { + if (OS_StrIsNum(values[k]) && (strlen(values[k]) <= 4)) { + ruleinfo_pt->frequency = atoi(values[k]); + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } + /* Rule accuracy */ + else if (strcasecmp(attributes[k], xml_accuracy) == 0) { + merror("%s: XXX: Use of 'accuracy' isn't supported. Ignoring.", + __local_name); + } + /* Rule ignore_time */ + else if (strcasecmp(attributes[k], xml_ignore_time) == 0) { + if (OS_StrIsNum(values[k]) && (strlen(values[k]) <= 4)) { + ruleinfo_pt->ignore_time = atoi(values[k]); + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } + /* Rule noalert */ + else if (strcasecmp(attributes[k], xml_noalert) == 0) { + ruleinfo_pt->alert_opts |= NO_ALERT; + } else if (strcasecmp(attributes[k], xml_overwrite) == 0) { + if (strcmp(values[k], "yes") == 0) { + ruleinfo_pt->alert_opts |= DO_OVERWRITE; + } else if (strcmp(values[k], "no") == 0) { + } else { + merror(XML_VALUEERR, __local_name, attributes[k], values[k]); + return (-1); + } + } else { + merror(XML_INVELEM, __local_name, attributes[k]); + return (-1); + } + k++; + } + return (0); +} + diff --git a/src/shared/sig_op.c b/src/shared/sig_op.c new file mode 100644 index 000000000..4ab56418f --- /dev/null +++ b/src/shared/sig_op.c @@ -0,0 +1,68 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Functions to handle signal manipulation */ + +#ifndef WIN32 + +#include +#include +#include +#include + +#include "sig_op.h" +#include "file_op.h" +#include "debug_op.h" +#include "error_messages/error_messages.h" + +static const char *pidfile = NULL; + + +void HandleSIG(int sig) +{ + merror(SIGNAL_RECV, pidfile, sig, strsignal(sig)); + + DeletePID(pidfile); + + exit(1); +} + + +/* To avoid client-server communication problems */ +void HandleSIGPIPE(__attribute__((unused)) int sig) +{ + return; +} + +void StartSIG(const char *process_name) +{ + pidfile = process_name; + + signal(SIGHUP, SIG_IGN); + signal(SIGINT, HandleSIG); + signal(SIGQUIT, HandleSIG); + signal(SIGTERM, HandleSIG); + signal(SIGALRM, HandleSIG); + signal(SIGPIPE, HandleSIGPIPE); +} + +void StartSIG2(const char *process_name, void (*func)(int)) +{ + pidfile = process_name; + + signal(SIGHUP, SIG_IGN); + signal(SIGINT, func); + signal(SIGQUIT, func); + signal(SIGTERM, func); + signal(SIGALRM, func); + signal(SIGPIPE, HandleSIGPIPE); +} + +#endif /* !WIN32 */ + diff --git a/src/shared/store_op.c b/src/shared/store_op.c new file mode 100644 index 000000000..b051abbe2 --- /dev/null +++ b/src/shared/store_op.c @@ -0,0 +1,383 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Common API for dealing with ordered lists + * Provides a fast search on average (n/2) + */ + +#include "shared.h" + + +/* Create the list storage + * Returns NULL on error + */ +OSStore *OSStore_Create() +{ + OSStore *my_list; + + my_list = (OSStore *) calloc(1, sizeof(OSStore)); + if (!my_list) { + return (NULL); + } + + my_list->first_node = NULL; + my_list->last_node = NULL; + my_list->cur_node = NULL; + my_list->currently_size = 0; + my_list->max_size = 0; + my_list->free_data_function = NULL; + + return (my_list); +} + +/* Delete the list storage + * Returns NULL on error + */ +OSStore *OSStore_Free(OSStore *list) +{ + OSStoreNode *delnode; + list->cur_node = list->first_node; + + while (list->cur_node) { + if (list->cur_node->key) { + free(list->cur_node->key); + list->cur_node->key = NULL; + } + if (list->cur_node->data) { + free(list->cur_node->data); + list->cur_node->data = NULL; + } + + /* Delete each node */ + delnode = list->cur_node; + list->cur_node = list->cur_node->next; + free(delnode); + } + + list->first_node = NULL; + list->last_node = NULL; + + free(list); + list = NULL; + + return (list); +} + +/* Set the maximum number of elements in the storage + * Returns 0 on error or 1 on success + */ +int OSStore_SetMaxSize(OSStore *list, int max_size) +{ + if (!list) { + return (0); + } + + /* Minimum size is 1 */ + if (max_size <= 1) { + return (0); + } + + list->max_size = max_size; + + return (1); +} + +/* Set the pointer to the function to free the memory data */ +int OSStore_SetFreeDataPointer(OSStore *list, void (free_data_function)(void *)) +{ + if (!list) { + return (0); + } + + list->free_data_function = free_data_function; + return (1); +} + +/* Sort the storage by size */ +int OSStore_Sort(OSStore *list, void *(sort_data_function)(void *d1, void *d2)) +{ + OSStoreNode *newnode = NULL; + OSStoreNode *movenode = NULL; + list->cur_node = list->first_node; + + while (list->cur_node) { + movenode = list->cur_node->prev; + + /* Check for all the previous entries, using sort */ + while (movenode) { + + if (sort_data_function(list->cur_node->data, movenode->data)) { + movenode = movenode->prev; + } + + /* This node should stay where it is */ + else if (movenode == list->cur_node->prev) { + break; + } + + /* Replace the nodes */ + else { + newnode = list->cur_node; + + if (list->cur_node->prev) { + list->cur_node->prev->next = list->cur_node->next; + } + + if (list->cur_node->next) { + list->cur_node->next->prev = list->cur_node->prev; + } else { + list->last_node = list->cur_node->prev; + } + + list->cur_node = list->cur_node->prev; + + newnode->next = movenode->next; + newnode->prev = movenode; + + if (movenode->next) { + movenode->next->prev = newnode; + } + + movenode->next = newnode; + + break; + } + } + + /* If movenode is not set, put the current node in first */ + if (!movenode && (list->cur_node != list->first_node)) { + newnode = list->cur_node; + + if (list->cur_node->prev) { + list->cur_node->prev->next = list->cur_node->next; + } + + if (list->cur_node->next) { + list->cur_node->next->prev = list->cur_node->prev; + } else { + list->last_node = list->cur_node->prev; + } + + if ((list->cur_node = list->cur_node->prev) == NULL) { + return (1); + } + + newnode->prev = NULL; + newnode->next = list->first_node; + list->first_node->prev = newnode; + + list->first_node = newnode; + } + + list->cur_node = list->cur_node->next; + } + + return (1); +} + +/* Get key position from storage + * Returns 0 if not present or the key if available + * (position may change after each PUT) + */ +int OSStore_GetPosition(OSStore *list, const char *key) +{ + int chk_rc, pos = 1; + list->cur_node = list->first_node; + + while (list->cur_node) { + if ((chk_rc = strcmp(list->cur_node->key, key)) >= 0) { + /* Found */ + if (chk_rc == 0) { + return (pos); + } + + /* Not found */ + return (0); + } + + list->cur_node = list->cur_node->next; + pos++; + } + return (0); +} + +/* Get first node from storage + * Returns NULL if not present + */ +OSStoreNode *OSStore_GetFirstNode(OSStore *list) +{ + return (list->first_node); +} + +/* Get data from storage + * Returns NULL if not present + */ +void *OSStore_Get(OSStore *list, const char *key) +{ + int chk_rc; + list->cur_node = list->first_node; + + while (list->cur_node) { + if ((chk_rc = strcmp(list->cur_node->key, key)) >= 0) { + /* Found */ + if (chk_rc == 0) { + return (list->cur_node->data); + } + + /* Not found */ + return (NULL); + } + + list->cur_node = list->cur_node->next; + } + return (NULL); +} + +/* Check if key is present on storage + * Returns 0 if not present + */ +int OSStore_Check(OSStore *list, const char *key) +{ + int chk_rc; + list->cur_node = list->first_node; + + while (list->cur_node) { + if ((chk_rc = strcmp(list->cur_node->key, key)) >= 0) { + /* Found */ + if (chk_rc == 0) { + return (1); + } + + /* Not found */ + return (0); + } + + list->cur_node = list->cur_node->next; + } + return (0); +} + +/* Check if key is present on storage (using strncmp) + * Returns 0 if not present + */ +int OSStore_NCheck(OSStore *list, const char *key) +{ + int chk_rc; + list->cur_node = list->first_node; + + while (list->cur_node) { + if ((chk_rc = strncmp(list->cur_node->key, key, + list->cur_node->key_size)) >= 0) { + /* Found */ + if (chk_rc == 0) { + return (1); + } + + /* Not found */ + return (0); + } + + list->cur_node = list->cur_node->next; + } + return (0); +} + +/* Check if key is present on storage (case insensitive) + * Returns 0 if not present + */ +int OSStore_NCaseCheck(OSStore *list, const char *key) +{ + int chk_rc; + list->cur_node = list->first_node; + + while (list->cur_node) { + if ((chk_rc = strncasecmp(list->cur_node->key, key, + list->cur_node->key_size)) == 0) { + return (1); + } + + list->cur_node = list->cur_node->next; + } + return (0); +} + +/* Add data to the list + * Returns 1 on success and 0 on failure + */ +int OSStore_Put(OSStore *list, const char *key, void *data) +{ + int chk_rc; + OSStoreNode *newnode; + + /* Allocate memory for new node */ + newnode = (OSStoreNode *) calloc(1, sizeof(OSStoreNode)); + if (!newnode) { + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (0); + } + + newnode->prev = NULL; + newnode->next = NULL; + newnode->data = data; + newnode->key = strdup(key); + if (!newnode->key) { + free(newnode); + merror(MEM_ERROR, __local_name, errno, strerror(errno)); + return (0); + } + newnode->key_size = strlen(key); + + /* If we don't have first node, assign it */ + if (!list->first_node) { + list->first_node = newnode; + list->last_node = newnode; + } + + /* Store the data in order */ + else { + list->cur_node = list->first_node; + while (list->cur_node) { + if ((chk_rc = strcmp(list->cur_node->key, key)) >= 0) { + /* Duplicate entry */ + if (chk_rc == 0) { + free(newnode->key); + free(newnode); + return (1); + } + + /* If there is no prev node, this is the first node */ + if (list->cur_node->prev) { + list->cur_node->prev->next = newnode; + } else { + list->first_node = newnode; + } + + newnode->prev = list->cur_node->prev; + + list->cur_node->prev = newnode; + newnode->next = list->cur_node; + break; + } + + list->cur_node = list->cur_node->next; + } + + /* New node is the higher key */ + if (!newnode->next) { + list->last_node->next = newnode; + newnode->prev = list->last_node; + list->last_node = newnode; + } + } + + /* Increment list size */ + list->currently_size++; + + return (1); +} diff --git a/src/shared/string_op.c b/src/shared/string_op.c new file mode 100644 index 000000000..9bb67fad6 --- /dev/null +++ b/src/shared/string_op.c @@ -0,0 +1,126 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "string.h" + + +/* Trim CR and/or LF from the last positions of a string */ +void os_trimcrlf(char *str) +{ + size_t len; + + len = strlen(str); + len--; + + while (str[len] == '\n' || str[len] == '\r') { + str[len] = '\0'; + len--; + } +} + +/* Remove offending char (e.g., double quotes) from source */ +char *os_strip_char(const char *source, char remove) +{ + char *clean; + const char *iterator = source; + size_t length = 0; + int i; + + /* Figure out how much memory to allocate */ + for ( ; *iterator; iterator++ ) { + if ( *iterator != remove ) { + length++; + } + } + + /* Allocate the memory */ + if ( (clean = (char *) malloc( length + 1 )) == NULL ) { + // Return NULL + return NULL; + } + memset(clean, '\0', length + 1); + + /* Remove the characters */ + iterator = source; + for ( i = 0; *iterator; iterator++ ) { + if ( *iterator != remove ) { + clean[i] = *iterator; + i++; + } + } + + return clean; +} + +/* Do a substring */ +int os_substr(char *dest, const char *src, size_t position, ssize_t length) +{ + dest[0] = '\0'; + + if ( length <= 0 ) { + /* Unsupported negative length string */ + return -3; + } + if ( src == NULL ) { + return -2; + } + if ( position >= strlen(src) ) { + return -1; + } + + strncat(dest, (src + position), (size_t) length); + + return 0; +} + +/* Escape a set of characters */ +char *os_shell_escape(const char *src) +{ + /* Maximum Length of the String is 2 times the current length */ + char shell_escapes[] = { '\\', '"', '\'', ' ', '\t', ';', '`', '>', '<', '|', '#', + '*', '[', ']', '{', '}', '&', '$', '!', ':', '(', ')' + }; + + char *escaped_string; + size_t length = 0; + int i = 0; + + if (src == NULL) { + return NULL; + } + + /* Determine how long the string will be */ + const char *iterator = src; + for (; *iterator; iterator++) { + if ( strchr(shell_escapes, *iterator) ) { + length++; + } + length++; + } + /* Allocate memory */ + if ( (escaped_string = (char *) calloc(1, length + 1 )) == NULL ) { + // Return NULL + return NULL; + } + + /* Escape the escapable characters */ + iterator = src; + for ( i = 0; *iterator; iterator++ ) { + if ( strchr(shell_escapes, *iterator) ) { + escaped_string[i] = '\\'; + i++; + } + escaped_string[i] = *iterator; + i++; + } + + return escaped_string; +} + diff --git a/src/shared/tests/Makefile b/src/shared/tests/Makefile new file mode 100644 index 000000000..6374609d7 --- /dev/null +++ b/src/shared/tests/Makefile @@ -0,0 +1,11 @@ +# Makefile for misc tests + +maketest: + $(CC) -g -o string_test string_test.c ../string_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall + $(CC) -g -o prime_test prime_test.c ../math_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall + $(CC) -g -o hash_test hash_test.c ../hash_op.c ../math_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall + $(CC) -g -o merge_test merge_test.c ../file_op.c ../debug_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall + $(CC) -DARGV0=\"ip_test\" -g -o ip_test ip_test.c ../validate_op.c ../debug_op.c ../regex_op.c -I../ -I../../ -I../../headers/ -I../headers/ -Wall + +clean: + -rm string_test prime_test hash_test merge_test ip_test *.core diff --git a/src/shared/tests/hash_test.c b/src/shared/tests/hash_test.c new file mode 100644 index 000000000..eca69b980 --- /dev/null +++ b/src/shared/tests/hash_test.c @@ -0,0 +1,36 @@ +#include +#include + +#include "hash_op.h" + + +int main(int argc, char **argv) +{ + int i = 0; + char *tmp; + char buf[1024]; + OSHash *mhash; + + mhash = OSHash_Create(); + + while (1) { + fgets(buf, 1024, stdin); + tmp = strchr(buf, '\n'); + if (tmp) { + *tmp = '\0'; + } + + if (strncmp(buf, "get ", 4) == 0) { + printf("Getting key: '%s'\n", buf + 4); + printf("Found: '%s'\n", (char *)OSHash_Get(mhash, buf + 4)); + } else { + printf("Adding key: '%s'\n", buf); + i = OSHash_Add(mhash, strdup(buf), strdup(buf)); + + printf("rc = %d\n", i); + } + } + + return (0); +} + diff --git a/src/shared/tests/ip_test.c b/src/shared/tests/ip_test.c new file mode 100644 index 000000000..ff79645e5 --- /dev/null +++ b/src/shared/tests/ip_test.c @@ -0,0 +1,25 @@ +#include +#include + +#include "validate_op.h" + + +int main(int argc, char **argv) +{ + os_ip myip; + + if (!argv[1]) { + return (1); + } + + if (!OS_IsValidIP(argv[1], &myip)) { + printf("Invalid ip\n"); + } + + if (OS_IPFound(argv[2], &myip)) { + printf("IP MATCHED!\n"); + } + + return (0); +} + diff --git a/src/shared/tests/merge_test.c b/src/shared/tests/merge_test.c new file mode 100644 index 000000000..41020d147 --- /dev/null +++ b/src/shared/tests/merge_test.c @@ -0,0 +1,25 @@ +#include +#include +#include + +#include "file_op.h" + + +int main(int argc, char **argv) +{ + if (!argv[1]) { + printf("%s [mu] ..\n", argv[0]); + exit(1); + } + + if (strcmp(argv[1], "m") == 0) { + MergeFiles(argv[2], argv + 3); + } else if (strcmp(argv[1], "u") == 0) { + UnmergeFiles(argv[2]); + } else { + printf("ERROR\n"); + } + + return (0); +} + diff --git a/src/shared/tests/prime_test.c b/src/shared/tests/prime_test.c new file mode 100644 index 000000000..334a7ed2e --- /dev/null +++ b/src/shared/tests/prime_test.c @@ -0,0 +1,19 @@ +#include +#include +#include + +#include "math_op.h" + + +int main(int argc, char **argv) +{ + if (!argv[1]) { + printf("%s \n", argv[0]); + exit(1); + } + + printf("Value: %d\n", os_getprime(atoi(argv[1]))); + + return (0); +} + diff --git a/src/shared/tests/string_test.c b/src/shared/tests/string_test.c new file mode 100644 index 000000000..f2fb709ee --- /dev/null +++ b/src/shared/tests/string_test.c @@ -0,0 +1,26 @@ +#include +#include + +#include "string_op.h" + + +int main(int argc, char **argv) +{ + int i = 0; + char *tmp; + char buf[] = "/var/www/html/Testing This Interface$%^&*().txt"; + + tmp = os_shell_escape(buf); + char clean[] = "/var/www/html/index.html"; + + printf("Sent: '%s'\n", buf); + printf("Fixed: '%s'\n", tmp); + free(tmp); + + tmp = os_shell_escape(clean); + printf("Sent: '%s'\n", clean); + printf("Fixed: '%s'\n", tmp); + + return (0); +} + diff --git a/src/shared/validate_op.c b/src/shared/validate_op.c new file mode 100644 index 000000000..c3385be5a --- /dev/null +++ b/src/shared/validate_op.c @@ -0,0 +1,766 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" + +static char *_read_file(const char *high_name, const char *low_name, const char *defines_file) __attribute__((nonnull(3))); +static const char *__gethour(const char *str, char *openarmor_hour) __attribute__((nonnull)); + + +/* Read the file and return a string the matches the following + * format: high_name.low_name. + * If return is not null, value must be freed + */ +static char *_read_file(const char *high_name, const char *low_name, const char *defines_file) +{ + FILE *fp; + char def_file[OS_FLSIZE + 1]; + char buf[OS_SIZE_1024 + 1]; + char *buf_pt; + char *tmp_buffer; + char *ret; + +#ifndef WIN32 + if (isChroot()) { + snprintf(def_file, OS_FLSIZE, "%s", defines_file); + } else { + snprintf(def_file, OS_FLSIZE, "%s%s", DEFAULTDIR, defines_file); + } +#else + snprintf(def_file, OS_FLSIZE, "%s", defines_file); +#endif + + fp = fopen(def_file, "r"); + if (!fp) { + if (strcmp(defines_file, openarmor_LDEFINES) != 0) { + merror(FOPEN_ERROR, __local_name, def_file, errno, strerror(errno)); + } + return (NULL); + } + + /* Invalid call */ + if (!high_name || !low_name) { + merror(NULL_ERROR, __local_name); + fclose(fp); + return (NULL); + } + + /* Read it */ + buf[OS_SIZE_1024] = '\0'; + while (fgets(buf, OS_SIZE_1024 , fp) != NULL) { + /* Commented or blank lines */ + if (buf[0] == '#' || buf[0] == ' ' || buf[0] == '\n') { + continue; + } + + /* Messages not formatted correctly */ + buf_pt = strchr(buf, '.'); + if (!buf_pt) { + merror(FGETS_ERROR, __local_name, def_file, buf); + continue; + } + + /* Check for the high name */ + *buf_pt = '\0'; + buf_pt++; + if (strcmp(buf, high_name) != 0) { + continue; + } + + tmp_buffer = buf_pt; + + /* Get the equal */ + buf_pt = strchr(buf_pt, '='); + if (!buf_pt) { + merror(FGETS_ERROR, __local_name, def_file, buf); + continue; + } + + /* Check for the low name */ + *buf_pt = '\0'; + buf_pt++; + if (strcmp(tmp_buffer, low_name) != 0) { + continue; + } + + /* Remove newlines or anything that will cause errors */ + tmp_buffer = strrchr(buf_pt, '\n'); + if (tmp_buffer) { + *tmp_buffer = '\0'; + } + tmp_buffer = strrchr(buf_pt, '\r'); + if (tmp_buffer) { + *tmp_buffer = '\0'; + } + + os_strdup(buf_pt, ret); + fclose(fp); + return (ret); + } + + fclose(fp); + return (NULL); +} + +/* Get an integer definition. This function always return on + * success or exits on error. + */ +int getDefine_Int(const char *high_name, const char *low_name, int min, int max) +{ + int ret; + char *value; + char *pt; + + /* Try to read from the local define file */ + value = _read_file(high_name, low_name, openarmor_LDEFINES); + if (!value) { + value = _read_file(high_name, low_name, openarmor_DEFINES); + if (!value) { + ErrorExit(DEF_NOT_FOUND, __local_name, high_name, low_name); + } + } + + pt = value; + while (*pt != '\0') { + if (!isdigit((int)*pt)) { + ErrorExit(INV_DEF, __local_name, high_name, low_name, value); + } + pt++; + } + + ret = atoi(value); + if ((ret < min) || (ret > max)) { + ErrorExit(INV_DEF, __local_name, high_name, low_name, value); + } + + /* Clear memory */ + free(value); + + return (ret); +} + +/* Check if IP_address is present at that_IP + * Returns 1 on success or 0 on failure + */ +int OS_IPFound(const char *ip_address, const os_ip *that_ip) +{ + int _true = 1; + os_ip temp_ip; + + /* If negate is set */ + char *ip = that_ip->ip; + if (ip[0] == '!') { + ip++; + _true = 0; + } + + /* The simplest case is the 'any' case. + * We just return true + */ + if( strcmp(ip, "any") == 0 ) { + return _true; + } + + memset(&temp_ip, 0, sizeof(struct _os_ip)); + + /* Extract IP address */ + if (OS_IsValidIP(ip_address, &temp_ip) == 0) { + return (!_true); + } + + + /* Check if IP is in thatip & netmask */ + if (sacmp((struct sockaddr *) &temp_ip.ss, + (struct sockaddr *) &that_ip->ss, + that_ip->prefixlength)) { + return (_true); + } + + /* Didn't match */ + return (!_true); +} + +/* Check if IP_address is present in the "list_of_ips". + * Returns 1 on success or 0 on failure + * The list MUST be NULL terminated + */ +int OS_IPFoundList(const char *ip_address, os_ip **list_of_ips) +{ + int _true = 1; + os_ip temp_ip; + + memset(&temp_ip, 0, sizeof(struct _os_ip)); + + /* Extract IP address */ + if (OS_IsValidIP(ip_address, &temp_ip) == 0) { + return (!_true); + } + + while (*list_of_ips) { + os_ip *l_ip = *list_of_ips; + + char *ip = l_ip->ip; + if (ip[0] == '!') { + ip++; + _true = 0; + } + else { + _true = 1; + } + + /* Simplest case, if the list contains an any + * ip, we return true. + */ + if( strcmp(ip,"any" ) == 0 ) { + return _true; + } + + /* Checking if ip is in thatip & netmask */ + if (sacmp((struct sockaddr *) &temp_ip.ss, + (struct sockaddr *) &l_ip->ss, + l_ip->prefixlength)) { + return (_true); + } + list_of_ips++; + } + + return (!_true); +} + +/** int OS_IsValidIP(char *ip_address, os_ip *final_ip) + * Validate if an IP address is in the right format + * Returns 0 if doesn't match or 1 if it is an IP or 2 an IP with CIDR. + * WARNING: On success this function may modify the value of ip_address + */ +int OS_IsValidIP(const char *in_address, os_ip *final_ip) +{ + char *tmp_str; + int cidr = -1, prefixlength; + struct addrinfo hints, *result; + char *ip_address = NULL; + + /* Can't be null */ + if (!in_address) { + return (0); + } + + /* We mess with in_address later and we set 'const' + * in the signature, so we need to copy it + * here. + */ + os_strdup(in_address, ip_address); + + if (final_ip) { + os_strdup(ip_address, final_ip->ip); + } + + if (*ip_address == '!') { + //ip_address++; + if (ip_address) { + free(ip_address); + } + os_strdup(in_address+1, ip_address); + } + + /* Use IPv6 here, because it doesn't matter + * OS_IPFound and OS_IPFoundList will + * return true if the os_ip.ip element is 'any' + */ + if(strcmp(ip_address, "any") == 0) { + //strcpy(ip_address, "::/0"); + free(ip_address); // Free the old value before writing the new one? + os_strdup("::/0", ip_address); + } + + /* Getting the cidr/netmask if available */ + tmp_str = strchr(ip_address,'/'); + if(tmp_str) { + *tmp_str = '\0'; + tmp_str++; + + /* Cidr */ + if(strlen(tmp_str) <= 3) { + cidr = atoi(tmp_str); + } else { + free(ip_address); + return(0); + } + } + + /* No cidr available */ + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(ip_address, NULL, &hints, &result) != 0) { + free(ip_address); + return(0); + } + + switch (result->ai_family) + { + case AF_INET: + if (cidr >=0 && cidr <= 32) { + prefixlength = cidr; + break; + } else if (cidr < 0) { + prefixlength = 32; + break; + } + free(ip_address); + free(result); + return(0); + case AF_INET6: + if (cidr >=0 && cidr <= 128) { + prefixlength = cidr; + break; + } else if (cidr < 0) { + prefixlength = 128; + break; + } + free(ip_address); + free(result); + return(0); + default: + free(ip_address); + free(result); + return(0); + } + + if (final_ip) { + memcpy(&(final_ip->ss), result->ai_addr, result->ai_addrlen); + final_ip->prefixlength = prefixlength; + } + + freeaddrinfo(result); + + free(ip_address); + return((cidr >= 0) ? 2 : 1); +} + +/** int sacmp(struct sockaddr *sa1, struct sockaddr *sa2, int prefixlength) + * Compares two sockaddrs up to prefixlength. + * Returns 0 if doesn't match or 1 if they do. + */ +int sacmp(struct sockaddr *sa1, struct sockaddr *sa2, int prefixlength) +{ + int _true = 1; + int i, realaf1, realaf2; + div_t ip_div; + char *addr1, *addr2, modbits; + + // If we have no prefixlength just return a match + // * This handles the "any" case + if (!prefixlength) { + return _true; + } + + switch (sa1->sa_family) + { + case AF_INET: + addr1 = (char *) &(((struct sockaddr_in *) sa1)->sin_addr); + realaf1 = AF_INET; + break; + case AF_INET6: + addr1 = (char *) &(((struct sockaddr_in6 *) sa1)->sin6_addr); + realaf1 = AF_INET6; + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *) addr1)) + { /* shift the pointer for a mapped address */ + addr1 += (sizeof (struct in6_addr)) - (sizeof (struct in_addr)); + realaf1 = AF_INET; + } + break; + default: + return(!_true); + } + + switch (sa2->sa_family) + { + case AF_INET: + addr2 = (char *) &(((struct sockaddr_in *) sa2)->sin_addr); + realaf2 = AF_INET; + break; + case AF_INET6: + addr2 = (char *) &(((struct sockaddr_in6 *) sa2)->sin6_addr); + realaf2 = AF_INET6; + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *) addr2)) { + /* shift the pointer for a mapped address */ + addr2 += (sizeof (struct in6_addr)) - (sizeof (struct in_addr)); + realaf2 = AF_INET; + } + break; + default: + return(!_true); + } + + if (realaf1 != realaf2) { + return(!_true); + } + + ip_div = div(prefixlength, 8); + + for (i=0; i < ip_div.quot; i++) { + if (addr1[i] != addr2[i]) { + return(!_true); + } + } + if (ip_div.rem) { + modbits = ((unsigned char) ~0) << (8 - ip_div.rem); + if ( (addr1[i] & modbits) != (addr2[i] & modbits) ) { + return(!_true); + } + } + return(_true); +} + + +/* Must be a valid string, called after OS_IsValidTime + * Returns 1 on success or 0 on failure + */ +int OS_IsonTime(const char *time_str, const char *openarmor_time) +{ + int _true = 1; + + if (*openarmor_time == '!') { + _true = 0; + } + openarmor_time++; + + /* Comparing against min/max value */ + if ((strncmp(time_str, openarmor_time, 5) >= 0) && + (strncmp(time_str, openarmor_time + 5, 5) <= 0)) { + return (_true); + } + + return (!_true); +} + +/* Validate if a time is in an acceptable format for openarmor. + * Returns 0 if doesn't match or a valid string for openarmor usage in success. + * ** On success this function may modify the value of date + * Acceptable formats: + * hh:mm - hh:mm (24 hour format) + * !hh:mm -hh:mm (24 hour format) + * hh - hh (24 hour format) + * hh:mm am - hh:mm pm (12 hour format) + * hh am - hh pm (12 hour format) + */ +#define RM_WHITE(x)while(*x == ' ')x++; + +static const char *__gethour(const char *str, char *openarmor_hour) +{ + int _size = 0; + int chour = 0; + int cmin = 0; + + /* Invalid time format */ + if (!isdigit((int)*str)) { + merror(INVALID_TIME, __local_name, str); + } + + /* Hour */ + chour = atoi(str); + + /* Get a valid hour */ + if (chour < 0 || chour >= 24) { + merror(INVALID_TIME, __local_name, str); + return (NULL); + } + + /* Go after the hour */ + while (isdigit((int)*str)) { + _size++; + str++; + } + + /* Invalid hour */ + if (_size > 2) { + merror(INVALID_TIME, __local_name, str); + return (NULL); + } + + /* Get minute */ + if (*str == ':') { + str++; + if ((!isdigit((int)*str) || + !isdigit((int) * (str + 1))) && isdigit((int) * (str + 2))) { + merror(INVALID_TIME, __local_name, str); + return (NULL); + } + + cmin = atoi(str); + str += 2; + } + + /* Remove spaces */ + RM_WHITE(str); + + if ((*str == 'a') || (*str == 'A')) { + str++; + if ((*str == 'm') || (*str == 'M')) { + snprintf(openarmor_hour, 6, "%02d:%02d", chour, cmin); + str++; + return (str); + } + } else if ((*str == 'p') || (*str == 'P')) { + str++; + if ((*str == 'm') || (*str == 'M')) { + if(chour != 12) { + chour += 12; + } + + /* New hour must be valid */ + if (chour < 0 || chour >= 24) { + merror(INVALID_TIME, __local_name, str); + return (NULL); + } + + snprintf(openarmor_hour, 6, "%02d:%02d", chour, cmin); + str++; + return (str); + } + + } else { + snprintf(openarmor_hour, 6, "%02d:%02d", chour, cmin); + return (str); + } + + /* Here is error */ + merror(INVALID_TIME, __local_name, str); + return (NULL); +} + +char *OS_IsValidTime(const char *time_str) +{ + char *ret; + char first_hour[7]; + char second_hour[7]; + int ng = 0; + + /* Must be not null */ + if (!time_str) { + return (NULL); + } + + /* Clear memory */ + memset(first_hour, '\0', 7); + memset(second_hour, '\0', 7); + + /* Remove spaces */ + RM_WHITE(time_str); + + /* Check for negative */ + if (*time_str == '!') { + ng = 1; + time_str++; + + /* We may have spaces after the '!' */ + RM_WHITE(time_str); + } + + /* Get first hour */ + time_str = __gethour(time_str, first_hour); + if (!time_str) { + return (NULL); + } + + /* Remove spaces */ + RM_WHITE(time_str); + + if (*time_str != '-') { + return (NULL); + } + + time_str++; + + /* Remove spaces */ + RM_WHITE(time_str); + + /* Get second hour */ + time_str = __gethour(time_str, second_hour); + if (!time_str) { + return (NULL); + } + + RM_WHITE(time_str); + if (*time_str != '\0') { + return (NULL); + } + + os_calloc(13, sizeof(char), ret); + + /* Fix dump hours */ + if (strcmp(first_hour, second_hour) > 0) { + snprintf(ret, 12, "!%s%s", second_hour, first_hour); + return (ret); + } + + /* For the normal times */ + snprintf(ret, 12, "%c%s%s", ng == 0 ? '.' : '!', first_hour, second_hour); + return (ret); +} + +/* Check if the current time is the same or has passed the specified one */ +int OS_IsAfterTime(const char *time_str, const char *openarmor_time) +{ + /* Unique times can't have a ! */ + if (*openarmor_time == '!') { + return (0); + } + + openarmor_time++; + + /* Compare against min/max value */ + if (strncmp(time_str, openarmor_time, 5) >= 0) { + return (1); + } + + return (0); +} + +/* Create a unique time, not a range. Must be used with OS_IsAfterTime. */ +char *OS_IsValidUniqueTime(const char *time_str) +{ + char mytime[128 + 1]; + + if (*time_str == '!') { + return (NULL); + } + + memset(mytime, '\0', 128 + 1); + snprintf(mytime, 128, "%s-%s", time_str, time_str); + + return (OS_IsValidTime(mytime)); +} + +/* Check if the specified week day is in the range */ +int OS_IsonDay(int week_day, const char *openarmor_day) +{ + int _true = 1; + + /* Negative */ + if (openarmor_day[7] == '!') { + _true = 0; + } + + if (week_day < 0 || week_day > 7) { + return (0); + } + + /* It is on the right day */ + if (openarmor_day[week_day] == 1) { + return (_true); + } + + return (!_true); +} + +/* Validate if a day is in an acceptable format for openarmor + * Returns 0 if doesn't match or a valid string for openarmor usage in success. + * WARNING: On success this function may modify the value of date + * Acceptable formats: + * weekdays, weekends, monday, tuesday, thursday,.. + * monday,tuesday + * mon,tue wed + */ +#define RM_SEP(x)while((*x == ' ') || (*x == ','))x++; + +#define IS_SEP(x) (*x == ' ' || *x == ',') + +char *OS_IsValidDay(const char *day_str) +{ + int i = 0, ng = 0; + char *ret; + char day_ret[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + const char *(days[]) = { + "sunday", "sun", "monday", "mon", "tuesday", "tue", + "wednesday", "wed", "thursday", "thu", "friday", + "fri", "saturday", "sat", "weekdays", "weekends", NULL + }; + int days_int[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8}; + + /* Must be a valid string */ + if (!day_str) { + return (NULL); + } + + RM_WHITE(day_str); + + /* Check for negatives */ + if (*day_str == '!') { + ng = 1; + RM_WHITE(day_str); + } + + while (*day_str != '\0') { + i = 0; + while (days[i]) { + if (strncasecmp(day_str, days[i], strlen(days[i])) == 0) { + /* Weekdays */ + if (days_int[i] == 7) { + day_ret[1] = 1; + day_ret[2] = 1; + day_ret[3] = 1; + day_ret[4] = 1; + day_ret[5] = 1; + } + /* Weekends */ + else if (days_int[i] == 8) { + day_ret[0] = 1; + day_ret[6] = 1; + } else { + day_ret[days_int[i]] = 1; + } + break; + } + i++; + } + + if (!days[i]) { + merror(INVALID_DAY, __local_name, day_str); + return (NULL); + } + + day_str += strlen(days[i]); + + if (IS_SEP(day_str)) { + RM_SEP(day_str); + continue; + } else if (*day_str == '\0') { + break; + } else { + merror(INVALID_DAY, __local_name, day_str); + return (NULL); + } + } + + /* Assign values */ + os_calloc(9, sizeof(char), ret); + if (ng == 1) { + /* Set negative */ + ret[7] = '!'; + } + + ng = 0; + for (i = 0; i <= 6; i++) { + /* Check if some is checked */ + if (day_ret[i] == 1) { + ng = 1; + } + ret[i] = day_ret[i]; + } + + /* At least one day must be checked */ + if (ng == 0) { + free(ret); + merror(INVALID_DAY, __local_name, day_str); + return (NULL); + } + + return (ret); +} + diff --git a/src/shared/wait_op.c b/src/shared/wait_op.c new file mode 100644 index 000000000..d70338012 --- /dev/null +++ b/src/shared/wait_op.c @@ -0,0 +1,122 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" + +#define LOCK_LOOP 5 + +static int __wait_lock = 0; + + +/* Create global lock */ +void os_setwait() +{ + FILE *fp = NULL; + + /* For same threads */ + __wait_lock = 1; + + if (isChroot()) { + fp = fopen(WAIT_FILE, "w"); + } else { + fp = fopen(WAIT_FILE_PATH, "w"); + } + + if (fp) { + fprintf(fp, "l"); + fclose(fp); + } + + return; +} + +/* Remove global lock */ +void os_delwait() +{ + __wait_lock = 0; + + if (isChroot()) { + if ((unlink(WAIT_FILE)) < 0) { + merror("Cannot unlink %s: %s", WAIT_FILE, strerror(errno)); + } + } else { + if ((unlink(WAIT_FILE_PATH)) < 0) { + merror("Cannot unlink %s: %s", WAIT_FILE_PATH, strerror(errno)); + } + } + return; +} + +/* Check for the wait file. If present, wait. + * Works as a simple inter process lock (only the main + * process is allowed to lock). + */ +#ifdef WIN32 +void os_wait() +{ + if (!__wait_lock) { + return; + } + + /* Wait until the lock is gone */ + verbose(WAITING_MSG, __local_name); + while (1) { + if (!__wait_lock) { + break; + } + + /* Sleep LOCK_LOOP seconds and check if lock is gone */ + sleep(LOCK_LOOP); + } + + verbose(WAITING_FREE, __local_name); + return; + +} + +#else /* !WIN32 */ + +void os_wait() +{ + struct stat file_status; + + /* If the wait file is not present, keep going */ + if (isChroot()) { + if (stat(WAIT_FILE, &file_status) == -1) { + return; + } + } else { + if (stat(WAIT_FILE_PATH, &file_status) == -1) { + return; + } + } + + /* Wait until the lock is gone */ + verbose(WAITING_MSG, __local_name); + while (1) { + if (isChroot()) { + if (stat(WAIT_FILE, &file_status) == -1) { + break; + } + } else { + if (stat(WAIT_FILE_PATH, &file_status) == -1) { + break; + } + } + + /* Sleep LOCK_LOOP seconds and check if lock is gone */ + sleep(LOCK_LOOP); + } + + verbose(WAITING_FREE, __local_name); + return; +} + +#endif /* !WIN32 */ + diff --git a/src/syscheckd/config.c b/src/syscheckd/config.c new file mode 100644 index 000000000..4cec1bafd --- /dev/null +++ b/src/syscheckd/config.c @@ -0,0 +1,84 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "syscheck.h" +#include "config/config.h" + +#ifdef WIN32 +static char *SYSCHECK_EMPTY[] = { NULL }; +#endif + + +int Read_Syscheck_Config(const char *cfgfile) +{ + int modules = 0; + + modules |= CSYSCHECK; + + syscheck.rootcheck = 0; + syscheck.disabled = 0; + syscheck.skip_nfs = 0; + syscheck.scan_on_start = 1; + syscheck.time = SYSCHECK_WAIT * 2; + syscheck.ignore = NULL; + syscheck.ignore_regex = NULL; + syscheck.nodiff = NULL; + syscheck.nodiff_regex = NULL; + syscheck.scan_day = NULL; + syscheck.scan_time = NULL; + syscheck.dir = NULL; + syscheck.opts = NULL; + syscheck.realtime = NULL; +#ifdef WIN32 + syscheck.registry = NULL; + syscheck.reg_fp = NULL; +#endif + syscheck.prefilter_cmd = NULL; + + debug2("%s: Reading Configuration [%s]", "syscheckd", cfgfile); + + /* Read config */ + if (ReadConfig(modules, cfgfile, &syscheck, NULL) < 0) { + return (OS_INVALID); + } + +#ifdef CLIENT + debug2("%s: Reading Client Configuration [%s]", "syscheckd", cfgfile); + + /* Read shared config */ + modules |= CAGENT_CONFIG; + ReadConfig(modules, AGENTCONFIG, &syscheck, NULL); +#endif + +#ifndef WIN32 + /* We must have at least one directory to check */ + if (!syscheck.dir || syscheck.dir[0] == NULL) { + return (1); + } +#else + /* We must have at least one directory or registry key to check. Since + it's possible on Windows to have syscheck enabled but only monitoring + either the filesystem or the registry, both lists must be valid, + even if empty. + */ + if (!syscheck.dir) { + syscheck.dir = SYSCHECK_EMPTY; + } + if (!syscheck.registry) { + syscheck.registry = SYSCHECK_EMPTY; + } + if ((syscheck.dir[0] == NULL) && (syscheck.registry[0] == NULL)) { + return (1); + } +#endif + + return (0); +} + diff --git a/src/syscheckd/create_db.c b/src/syscheckd/create_db.c new file mode 100644 index 000000000..3340fe5bf --- /dev/null +++ b/src/syscheckd/create_db.c @@ -0,0 +1,480 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "syscheck.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/sha1/sha1_op.h" +#include "os_crypto/md5_sha1/md5_sha1_op.h" +#ifdef WIN32 +#include +#include +#endif + +/* Prototypes */ +static int read_file(const char *dir_name, int opts, OSMatch *restriction) __attribute__((nonnull(1))); + +/* Global variables */ +static int __counter = 0; + + +/* Read and generate the integrity data of a file */ +static int read_file(const char *file_name, int opts, OSMatch *restriction) +{ + char *buf; + char sha1s = '+'; + struct stat statbuf; + + /* Check if the file should be ignored */ + if (syscheck.ignore) { + int i = 0; + while (syscheck.ignore[i] != NULL) { + if (strncasecmp(syscheck.ignore[i], file_name, + strlen(syscheck.ignore[i])) == 0) { + return (0); + } + i++; + } + } + + /* Check in the regex entry */ + if (syscheck.ignore_regex) { + int i = 0; + while (syscheck.ignore_regex[i] != NULL) { + if (OSMatch_Execute(file_name, strlen(file_name), + syscheck.ignore_regex[i])) { + return (0); + } + i++; + } + } + +#ifdef WIN32 + /* Win32 does not have lstat */ + if (stat(file_name, &statbuf) < 0) +#else + if (lstat(file_name, &statbuf) < 0) +#endif + { + if(errno == ENOTDIR){ + /*Deletion message sending*/ + char alert_msg[PATH_MAX+4]; + alert_msg[PATH_MAX + 3] = '\0'; + snprintf(alert_msg, PATH_MAX + 4, "-1 %s", file_name); + send_syscheck_msg(alert_msg); + return (0); + }else{ + merror("%s: Error accessing '%s'.", ARGV0, file_name); + return (-1); + } + } + + if (S_ISDIR(statbuf.st_mode)) { +#ifdef DEBUG + verbose("%s: Reading dir: %s\n", ARGV0, file_name); +#endif + +#ifdef WIN32 + /* Directory links are not supported */ + if (GetFileAttributes(file_name) & FILE_ATTRIBUTE_REPARSE_POINT) { + merror("%s: WARN: Links are not supported: '%s'", ARGV0, file_name); + return (-1); + } +#endif + return (read_dir(file_name, opts, restriction)); + } + + /* Restrict file types */ + if (restriction) { + if (!OSMatch_Execute(file_name, strlen(file_name), + restriction)) { + return (0); + } + } + + /* No S_ISLNK on Windows */ +#ifdef WIN32 + if (S_ISREG(statbuf.st_mode)) +#else + if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) +#endif + { + os_md5 mf_sum; + os_sha1 sf_sum; + os_sha1 sf_sum2; + os_sha1 sf_sum3; + + /* Clean sums */ + strncpy(mf_sum, "xxx", 4); + strncpy(sf_sum, "xxx", 4); + strncpy(sf_sum2, "xxx", 4); + strncpy(sf_sum3, "xxx", 4); + + /* Generate checksums */ + if ((opts & CHECK_MD5SUM) || (opts & CHECK_SHA1SUM)) { + /* If it is a link, check if dest is valid */ +#ifndef WIN32 + if (S_ISLNK(statbuf.st_mode)) { + struct stat statbuf_lnk; + if (stat(file_name, &statbuf_lnk) == 0) { + if (S_ISREG(statbuf_lnk.st_mode)) { + if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) { + strncpy(mf_sum, "xxx", 4); + strncpy(sf_sum, "xxx", 4); + } + } + } + } else if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) +#else + if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) +#endif + { + strncpy(mf_sum, "xxx", 4); + strncpy(sf_sum, "xxx", 4); + } + + if (opts & CHECK_SEECHANGES) { + sha1s = 's'; + } + } else { + if (opts & CHECK_SEECHANGES) { + sha1s = 'n'; + } else { + sha1s = '-'; + } + } + + buf = (char *) OSHash_Get(syscheck.fp, file_name); + if (!buf) { + char alert_msg[916 + 1]; /* to accommodate a long */ + alert_msg[916] = '\0'; + +#ifndef WIN32 + if (opts & CHECK_SEECHANGES) { + char *alertdump = seechanges_addfile(file_name); + if (alertdump) { + free(alertdump); + alertdump = NULL; + } + } +#endif + + snprintf(alert_msg, 916, "%c%c%c%c%c%c%ld:%d:%d:%d:%s:%s", + opts & CHECK_SIZE ? '+' : '-', + opts & CHECK_PERM ? '+' : '-', + opts & CHECK_OWNER ? '+' : '-', + opts & CHECK_GROUP ? '+' : '-', + opts & CHECK_MD5SUM ? '+' : '-', + sha1s, + opts & CHECK_SIZE ? (long)statbuf.st_size : 0, + opts & CHECK_PERM ? (int)statbuf.st_mode : 0, + opts & CHECK_OWNER ? (int)statbuf.st_uid : 0, + opts & CHECK_GROUP ? (int)statbuf.st_gid : 0, + opts & CHECK_MD5SUM ? mf_sum : "xxx", + opts & CHECK_SHA1SUM ? sf_sum : "xxx"); + + if (OSHash_Add(syscheck.fp, file_name, strdup(alert_msg)) <= 0) { + merror("%s: ERROR: Unable to add file to db: %s", ARGV0, file_name); + } + + /* Send the new checksum to the analysis server */ + alert_msg[916] = '\0'; + +#ifndef WIN32 + snprintf(alert_msg, 916, "%ld:%d:%d:%d:%s:%s %s", + opts & CHECK_SIZE ? (long)statbuf.st_size : 0, + opts & CHECK_PERM ? (int)statbuf.st_mode : 0, + opts & CHECK_OWNER ? (int)statbuf.st_uid : 0, + opts & CHECK_GROUP ? (int)statbuf.st_gid : 0, + opts & CHECK_MD5SUM ? mf_sum : "xxx", + opts & CHECK_SHA1SUM ? sf_sum : "xxx", + file_name); +#else + + HANDLE hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + DWORD dwErrorCode = GetLastError(); + char alert_msg[PATH_MAX+4]; + alert_msg[PATH_MAX + 3] = '\0'; + snprintf(alert_msg, PATH_MAX + 4, "CreateFile=%ld %s", dwErrorCode, file_name); + send_syscheck_msg(alert_msg); + return -1; + } + + PSID pSidOwner = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + DWORD dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD); + if (dwRtnCode != ERROR_SUCCESS) { + DWORD dwErrorCode = GetLastError(); + CloseHandle(hFile); + char alert_msg[PATH_MAX+4]; + alert_msg[PATH_MAX + 3] = '\0'; + snprintf(alert_msg, PATH_MAX + 4, "GetSecurityInfo=%ld %s", dwErrorCode, file_name); + send_syscheck_msg(alert_msg); + return -1; + } + + LPSTR szSID = NULL; + ConvertSidToStringSid(pSidOwner, &szSID); + char* st_uid = NULL; + if(szSID) { + st_uid = (char *) calloc(strlen(szSID) + 1, 1); + memcpy(st_uid, szSID, strlen(szSID)); + } + LocalFree(szSID); + CloseHandle(hFile); + + snprintf(alert_msg, 916, "%ld:%d:%s:%d:%s:%s %s", + opts & CHECK_SIZE ? (long)statbuf.st_size : 0, + opts & CHECK_PERM ? (int)statbuf.st_mode : 0, + (opts & CHECK_OWNER) ? st_uid : "0", + opts & CHECK_GROUP ? (int)statbuf.st_gid : 0, + opts & CHECK_MD5SUM ? mf_sum : "xxx", + opts & CHECK_SHA1SUM ? sf_sum : "xxx", + file_name); + free(st_uid); +#endif + send_syscheck_msg(alert_msg); + } else { + char alert_msg[OS_MAXSTR + 1]; + char c_sum[256 + 2]; + + c_sum[0] = '\0'; + c_sum[256] = '\0'; + alert_msg[0] = '\0'; + alert_msg[OS_MAXSTR] = '\0'; + + /* If it returns < 0, we have already alerted */ + if (c_read_file(file_name, buf, c_sum) < 0) { + return (0); + } + + if (strcmp(c_sum, buf + 6) != 0) { + /* Send the new checksum to the analysis server */ + alert_msg[OS_MAXSTR] = '\0'; + #ifdef WIN32 + snprintf(alert_msg, 916, "%s %s", c_sum, file_name); + #else + char *fullalert = NULL; + if (buf[5] == 's' || buf[5] == 'n') { + fullalert = seechanges_addfile(file_name); + if (fullalert) { + snprintf(alert_msg, OS_MAXSTR, "%s %s\n%s", c_sum, file_name, fullalert); + free(fullalert); + fullalert = NULL; + } else { + snprintf(alert_msg, 916, "%s %s", c_sum, file_name); + } + } else { + snprintf(alert_msg, 916, "%s %s", c_sum, file_name); + } + #endif + send_syscheck_msg(alert_msg); + } + } + + /* Sleep here too */ + if (__counter >= (syscheck.sleep_after)) { + sleep(syscheck.tsleep); + __counter = 0; + } + __counter++; + +#ifdef DEBUG + verbose("%s: file '%s %s'", ARGV0, file_name, mf_sum); +#endif + } else { +#ifdef DEBUG + verbose("%s: *** IRREG file: '%s'\n", ARGV0, file_name); +#endif + } + + return (0); +} + +int read_dir(const char *dir_name, int opts, OSMatch *restriction) +{ + size_t dir_size; + char f_name[PATH_MAX + 2]; + short is_nfs; + + DIR *dp; + struct dirent *entry; + + f_name[PATH_MAX + 1] = '\0'; + + /* Directory should be valid */ + if ((dir_size = strlen(dir_name)) > PATH_MAX) { + merror(NULL_ERROR, ARGV0); + return (-1); + } + + /* Should we check for NFS? */ + if(syscheck.skip_nfs) + { + is_nfs = IsNFS(dir_name); + if(is_nfs != 0) + { + // Error will be -1, and 1 means skipped + return(is_nfs); + } + } + + + /* Open the directory given */ + dp = opendir(dir_name); + if (!dp) { + if (errno == ENOTDIR) { + if (read_file(dir_name, opts, restriction) == 0) { + return (0); + } + } + +#ifdef WIN32 + int di = 0; + char *(defaultfilesn[]) = { + "C:\\autoexec.bat", + "C:\\config.sys", + "C:\\WINDOWS/System32/eventcreate.exe", + "C:\\WINDOWS/System32/eventtriggers.exe", + "C:\\WINDOWS/System32/tlntsvr.exe", + "C:\\WINDOWS/System32/Tasks", + NULL + }; + while (defaultfilesn[di] != NULL) { + if (strcmp(defaultfilesn[di], dir_name) == 0) { + break; + } + di++; + } + + if (defaultfilesn[di] == NULL) { + merror("%s: WARN: Error opening directory: '%s': %s ", + ARGV0, dir_name, strerror(errno)); + } +#else + merror("%s: WARN: Error opening directory: '%s': %s ", + ARGV0, + dir_name, + strerror(errno)); +#endif /* WIN32 */ + return (-1); + } + + /* Check for real time flag */ + if (opts & CHECK_REALTIME) { +#if defined(INOTIFY_ENABLED) || defined(WIN32) + realtime_adddir(dir_name); +#else + merror("%s: WARN: realtime monitoring request on unsupported system for '%s'", + ARGV0, + dir_name + ); +#endif + } + + while ((entry = readdir(dp)) != NULL) { + char *s_name; + + /* Ignore . and .. */ + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { + continue; + } + + strncpy(f_name, dir_name, PATH_MAX); + s_name = f_name; + s_name += dir_size; + + /* Check if the file name is already null terminated */ + if (*(s_name - 1) != '/') { + *s_name++ = '/'; + } + + *s_name = '\0'; + strncpy(s_name, entry->d_name, PATH_MAX - dir_size - 2); + + /* Check if the file is a directory */ + if(opts & CHECK_NORECURSE) { + struct stat recurse_sb; + if((stat(f_name, &recurse_sb)) < 0) { + merror("%s: ERR: Cannot stat %s: %s", ARGV0, f_name, strerror(errno)); + } else { + switch (recurse_sb.st_mode & S_IFMT) { + case S_IFDIR: + continue; + break; + } + } + } + + + /* Check integrity of the file */ + read_file(f_name, opts, restriction); + } + + closedir(dp); + return (0); +} + +int run_dbcheck() +{ + int i = 0; + + __counter = 0; + while (syscheck.dir[i] != NULL) { + read_dir(syscheck.dir[i], syscheck.opts[i], syscheck.filerestrict[i]); + i++; + } + + return (0); +} + +int create_db() +{ + int i = 0; + + /* Create store data */ + syscheck.fp = OSHash_Create(); + if (!syscheck.fp) { + ErrorExit("%s: Unable to create syscheck database." + ". Exiting.", ARGV0); + } + + if (!OSHash_setSize(syscheck.fp, 2048)) { + merror(LIST_ERROR, ARGV0); + return (0); + } + + if ((syscheck.dir == NULL) || (syscheck.dir[0] == NULL)) { + merror("%s: No directories to check.", ARGV0); + return (-1); + } + + merror("%s: INFO: Starting syscheck database (pre-scan).", ARGV0); + + /* Read all available directories */ + __counter = 0; + do { + if (read_dir(syscheck.dir[i], syscheck.opts[i], syscheck.filerestrict[i]) == 0) { + debug2("%s: Directory loaded from syscheck db: %s", ARGV0, syscheck.dir[i]); + } + i++; + } while (syscheck.dir[i] != NULL); + +#if defined (INOTIFY_ENABLED) || defined (WIN32) + if (syscheck.realtime && (syscheck.realtime->fd >= 0)) { + verbose("%s: INFO: Real time file monitoring started.", ARGV0); + } +#endif + merror("%s: INFO: Finished creating syscheck database (pre-scan " + "completed).", ARGV0); + return (0); +} + diff --git a/src/syscheckd/run_check.c b/src/syscheckd/run_check.c new file mode 100644 index 000000000..4839b6988 --- /dev/null +++ b/src/syscheckd/run_check.c @@ -0,0 +1,469 @@ +/* Copyright (C) 2010 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* SCHED_BATCH is Linux specific and is only picked up with _GNU_SOURCE */ +#ifdef __linux__ +#define _GNU_SOURCE +#include +#endif +#ifdef WIN32 +#include +#include +#include +#endif + +#include "shared.h" +#include "syscheck.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/sha1/sha1_op.h" +#include "os_crypto/md5_sha1/md5_sha1_op.h" +#include "rootcheck/rootcheck.h" + +/* Prototypes */ +static void send_sk_db(void); + + +/* Send a message related to syscheck change/addition */ +int send_syscheck_msg(const char *msg) +{ + if (SendMSG(syscheck.queue, msg, SYSCHECK, SYSCHECK_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* Try to send it again */ + SendMSG(syscheck.queue, msg, SYSCHECK, SYSCHECK_MQ); + } + return (0); +} + +/* Send a message related to rootcheck change/addition */ +int send_rootcheck_msg(const char *msg) +{ + if (SendMSG(syscheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* Try to send it again */ + SendMSG(syscheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ); + } + return (0); +} + +/* Send syscheck db to the server */ +static void send_sk_db() +{ + /* Send scan start message */ + if (syscheck.dir[0]) { + merror("%s: INFO: Starting syscheck scan (forwarding database).", ARGV0); + send_rootcheck_msg("Starting syscheck scan."); + } else { + return; + } + + create_db(); + + /* Send scan ending message */ + sleep(syscheck.tsleep + 10); + + if (syscheck.dir[0]) { + merror("%s: INFO: Ending syscheck scan (forwarding database).", ARGV0); + send_rootcheck_msg("Ending syscheck scan."); + } +} + +/* Periodically run the integrity checker */ +void start_daemon() +{ + int day_scanned = 0; + int curr_day = 0; + time_t curr_time = 0; + time_t prev_time_rk = 0; + time_t prev_time_sk = 0; + char curr_hour[12]; + struct tm *p; + +#ifdef INOTIFY_ENABLED + /* To be used by select */ + struct timeval selecttime; + fd_set rfds; +#endif + + /* SCHED_BATCH forces the kernel to assume this is a cpu intensive + * process and gives it a lower priority. This keeps openarmor-syscheckd + * from reducing the interactivity of an ssh session when checksumming + * large files. This is available in kernel flavors >= 2.6.16. + */ +#ifdef SCHED_BATCH + struct sched_param pri; + int status; + + pri.sched_priority = 0; + status = sched_setscheduler(0, SCHED_BATCH, &pri); + + debug1("%s: Setting SCHED_BATCH returned: %d", ARGV0, status); +#endif + +#ifdef DEBUG + verbose("%s: Starting daemon ..", ARGV0); +#endif + + /* Some time to settle */ + memset(curr_hour, '\0', 12); + sleep(syscheck.tsleep * 10); + + /* If the scan time/day is set, reset the + * syscheck.time/rootcheck.time + */ + if (syscheck.scan_time || syscheck.scan_day) { + /* At least once a week */ + syscheck.time = 604800; + rootcheck.time = 604800; + } + + /* Will create the db to store syscheck data */ + if (syscheck.scan_on_start) { + sleep(syscheck.tsleep * 15); + send_sk_db(); + +#ifdef WIN32 + /* Check for registry changes on Windows */ + os_winreg_check(); +#endif + /* Send database completed message */ + send_syscheck_msg(HC_SK_DB_COMPLETED); + debug2("%s: DEBUG: Sending database completed message.", ARGV0); + + } else { + prev_time_rk = time(0); + } + + /* Before entering in daemon mode itself */ + prev_time_sk = time(0); + sleep(syscheck.tsleep * 10); + + /* If the scan_time or scan_day is set, we need to handle the + * current day/time on the loop. + */ + if (syscheck.scan_time || syscheck.scan_day) { + curr_time = time(0); + p = localtime(&curr_time); + + /* Assign hour/min/sec values */ + snprintf(curr_hour, 9, "%02d:%02d:%02d", + p->tm_hour, + p->tm_min, + p->tm_sec); + + curr_day = p->tm_mday; + + if (syscheck.scan_time && syscheck.scan_day) { + if ((OS_IsAfterTime(curr_hour, syscheck.scan_time)) && + (OS_IsonDay(p->tm_wday, syscheck.scan_day))) { + day_scanned = 1; + } + } else if (syscheck.scan_time) { + if (OS_IsAfterTime(curr_hour, syscheck.scan_time)) { + day_scanned = 1; + } + } else if (syscheck.scan_day) { + if (OS_IsonDay(p->tm_wday, syscheck.scan_day)) { + day_scanned = 1; + } + } + } + + /* Check every SYSCHECK_WAIT */ + while (1) { + int run_now = 0; + curr_time = time(0); + + /* Check if syscheck should be restarted */ + run_now = os_check_restart_syscheck(); + + /* Check if a day_time or scan_time is set */ + if (syscheck.scan_time || syscheck.scan_day) { + p = localtime(&curr_time); + + /* Day changed */ + if (curr_day != p->tm_mday) { + day_scanned = 0; + curr_day = p->tm_mday; + } + + /* Check for the time of the scan */ + if (!day_scanned && syscheck.scan_time && syscheck.scan_day) { + /* Assign hour/min/sec values */ + snprintf(curr_hour, 9, "%02d:%02d:%02d", + p->tm_hour, p->tm_min, p->tm_sec); + + if ((OS_IsAfterTime(curr_hour, syscheck.scan_time)) && + (OS_IsonDay(p->tm_wday, syscheck.scan_day))) { + day_scanned = 1; + run_now = 1; + } + } else if (!day_scanned && syscheck.scan_time) { + /* Assign hour/min/sec values */ + snprintf(curr_hour, 9, "%02d:%02d:%02d", + p->tm_hour, p->tm_min, p->tm_sec); + + if (OS_IsAfterTime(curr_hour, syscheck.scan_time)) { + run_now = 1; + day_scanned = 1; + } + } else if (!day_scanned && syscheck.scan_day) { + /* Check for the day of the scan */ + if (OS_IsonDay(p->tm_wday, syscheck.scan_day)) { + run_now = 1; + day_scanned = 1; + } + } + } + + /* If time elapsed is higher than the rootcheck_time, run it */ + if (syscheck.rootcheck) { + if (((curr_time - prev_time_rk) > rootcheck.time) || run_now) { + run_rk_check(); + prev_time_rk = time(0); + } + } + + /* If time elapsed is higher than the syscheck time, run syscheck time */ + if (((curr_time - prev_time_sk) > syscheck.time) || run_now) { + if (syscheck.scan_on_start == 0) { + /* Need to create the db if scan on start is not set */ + sleep(syscheck.tsleep * 10); + send_sk_db(); + sleep(syscheck.tsleep * 10); + + syscheck.scan_on_start = 1; + } else { + /* Send scan start message */ + if (syscheck.dir[0]) { + merror("%s: INFO: Starting syscheck scan.", ARGV0); + send_rootcheck_msg("Starting syscheck scan."); + } +#ifdef WIN32 + /* Check for registry changes on Windows */ + os_winreg_check(); +#endif + /* Check for changes */ + run_dbcheck(); + } + + /* Send scan ending message */ + sleep(syscheck.tsleep + 20); + if (syscheck.dir[0]) { + merror("%s: INFO: Ending syscheck scan.", ARGV0); + send_rootcheck_msg("Ending syscheck scan."); + } + + /* Send database completed message */ + send_syscheck_msg(HC_SK_DB_COMPLETED); + debug2("%s: DEBUG: Sending database completed message.", ARGV0); + + prev_time_sk = time(0); + } + +#ifdef INOTIFY_ENABLED + if (syscheck.realtime && (syscheck.realtime->fd >= 0)) { + selecttime.tv_sec = SYSCHECK_WAIT; + selecttime.tv_usec = 0; + + /* zero-out the fd_set */ + FD_ZERO (&rfds); + FD_SET(syscheck.realtime->fd, &rfds); + + run_now = select(syscheck.realtime->fd + 1, &rfds, + NULL, NULL, &selecttime); + if (run_now < 0) { + merror("%s: ERROR: Select failed (for realtime fim).", ARGV0); + sleep(SYSCHECK_WAIT); + } else if (run_now == 0) { + /* Timeout */ + } else if (FD_ISSET (syscheck.realtime->fd, &rfds)) { + realtime_process(); + } + } else { + sleep(SYSCHECK_WAIT); + } +#elif defined(WIN32) + if (syscheck.realtime && (syscheck.realtime->fd >= 0)) { + if (WaitForSingleObjectEx(syscheck.realtime->evt, SYSCHECK_WAIT * 1000, TRUE) == WAIT_FAILED) { + merror("%s: ERROR: WaitForSingleObjectEx failed (for realtime fim).", ARGV0); + sleep(SYSCHECK_WAIT); + } else { + sleep(1); + } + } else { + sleep(SYSCHECK_WAIT); + } +#else + sleep(SYSCHECK_WAIT); +#endif + } +} + +/* Read file information and return a pointer to the checksum */ +int c_read_file(const char *file_name, const char *oldsum, char *newsum) +{ + int size = 0, perm = 0, owner = 0, group = 0, md5sum = 0, sha1sum = 0; + int return_error = 0; + struct stat statbuf; + os_md5 mf_sum; + os_sha1 sf_sum; + + /* Clean sums */ + strncpy(mf_sum, "xxx", 4); + strncpy(sf_sum, "xxx", 4); + + /* Stat the file */ +#ifdef WIN32 + return_error = (stat(file_name, &statbuf) < 0); +#else + return_error = (lstat(file_name, &statbuf) < 0); +#endif + if (return_error) + { + char alert_msg[PATH_MAX+4]; + + alert_msg[PATH_MAX + 3] = '\0'; + snprintf(alert_msg, PATH_MAX + 4, "-1 %s", file_name); + send_syscheck_msg(alert_msg); + + return (-1); + } + + /* Get the old sum values */ + + /* size */ + if (oldsum[0] == '+') { + size = 1; + } + + /* perm */ + if (oldsum[1] == '+') { + perm = 1; + } + + /* owner */ + if (oldsum[2] == '+') { + owner = 1; + } + + /* group */ + if (oldsum[3] == '+') { + group = 1; + } + + /* md5 sum */ + if (oldsum[4] == '+') { + md5sum = 1; + } + + /* sha1 sum */ + if (oldsum[5] == '+') { + sha1sum = 1; + } else if (oldsum[5] == 's') { + sha1sum = 1; + } else if (oldsum[5] == 'n') { + sha1sum = 0; + } + + /* Generate new checksum */ + if (S_ISREG(statbuf.st_mode)) + { + if (sha1sum || md5sum) { + /* Generate checksums of the file */ + if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) { + strncpy(sf_sum, "xxx", 4); + strncpy(mf_sum, "xxx", 4); + } + } + } +#ifndef WIN32 + /* If it is a link, check if the actual file is valid */ + else if (S_ISLNK(statbuf.st_mode)) { + struct stat statbuf_lnk; + if (stat(file_name, &statbuf_lnk) == 0) { + if (S_ISREG(statbuf_lnk.st_mode)) { + if (sha1sum || md5sum) { + /* Generate checksums of the file */ + if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) { + strncpy(sf_sum, "xxx", 4); + strncpy(mf_sum, "xxx", 4); + } + } + } + } + } +#endif + + newsum[0] = '\0'; + newsum[255] = '\0'; +#ifndef WIN32 + snprintf(newsum, 255, "%ld:%d:%d:%d:%s:%s", + size == 0 ? 0 : (long)statbuf.st_size, + perm == 0 ? 0 : (int)statbuf.st_mode, + owner == 0 ? 0 : (int)statbuf.st_uid, + group == 0 ? 0 : (int)statbuf.st_gid, + md5sum == 0 ? "xxx" : mf_sum, + sha1sum == 0 ? "xxx" : sf_sum); +#else + HANDLE hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + DWORD dwErrorCode = GetLastError(); + char alert_msg[PATH_MAX+4]; + alert_msg[PATH_MAX + 3] = '\0'; + snprintf(alert_msg, PATH_MAX + 4, "CreateFile=%ld %s", dwErrorCode, file_name); + send_syscheck_msg(alert_msg); + return -1; + } + + PSID pSidOwner = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + DWORD dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD); + if (dwRtnCode != ERROR_SUCCESS) { + DWORD dwErrorCode = GetLastError(); + CloseHandle(hFile); + char alert_msg[PATH_MAX+4]; + alert_msg[PATH_MAX + 3] = '\0'; + snprintf(alert_msg, PATH_MAX + 4, "GetSecurityInfo=%ld %s", dwErrorCode, file_name); + send_syscheck_msg(alert_msg); + return -1; + } + + LPSTR szSID = NULL; + ConvertSidToStringSid(pSidOwner, &szSID); + char* st_uid = NULL; + if( szSID ) { + st_uid = (char *) calloc( strlen(szSID) + 1, 1 ); + memcpy( st_uid, szSID, strlen(szSID) ); + } + LocalFree(szSID); + CloseHandle(hFile); + + snprintf(newsum, 255, "%ld:%d:%s:%d:%s:%s", + size == 0 ? 0 : (long)statbuf.st_size, + perm == 0 ? 0 : (int)statbuf.st_mode, + owner == 0 ? "0" : st_uid, + group == 0 ? 0 : (int)statbuf.st_gid, + md5sum == 0 ? "xxx" : mf_sum, + sha1sum == 0 ? "xxx" : sf_sum); + + free(st_uid); +#endif + + return (0); +} diff --git a/src/syscheckd/run_realtime.c b/src/syscheckd/run_realtime.c new file mode 100644 index 000000000..575b97c39 --- /dev/null +++ b/src/syscheckd/run_realtime.c @@ -0,0 +1,435 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#define sleep(x) Sleep(x * 1000) +#endif + +#ifdef INOTIFY_ENABLED +#include +#define OS_SIZE_6144 6144 +#define OS_MAXSTR OS_SIZE_6144 /* Size for logs, sockets, etc */ +#else +#include "shared.h" +#endif + +#include "fs_op.h" +#include "hash_op.h" +#include "debug_op.h" +#include "syscheck.h" +#include "error_messages/error_messages.h" + +/* Prototypes */ +int realtime_checksumfile(const char *file_name) __attribute__((nonnull)); + + +/* Checksum of the realtime file being monitored */ +int realtime_checksumfile(const char *file_name) +{ + char *buf; + + buf = (char *) OSHash_Get(syscheck.fp, file_name); + if (buf != NULL) { + char c_sum[256 + 2]; + + c_sum[0] = '\0'; + c_sum[255] = '\0'; + + /* If it returns < 0, we have already alerted */ + if (c_read_file(file_name, buf, c_sum) < 0) { + return (0); + } + + if (strcmp(c_sum, buf + 6) != 0) { + char alert_msg[OS_MAXSTR + 1]; + + alert_msg[OS_MAXSTR] = '\0'; + + #ifdef WIN32 + snprintf(alert_msg, 912, "%s %s", c_sum, file_name); + #else + char *fullalert = NULL; + + if (buf[5] == 's' || buf[5] == 'n') { + fullalert = seechanges_addfile(file_name); + if (fullalert) { + snprintf(alert_msg, OS_MAXSTR, "%s %s\n%s", c_sum, file_name, fullalert); + free(fullalert); + fullalert = NULL; + } else { + snprintf(alert_msg, 912, "%s %s", c_sum, file_name); + } + } else { + snprintf(alert_msg, 912, "%s %s", c_sum, file_name); + } + #endif + send_syscheck_msg(alert_msg); + + return (1); + } + return (0); + } else { + /* New file */ + char *c; + int i; + buf = strdup(file_name); + + /* Find container directory */ + + while (c = strrchr(buf, '/'), c && c != buf) { + *c = '\0'; + + for (i = 0; syscheck.dir[i]; i++) { + if (strcmp(syscheck.dir[i], buf) == 0) { + debug1("%s: DEBUG: Scanning new file '%s' with options for directory '%s'.", ARGV0, file_name, buf); + read_dir(file_name, syscheck.opts[i], syscheck.filerestrict[i]); + break; + } + } + + if (syscheck.dir[i]) { + break; + } + } + + free(buf); + } + + return (0); +} + +#ifdef INOTIFY_ENABLED +#include + +#define REALTIME_MONITOR_FLAGS IN_MODIFY|IN_ATTRIB|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE|IN_DELETE_SELF +#define REALTIME_EVENT_SIZE (sizeof (struct inotify_event)) +#define REALTIME_EVENT_BUFFER (2048 * (REALTIME_EVENT_SIZE + 16)) + +/* Start real time monitoring using inotify */ +int realtime_start() +{ + verbose("%s: INFO: Initializing real time file monitoring (not started).", ARGV0); + + syscheck.realtime = (rtfim *) calloc(1, sizeof(rtfim)); + if (syscheck.realtime == NULL) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + syscheck.realtime->dirtb = OSHash_Create(); + syscheck.realtime->fd = -1; + +#ifdef INOTIFY_ENABLED + syscheck.realtime->fd = inotify_init(); + if (syscheck.realtime->fd < 0) { + merror("%s: ERROR: Unable to initialize inotify.", ARGV0); + return (-1); + } +#endif + + return (1); +} + +/* Add a directory to real time checking */ +int realtime_adddir(const char *dir) +{ + if (!syscheck.realtime) { + realtime_start(); + } + + /* Check if it is ready to use */ + if (syscheck.realtime->fd < 0) { + return (-1); + } else { + int wd = 0; + + if(syscheck.skip_nfs) { + short is_nfs = IsNFS(dir); + if( is_nfs == 1 ) { + merror("%s: ERROR: %s NFS Directories do not support iNotify.", ARGV0, dir); + return(-1); + } + else { + debug2("%s: DEBUG: syscheck.skip_nfs=%d, %s::is_nfs=%d", ARGV0, syscheck.skip_nfs, dir, is_nfs); + } + } + + wd = inotify_add_watch(syscheck.realtime->fd, + dir, + REALTIME_MONITOR_FLAGS); + if (wd < 0) { + merror("%s: ERROR: Unable to add directory to real time " + "monitoring: '%s'. %d %s", ARGV0, dir, wd, strerror(errno)); + } else { + char wdchar[32 + 1]; + wdchar[32] = '\0'; + snprintf(wdchar, 32, "%d", wd); + + /* Entry not present */ + if (!OSHash_Get(syscheck.realtime->dirtb, wdchar)) { + char *ndir; + + ndir = strdup(dir); + if (ndir == NULL) { + ErrorExit("%s: ERROR: Out of memory. Exiting.", ARGV0); + } + + OSHash_Add(syscheck.realtime->dirtb, wdchar, ndir); + debug1("%s: DEBUG: Directory added for real time monitoring: " + "'%s'.", ARGV0, ndir); + } + } + } + + return (1); +} + +/* Process events in the real time queue */ +int realtime_process() +{ + ssize_t len; + size_t i = 0; + char buf[REALTIME_EVENT_BUFFER + 1]; + struct inotify_event *event; + + buf[REALTIME_EVENT_BUFFER] = '\0'; + + len = read(syscheck.realtime->fd, buf, REALTIME_EVENT_BUFFER); + if (len < 0) { + merror("%s: ERROR: Unable to read from real time buffer.", ARGV0); + } else if (len > 0) { + buf[len] = '\0'; + while (i < (size_t) len) { + event = (struct inotify_event *) (void *) &buf[i]; + + if (event->len) { + char wdchar[32 + 1]; + char final_name[MAX_LINE + 1]; + + wdchar[32] = '\0'; + final_name[MAX_LINE] = '\0'; + + snprintf(wdchar, 32, "%d", event->wd); + + snprintf(final_name, MAX_LINE, "%s/%s", + (char *)OSHash_Get(syscheck.realtime->dirtb, wdchar), + event->name); + /* Need a sleep here to avoid triggering on vim edits + * (and finding the file removed) + */ + sleep(1); + + realtime_checksumfile(final_name); + } + + i += REALTIME_EVENT_SIZE + event->len; + } + } + + return (0); +} + +#elif defined(WIN32) +typedef struct _win32rtfim { + HANDLE h; + OVERLAPPED overlap; + + char *dir; + TCHAR buffer[1228800]; +} win32rtfim; + +int realtime_win32read(win32rtfim *rtlocald); + +void CALLBACK RTCallBack(DWORD dwerror, DWORD dwBytes, LPOVERLAPPED overlap) +{ + int lcount; + size_t offset = 0; + char *ptfile; + char wdchar[32 + 1]; + char final_path[MAX_LINE + 1]; + win32rtfim *rtlocald; + PFILE_NOTIFY_INFORMATION pinfo; + TCHAR finalfile[MAX_PATH]; + + if (dwBytes == 0) { + merror("%s: ERROR: real time call back called, but 0 bytes.", ARGV0); + rtlocald = OSHash_Get(syscheck.realtime->dirtb, "0"); + if(rtlocald) + realtime_win32read(rtlocald); + + return; + } + + if (dwerror != ERROR_SUCCESS) { + merror("%s: ERROR: real time call back called, but error is set.", + ARGV0); + return; + } + + /* Get hash to parse the data */ + wdchar[32] = '\0'; + snprintf(wdchar, 32, "%d", (int)overlap->Offset); + rtlocald = OSHash_Get(syscheck.realtime->dirtb, wdchar); + if (rtlocald == NULL) { + merror("%s: ERROR: real time call back called, but hash is empty.", + ARGV0); + return; + } + + do { + pinfo = (PFILE_NOTIFY_INFORMATION) &rtlocald->buffer[offset]; + offset += pinfo->NextEntryOffset; + + lcount = WideCharToMultiByte(CP_ACP, 0, pinfo->FileName, + pinfo->FileNameLength / sizeof(WCHAR), + finalfile, MAX_PATH - 1, NULL, NULL); + finalfile[lcount] = TEXT('\0'); + + /* Change forward slashes to backslashes on finalfile */ + ptfile = strchr(finalfile, '\\'); + while (ptfile) { + *ptfile = '/'; + ptfile++; + + ptfile = strchr(ptfile, '\\'); + } + + final_path[MAX_LINE] = '\0'; + snprintf(final_path, MAX_LINE, "%s/%s", rtlocald->dir, finalfile); + + /* Check the change */ + realtime_checksumfile(final_path); + } while (pinfo->NextEntryOffset != 0); + + realtime_win32read(rtlocald); + + return; +} + +int realtime_start() +{ + verbose("%s: INFO: Initializing real time file monitoring (not started).", ARGV0); + + os_calloc(1, sizeof(rtfim), syscheck.realtime); + syscheck.realtime->dirtb = (void *)OSHash_Create(); + syscheck.realtime->fd = -1; + syscheck.realtime->evt = CreateEvent(NULL, TRUE, FALSE, NULL); + + return (0); +} + +int realtime_win32read(win32rtfim *rtlocald) +{ + int rc; + + rc = ReadDirectoryChangesW(rtlocald->h, + rtlocald->buffer, + sizeof(rtlocald->buffer) / sizeof(TCHAR), + TRUE, + FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SECURITY, + 0, + &rtlocald->overlap, + RTCallBack); + if (rc == 0) { + merror("%s: ERROR: Unable to set directory for monitoring: %s", + ARGV0, rtlocald->dir); + sleep(2); + } + + return (0); +} + +int realtime_adddir(const char *dir) +{ + char wdchar[32 + 1]; + win32rtfim *rtlocald; + + if (!syscheck.realtime) { + realtime_start(); + } + + /* Maximum limit for realtime on Windows */ + if (syscheck.realtime->fd > 256) { + merror("%s: ERROR: Unable to add directory to real time " + "monitoring: '%s' - Maximum size permitted.", ARGV0, dir); + return (0); + } + + os_calloc(1, sizeof(win32rtfim), rtlocald); + + rtlocald->h = CreateFile(dir, + FILE_LIST_DIRECTORY, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + NULL); + + + if (rtlocald->h == INVALID_HANDLE_VALUE || + rtlocald->h == NULL) { + free(rtlocald); + rtlocald = NULL; + merror("%s: ERROR: Unable to add directory to real time " + "monitoring: '%s'.", ARGV0, dir); + return (0); + } + + rtlocald->overlap.Offset = ++syscheck.realtime->fd; + + /* Set key for hash */ + wdchar[32] = '\0'; + snprintf(wdchar, 32, "%d", (int)rtlocald->overlap.Offset); + + if (OSHash_Get(syscheck.realtime->dirtb, wdchar)) { + merror("%s: ERROR: Entry already in the real time hash: %s", + ARGV0, wdchar); + CloseHandle(rtlocald->overlap.hEvent); + free(rtlocald); + rtlocald = NULL; + return (0); + } + + /* Add final elements to the hash */ + os_strdup(dir, rtlocald->dir); + OSHash_Add(syscheck.realtime->dirtb, strdup(wdchar), rtlocald); + + /* Add directory to be monitored */ + realtime_win32read(rtlocald); + + return (1); +} + +#else /* !WIN32 */ + +int realtime_start() +{ + verbose("%s: ERROR: Unable to initialize real time file monitoring.", ARGV0); + + return (0); +} + +int realtime_adddir(__attribute__((unused)) const char *dir) +{ + return (0); +} + +int realtime_process() +{ + return (0); +} + +#endif /* WIN32 */ + diff --git a/src/syscheckd/seechanges.c b/src/syscheckd/seechanges.c new file mode 100644 index 000000000..fcd399e94 --- /dev/null +++ b/src/syscheckd/seechanges.c @@ -0,0 +1,425 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "shared.h" +#include "os_crypto/md5/md5_op.h" +#include "syscheck.h" + +/* Prototypes */ +static char *gen_diff_alert(const char *filename, time_t alert_diff_time) __attribute__((nonnull)); +static int seechanges_dupfile(const char *old, const char *current) __attribute__((nonnull)); +static int seechanges_createpath(const char *filename) __attribute__((nonnull)); + +#ifdef USE_MAGIC +#include + +/* Global variables */ +extern magic_t magic_cookie; + + +int is_text(magic_t cookie, const void *buf, size_t len) +{ + const char *magic = magic_buffer(cookie, buf, len); + + if (!magic) { + const char *err = magic_error(cookie); + merror("%s: ERROR: magic_buffer: %s", ARGV0, err ? err : "unknown"); + return (1); // TODO default to true? + } else { + if (strncmp(magic, "text/", 5) == 0) { + return (1); + } + } + + return (0); +} +#endif + +/* Return TRUE if the file name match one of the ``nodiff`` entries. + Return FALSE otherwise */ +int is_nodiff(const char *filename){ + if (syscheck.nodiff){ + int i; + for (i = 0; syscheck.nodiff[i] != NULL; i++){ + if (strncasecmp(syscheck.nodiff[i], filename, + strlen(syscheck.nodiff[i])) == 0) { + return (TRUE); + } + } + } + if (syscheck.nodiff_regex) { + int i; + for (i = 0; syscheck.nodiff_regex[i] != NULL; i++) { + if (OSMatch_Execute(filename, strlen(filename), + syscheck.nodiff_regex[i])) { + return (TRUE); + } + } + } + return (FALSE); +} + +/* Generate diffs alerts */ +static char *gen_diff_alert(const char *filename, time_t alert_diff_time) +{ + size_t n = 0; + FILE *fp; + char *tmp_str; + char buf[OS_MAXSTR + 1]; + char diff_alert[OS_MAXSTR + 1]; + + buf[OS_MAXSTR] = '\0'; + diff_alert[OS_MAXSTR] = '\0'; + + snprintf(buf, OS_MAXSTR, "%s/local/%s/diff.%d", + DIFF_DIR_PATH, filename, (int)alert_diff_time); + + fp = fopen(buf, "r"); + if (!fp) { + merror("%s: ERROR: Unable to generate diff alert.", ARGV0); + return (NULL); + } + + n = fread(buf, 1, 4096 - 1, fp); + if (n <= 0) { + merror("%s: ERROR: Unable to generate diff alert (fread).", ARGV0); + fclose(fp); + return (NULL); + } else if (n >= 4000) { + /* Clear the last newline */ + buf[n] = '\0'; + tmp_str = strrchr(buf, '\n'); + if (tmp_str) { + *tmp_str = '\0'; + } else { + /* Weird diff with only one large line */ + buf[256] = '\0'; + } + } else { + buf[n] = '\0'; + } + + n = 0; + + /* Get up to 20 line changes */ + tmp_str = buf; + + while (tmp_str && (*tmp_str != '\0')) { + tmp_str = strchr(tmp_str, '\n'); + if (!tmp_str) { + break; + } else if (n >= 19) { + *tmp_str = '\0'; + break; + } + n++; + tmp_str++; + } + + /* Create alert */ + snprintf(diff_alert, 4096 - 1, "%s%s", + buf, n >= 19 ? + "\nMore changes.." : + ""); + + fclose(fp); + return (strdup(diff_alert)); +} + +static int seechanges_dupfile(const char *old, const char *current) +{ + size_t n; + FILE *fpr; + FILE *fpw; + unsigned char buf[2048 + 1]; + + buf[2048] = '\0'; + + fpr = fopen(old, "r"); + if (!fpr) { + return (0); + } + + fpw = fopen(current, "w"); + if (!fpw) { + fclose(fpr); + return (0); + } + + n = fread(buf, 1, 2048, fpr); +#ifdef USE_MAGIC + if (is_text(magic_cookie, buf, n) == 0) { + goto cleanup; + } +#endif + + do { + buf[n] = '\0'; + fwrite(buf, n, 1, fpw); + } while ((n = fread(buf, 1, 2048, fpr)) > 0); + +#ifdef USE_MAGIC +cleanup: +#endif + fclose(fpr); + fclose(fpw); + return (1); +} + +static int seechanges_createpath(const char *filename) +{ + char *buffer = NULL; + char *tmpstr = NULL; + char *newdir = NULL; + + os_strdup(filename, buffer); + newdir = buffer; + tmpstr = strchr(buffer + 1, '/'); + if (!tmpstr) { + merror("%s: ERROR: Invalid path name: '%s'", ARGV0, filename); + free(buffer); + return (0); + } + *tmpstr = '\0'; + tmpstr++; + + while (1) { + if (IsDir(newdir) != 0) { +#ifndef WIN32 + if (mkdir(newdir, 0770) == -1) +#else + if (mkdir(newdir) == -1) +#endif + { + merror(MKDIR_ERROR, ARGV0, newdir, errno, strerror(errno)); + free(buffer); + return (0); + } + } + + if (*tmpstr == '\0') { + break; + } + + tmpstr[-1] = '/'; + tmpstr = strchr(tmpstr, '/'); + if (!tmpstr) { + break; + } + *tmpstr = '\0'; + tmpstr++; + } + + free(buffer); + return (1); +} + +/* Check if the file has changed */ +char *seechanges_addfile(const char *filename) +{ + time_t old_date_of_change; + time_t new_date_of_change; + char old_location[OS_MAXSTR + 1]; + char tmp_location[OS_MAXSTR + 1]; + char diff_location[OS_MAXSTR + 1]; + char old_tmp[OS_MAXSTR + 1]; + char new_tmp[OS_MAXSTR + 1]; + char diff_tmp[OS_MAXSTR + 1]; + char diff_cmd[OS_MAXSTR + 1]; + os_md5 md5sum_old; + os_md5 md5sum_new; + int status = -1; + + old_location[OS_MAXSTR] = '\0'; + tmp_location[OS_MAXSTR] = '\0'; + diff_location[OS_MAXSTR] = '\0'; + old_tmp[OS_MAXSTR] = '\0'; + new_tmp[OS_MAXSTR] = '\0'; + diff_tmp[OS_MAXSTR] = '\0'; + diff_cmd[OS_MAXSTR] = '\0'; + md5sum_new[0] = '\0'; + md5sum_old[0] = '\0'; + + snprintf( + old_location, + OS_MAXSTR, + "%s/local/%s/%s", + DIFF_DIR_PATH, + filename + 1, + DIFF_LAST_FILE + ); + + /* If the file is not there, rename new location to last location */ + if (OS_MD5_File(old_location, md5sum_old, OS_BINARY) != 0) { + seechanges_createpath(old_location); + if (seechanges_dupfile(filename, old_location) != 1) { + merror(RENAME_ERROR, ARGV0, filename, old_location, errno, strerror(errno)); + } + return (NULL); + } + + /* Get md5sum of the new file */ + if (OS_MD5_File(filename, md5sum_new, OS_BINARY) != 0) { + return (NULL); + } + + /* If they match, keep the old file and remove the new */ + if (strcmp(md5sum_new, md5sum_old) == 0) { + return (NULL); + } + + /* Save the old file at timestamp and rename new to last */ + old_date_of_change = File_DateofChange(old_location); + + snprintf( + tmp_location, + OS_MAXSTR, + "%s/local/%s/state.%d", + DIFF_DIR_PATH, + filename + 1, + (int)old_date_of_change + ); + + /* Saving the old file at timestamp and renaming new to last. */ + old_date_of_change = File_DateofChange(old_location); + + snprintf( + tmp_location, + sizeof(tmp_location), + "%s/local/%s/state.%d", + DIFF_DIR_PATH, + filename + 1, + (int)old_date_of_change + ); + + + if((rename(old_location, tmp_location)) < 0) { + merror("%s: ERROR rename of %s failed: %s", ARGV0, old_location, strerror(errno)); + } + if(seechanges_dupfile(filename, old_location) != 1) + { + merror("%s: ERROR: Unable to create snapshot for %s",ARGV0, filename); + return(NULL); + } + + if (seechanges_dupfile(filename, old_location) != 1) { + merror("%s: ERROR: Unable to create snapshot for %s", ARGV0, filename); + return (NULL); + } + + new_date_of_change = File_DateofChange(old_location); + + /* Create file names */ + snprintf( + old_tmp, + OS_MAXSTR, + "%s/%s/syscheck-changes-%s-%d", + DEFAULTDIR, + TMP_DIR, + md5sum_old, + (int)old_date_of_change + ); + + snprintf( + new_tmp, + OS_MAXSTR, + "%s/%s/syscheck-changes-%s-%d", + DEFAULTDIR, + TMP_DIR, + md5sum_new, + (int)new_date_of_change + ); + + snprintf( + diff_tmp, + OS_MAXSTR, + "%s/%s/syscheck-changes-%s-%d-%s-%d", + DEFAULTDIR, + TMP_DIR, + md5sum_old, + (int)old_date_of_change, + md5sum_new, + (int)new_date_of_change + ); + /* Create diff location */ + snprintf( + diff_location, + OS_MAXSTR, + "%s/local/%s/diff.%d", + DIFF_DIR_PATH, + filename + 1, + (int)new_date_of_change + ); + + /* Create symlinks */ + if (symlink(old_location, old_tmp) == -1) { + merror(LINK_ERROR, ARGV0, old_location, old_tmp, errno, strerror(errno)); + goto cleanup; + } + + if (symlink(tmp_location, new_tmp) == -1) { + merror(LINK_ERROR, ARGV0, tmp_location, new_tmp, errno, strerror(errno)); + goto cleanup; + } + + if (symlink(diff_location, diff_tmp) == -1) { + merror(LINK_ERROR, ARGV0, diff_location, diff_tmp, errno, strerror(errno)); + goto cleanup; + } + + if (is_nodiff((filename))) { + /* Dont leak sensible data with a diff hanging around */ + FILE *fdiff; + char* nodiff_message = ""; + fdiff = fopen(diff_location, "w"); + if (!fdiff){ + merror("%s: ERROR: Unable to open file for writing `%s`", ARGV0, diff_location); + goto cleanup; + } + fwrite(nodiff_message, strlen(nodiff_message) + 1, 1, fdiff); + fclose(fdiff); + /* Success */ + status = 0; + } else { + /* OK, run diff */ + snprintf( + diff_cmd, + 2048, + "diff \"%s\" \"%s\" > \"%s\" 2> /dev/null", + new_tmp, + old_tmp, + diff_tmp + ); + + if (system(diff_cmd) != 256) { + merror("%s: ERROR: Unable to run `%s`", ARGV0, diff_cmd); + goto cleanup; + } + + /* Success */ + status = 0; + }; + +cleanup: + if ((unlink(old_tmp)) < 0) { + merror("%s: ERROR: Unable to unlink %s (old_tmp): %s", ARGV0, old_tmp, strerror(errno)); + } + if ((unlink(new_tmp)) < 0) { + merror("%s: ERROR: Unable to unlink %s (new_tmp): %s", ARGV0, new_tmp, strerror(errno)); + } + if ((unlink(diff_tmp)) < 0) { + merror("%s: ERROR: Unable to unlink %s (diff_tmp): %s", ARGV0, diff_tmp, strerror(errno)); + } + + if (status == -1) + return (NULL); + + /* Generate alert */ + return (gen_diff_alert(filename, new_date_of_change)); +} diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c new file mode 100644 index 000000000..5a1dec3a5 --- /dev/null +++ b/src/syscheckd/syscheck.c @@ -0,0 +1,365 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +/* Syscheck + * Copyright (C) 2003 Daniel B. Cid + */ + +#include "shared.h" +#include "syscheck.h" +#include "rootcheck/rootcheck.h" + +/* Prototypes */ +static void read_internal(int debug_level); +#ifndef WIN32 +static void help_syscheckd(void) __attribute__((noreturn)); +#endif + +syscheck_config syscheck; + +#ifdef USE_MAGIC +#include +magic_t magic_cookie = 0; + + +void init_magic(magic_t *cookie_ptr) +{ + if (!cookie_ptr || *cookie_ptr) { + return; + } + + *cookie_ptr = magic_open(MAGIC_MIME_TYPE); + + if (!*cookie_ptr) { + const char *err = magic_error(*cookie_ptr); + merror("%s: ERROR: Can't init libmagic: %s", ARGV0, err ? err : "unknown"); + } else if (magic_load(*cookie_ptr, NULL) < 0) { + const char *err = magic_error(*cookie_ptr); + merror("%s: ERROR: Can't load magic file: %s", ARGV0, err ? err : "unknown"); + magic_close(*cookie_ptr); + *cookie_ptr = 0; + } +} +#endif /* USE_MAGIC */ + +/* Read syscheck internal options */ +static void read_internal(int debug_level) +{ + syscheck.tsleep = (unsigned int) getDefine_Int("syscheck", "sleep", 0, 64); + syscheck.sleep_after = getDefine_Int("syscheck", "sleep_after", 1, 9999); + + /* Check current debug_level + * Command line setting takes precedence + */ + if (debug_level == 0) { + debug_level = getDefine_Int("syscheck", "debug", 0, 2); + while (debug_level != 0) { + nowDebug(); + debug_level--; + } + } + + return; +} + +#ifdef WIN32 +/* syscheck main for Windows */ +int Start_win32_Syscheck() +{ + int debug_level = 0; + int r = 0; + char *cfg = DEFAULTCPATH; + + /* Read internal options */ + read_internal(debug_level); + + debug1(STARTED_MSG, ARGV0); + + /* Check if the configuration is present */ + if (File_DateofChange(cfg) < 0) { + ErrorExit(NO_CONFIG, ARGV0, cfg); + } + + /* Read syscheck config */ + if ((r = Read_Syscheck_Config(cfg)) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } else if ((r == 1) || (syscheck.disabled == 1)) { + /* Disabled */ + if (!syscheck.dir) { + merror(SK_NO_DIR, ARGV0); + dump_syscheck_entry(&syscheck, "", 0, 0, NULL); + } else if (!syscheck.dir[0]) { + merror(SK_NO_DIR, ARGV0); + } + syscheck.dir[0] = NULL; + + if (!syscheck.registry) { + dump_syscheck_entry(&syscheck, "", 0, 1, NULL); + } + syscheck.registry[0] = NULL; + + merror("%s: WARN: Syscheck disabled.", ARGV0); + } + + /* Rootcheck config */ + if (rootcheck_init(0) == 0) { + syscheck.rootcheck = 1; + } else { + syscheck.rootcheck = 0; + merror("%s: WARN: Rootcheck module disabled.", ARGV0); + } + + /* Print options */ + r = 0; + while (syscheck.registry[r] != NULL) { + verbose("%s: INFO: Monitoring registry entry: '%s'.", + ARGV0, syscheck.registry[r]); + r++; + } + + /* Print directories to be monitored */ + r = 0; + while (syscheck.dir[r] != NULL) { + char optstr[ 100 ]; + verbose("%s: INFO: Monitoring directory: '%s', with options %s.", + ARGV0, syscheck.dir[r], + syscheck_opts2str(optstr, sizeof( optstr ), syscheck.opts[r])); + r++; + } + + /* Print ignores. */ + if(syscheck.ignore) + for (r = 0; syscheck.ignore[r] != NULL; r++) + verbose("%s: INFO: ignoring: '%s'", + ARGV0, syscheck.ignore[r]); + + + /* Print files with no diff. */ + if (syscheck.nodiff){ + r = 0; + while (syscheck.nodiff[r] != NULL) { + verbose("%s: INFO: No diff for file: '%s'", + ARGV0, syscheck.nodiff[r]); + r++; + } + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, getpid()); + + /* Some sync time */ + sleep(syscheck.tsleep + 10); + + /* Wait if agent started properly */ + os_wait(); + + start_daemon(); + + exit(0); +} +#endif /* WIN32 */ + +#ifndef WIN32 +/* Print help statement */ +static void help_syscheckd() +{ + print_header(); + print_out(" %s: -[Vhdtf] [-c config]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" "); + exit(1); +} + +/* Syscheck unix main */ +int main(int argc, char **argv) +{ + int c, r; + int debug_level = 0; + int test_config = 0, run_foreground = 0; + const char *cfg = DEFAULTCPATH; + + /* Set the name */ + OS_SetName(ARGV0); + + while ((c = getopt(argc, argv, "Vtdhfc:")) != -1) { + switch (c) { + case 'V': + print_version(); + break; + case 'h': + help_syscheckd(); + break; + case 'd': + nowDebug(); + debug_level ++; + break; + case 'f': + run_foreground = 1; + break; + case 'c': + if (!optarg) { + ErrorExit("%s: -c needs an argument", ARGV0); + } + cfg = optarg; + break; + case 't': + test_config = 1; + break; + default: + help_syscheckd(); + break; + } + } + + /* Read internal options */ + read_internal(debug_level); + + debug1(STARTED_MSG, ARGV0); + + /* Check if the configuration is present */ + if (File_DateofChange(cfg) < 0) { + ErrorExit(NO_CONFIG, ARGV0, cfg); + } + + /* Read syscheck config */ + if ((r = Read_Syscheck_Config(cfg)) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } else if ((r == 1) || (syscheck.disabled == 1)) { + if (!syscheck.dir) { + if (!test_config) { + merror(SK_NO_DIR, ARGV0); + } + dump_syscheck_entry(&syscheck, "", 0, 0, NULL); + } else if (!syscheck.dir[0]) { + if (!test_config) { + merror(SK_NO_DIR, ARGV0); + } + } + syscheck.dir[0] = NULL; + if (!test_config) { + merror("%s: WARN: Syscheck disabled.", ARGV0); + } + } + + /* Rootcheck config */ + if (rootcheck_init(test_config) == 0) { + syscheck.rootcheck = 1; + } else { + syscheck.rootcheck = 0; + merror("%s: WARN: Rootcheck module disabled.", ARGV0); + } + + /* Exit if testing config */ + if (test_config) { + exit(0); + } + + /* Setup libmagic */ +#ifdef USE_MAGIC + init_magic(&magic_cookie); +#endif + + if (!run_foreground) { + nowDaemon(); + goDaemon(); + } + + /* Initial time to settle */ + sleep(syscheck.tsleep + 2); + + /* Connect to the queue */ + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno)); + + sleep(5); + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + /* more 10 seconds of wait */ + merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno)); + sleep(10); + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + } + } + + /* Start signal handling */ + StartSIG(ARGV0); + + /* Create pid */ + if (CreatePID(ARGV0, getpid()) < 0) { + merror(PID_ERROR, ARGV0); + } + + /* Start up message */ + verbose(STARTUP_MSG, ARGV0, (int)getpid()); + + if (syscheck.rootcheck) { + verbose(STARTUP_MSG, "openarmor-rootcheck", (int)getpid()); + } + + /* Print directories to be monitored */ + r = 0; + while (syscheck.dir[r] != NULL) { + char optstr[ 100 ]; + verbose("%s: INFO: Monitoring directory: '%s', with options %s.", + ARGV0, syscheck.dir[r], + syscheck_opts2str(optstr, sizeof( optstr ), syscheck.opts[r])); + r++; + } + + /* Print ignores. */ + if(syscheck.ignore) + for (r = 0; syscheck.ignore[r] != NULL; r++) + verbose("%s: INFO: ignoring: '%s'", + ARGV0, syscheck.ignore[r]); + + /* Print files with no diff. */ + if (syscheck.nodiff){ + r = 0; + while (syscheck.nodiff[r] != NULL) { + verbose("%s: INFO: No diff for file: '%s'", + ARGV0, syscheck.nodiff[r]); + r++; + } + } + + /* Check directories set for real time */ + r = 0; + while (syscheck.dir[r] != NULL) { + if (syscheck.opts[r] & CHECK_REALTIME) { +#ifdef INOTIFY_ENABLED + verbose("%s: INFO: Directory set for real time monitoring: " + "'%s'.", ARGV0, syscheck.dir[r]); +#elif defined(WIN32) + verbose("%s: INFO: Directory set for real time monitoring: " + "'%s'.", ARGV0, syscheck.dir[r]); +#else + verbose("%s: WARN: Ignoring flag for real time monitoring on " + "directory: '%s'.", ARGV0, syscheck.dir[r]); +#endif + } + r++; + } + + /* Some sync time */ + sleep(syscheck.tsleep + 10); + + /* Start the daemon */ + start_daemon(); +} + +#endif /* !WIN32 */ + diff --git a/src/syscheckd/syscheck.h b/src/syscheckd/syscheck.h new file mode 100644 index 000000000..78cc1c356 --- /dev/null +++ b/src/syscheckd/syscheck.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef __SYSCHECK_H +#define __SYSCHECK_H + +#include "config/syscheck-config.h" +#define MAX_LINE PATH_MAX+256 + +/* Notify list size */ +#define NOTIFY_LIST_SIZE 32 + +/* Global config */ +extern syscheck_config syscheck; + +/** Function Prototypes **/ + +/* Check the integrity of the files against the saved database */ +void run_check(void); + +/* Run run_check periodically */ +void start_daemon(void) __attribute__((noreturn)); + +/* Read the XML config */ +int Read_Syscheck_Config(const char *cfgfile) __attribute__((nonnull)); + +/* Create the database */ +int create_db(void); + +/* Check database for changes */ +int run_dbcheck(void); + +/* Scan directory */ +int read_dir(const char *dir_name, int opts, OSMatch *restriction); + + +/* Check the registry for changes */ +void os_winreg_check(void); + +/* Start real time */ +int realtime_start(void); + +/* Add a directory to real time monitoring */ +int realtime_adddir(const char *dir) __attribute__((nonnull)); + +/* Process real time queue */ +int realtime_process(void); + +/* Process the content of the file changes */ +char *seechanges_addfile(const char *filename) __attribute__((nonnull)); + +/* Get checksum changes */ +int c_read_file(const char *file_name, const char *oldsum, char *newsum) __attribute__((nonnull)); + +int send_syscheck_msg(const char *msg) __attribute__((nonnull)); +int send_rootcheck_msg(const char *msg) __attribute__((nonnull)); + +#endif + diff --git a/src/syscheckd/win-registry.c b/src/syscheckd/win-registry.c new file mode 100644 index 000000000..3aac6eb52 --- /dev/null +++ b/src/syscheckd/win-registry.c @@ -0,0 +1,412 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef WIN32 + +#include "shared.h" +#include "syscheck.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/sha1/sha1_op.h" +#include "os_crypto/md5_sha1/md5_sha1_op.h" + +/* Default values */ +#define MAX_KEY_LENGTH 255 +#define MAX_KEY 2048 +#define MAX_VALUE_NAME 16383 + +/* Places to story the registry values */ +#define SYS_WIN_REG "syscheck/syscheckregistry.db" +#define SYS_REG_TMP "syscheck/syscheck_sum.tmp" + +/* Global variables */ +HKEY sub_tree; +int ig_count = 0; +int run_count = 0; + +/* Prototypes */ +void os_winreg_open_key(char *subkey, char *fullkey_name); + + +int os_winreg_changed(char *key, char *md5, char *sha1) +{ + char buf[MAX_LINE + 1]; + + buf[MAX_LINE] = '\0'; + + /* Seek to the beginning of the db */ + fseek(syscheck.reg_fp, 0, SEEK_SET); + + while (fgets(buf, MAX_LINE, syscheck.reg_fp) != NULL) { + if ((buf[0] != '#') && (buf[0] != ' ') && (buf[0] != '\n')) { + char *n_buf; + + /* Remove the \n before reading */ + n_buf = strchr(buf, '\n'); + if (n_buf == NULL) { + continue; + } + + *n_buf = '\0'; + + n_buf = strchr(buf, ' '); + if (n_buf == NULL) { + continue; + } + + if (strcmp(n_buf + 1, key) != 0) { + continue; + } + + /* Entry found, check if checksum is the same */ + *n_buf = '\0'; + if ((strncmp(buf, md5, sizeof(os_md5) - 1) == 0) && + (strcmp(buf + sizeof(os_md5) - 1, sha1) == 0)) { + /* File didn't change */ + return (0); + } + + /* File did change */ + return (1); + } + } + + fseek(syscheck.reg_fp, 0, SEEK_END); + fprintf(syscheck.reg_fp, "%s%s %s\n", md5, sha1, key); + return (1); +} + +/* Notify of registry changes */ +int notify_registry(char *msg, __attribute__((unused)) int send_now) +{ + if (SendMSG(syscheck.queue, msg, + SYSCHECK_REG, SYSCHECK_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + + /* If we reach here, we can try to send it again */ + SendMSG(syscheck.queue, msg, SYSCHECK_REG, SYSCHECK_MQ); + } + + return (0); +} + +/* Check if the registry entry is valid */ +char *os_winreg_sethkey(char *reg_entry) +{ + char *ret = NULL; + char *tmp_str; + + /* Get only the sub tree first */ + tmp_str = strchr(reg_entry, '\\'); + if (tmp_str) { + *tmp_str = '\0'; + ret = tmp_str + 1; + } + + /* Set sub tree */ + if (strcmp(reg_entry, "HKEY_LOCAL_MACHINE") == 0) { + sub_tree = HKEY_LOCAL_MACHINE; + } else if (strcmp(reg_entry, "HKEY_CLASSES_ROOT") == 0) { + sub_tree = HKEY_CLASSES_ROOT; + } else if (strcmp(reg_entry, "HKEY_CURRENT_CONFIG") == 0) { + sub_tree = HKEY_CURRENT_CONFIG; + } else if (strcmp(reg_entry, "HKEY_USERS") == 0) { + sub_tree = HKEY_USERS; + } else { + /* Return tmp_str to the previous value */ + if (tmp_str && (*tmp_str == '\0')) { + *tmp_str = '\\'; + } + return (NULL); + } + + /* Check if ret has nothing else */ + if (ret && (*ret == '\0')) { + ret = NULL; + } + + /* Fix tmp_str and the real name of the registry */ + if (tmp_str && (*tmp_str == '\0')) { + *tmp_str = '\\'; + } + + return (ret); +} + +/* Query the key and get all its values */ +void os_winreg_querykey(HKEY hKey, char *p_key, char *full_key_name) +{ + int rc; + DWORD i, j; + + /* QueryInfo and EnumKey variables */ + TCHAR sub_key_name_b[MAX_KEY_LENGTH + 2]; + TCHAR class_name_b[MAX_PATH + 1]; + DWORD sub_key_name_s; + DWORD class_name_s = MAX_PATH; + + /* Number of sub keys */ + DWORD subkey_count = 0; + + /* Number of values */ + DWORD value_count; + + /* Variables for RegEnumValue */ + TCHAR value_buffer[MAX_VALUE_NAME + 1]; + TCHAR data_buffer[MAX_VALUE_NAME + 1]; + DWORD value_size; + DWORD data_size; + + /* Data type for RegEnumValue */ + DWORD data_type = 0; + + /* Initializing the memory for some variables */ + class_name_b[0] = '\0'; + class_name_b[MAX_PATH] = '\0'; + sub_key_name_b[0] = '\0'; + sub_key_name_b[MAX_KEY_LENGTH] = '\0'; + sub_key_name_b[MAX_KEY_LENGTH + 1] = '\0'; + + /* We use the class_name, subkey_count and the value count */ + rc = RegQueryInfoKey(hKey, class_name_b, &class_name_s, NULL, + &subkey_count, NULL, NULL, &value_count, + NULL, NULL, NULL, NULL); + + /* Check return code of QueryInfo */ + if (rc != ERROR_SUCCESS) { + return; + } + + /* Check if we have sub keys */ + if (subkey_count) { + /* Open each subkey and call open_key */ + for (i = 0; i < subkey_count; i++) { + sub_key_name_s = MAX_KEY_LENGTH; + rc = RegEnumKeyEx(hKey, i, sub_key_name_b, &sub_key_name_s, + NULL, NULL, NULL, NULL); + + /* Checking for the rc */ + if (rc == ERROR_SUCCESS) { + char new_key[MAX_KEY + 2]; + char new_key_full[MAX_KEY + 2]; + new_key[MAX_KEY + 1] = '\0'; + new_key_full[MAX_KEY + 1] = '\0'; + + if (p_key) { + snprintf(new_key, MAX_KEY, + "%s\\%s", p_key, sub_key_name_b); + snprintf(new_key_full, MAX_KEY, + "%s\\%s", full_key_name, sub_key_name_b); + } else { + snprintf(new_key, MAX_KEY, "%s", sub_key_name_b); + snprintf(new_key_full, MAX_KEY, + "%s\\%s", full_key_name, sub_key_name_b); + } + + /* Open subkey */ + os_winreg_open_key(new_key, new_key_full); + } + } + } + + /* Get values (if available) */ + if (value_count) { + /* md5 and sha1 sum */ + os_md5 mf_sum; + os_sha1 sf_sum; + FILE *checksum_fp; + char *mt_data; + + /* Clear the values for value_size and data_size */ + value_buffer[MAX_VALUE_NAME] = '\0'; + data_buffer[MAX_VALUE_NAME] = '\0'; + checksum_fp = fopen(SYS_REG_TMP, "w"); + if (!checksum_fp) { + printf(FOPEN_ERROR, ARGV0, SYS_REG_TMP, errno, strerror(errno)); + return; + } + + /* Get each value */ + for (i = 0; i < value_count; i++) { + value_size = MAX_VALUE_NAME; + data_size = MAX_VALUE_NAME; + + value_buffer[0] = '\0'; + data_buffer[0] = '\0'; + + rc = RegEnumValue(hKey, i, value_buffer, &value_size, + NULL, &data_type, (LPBYTE)data_buffer, &data_size); + + /* No more values available */ + if (rc != ERROR_SUCCESS) { + break; + } + + /* Check if no value name is specified */ + if (value_buffer[0] == '\0') { + value_buffer[0] = '@'; + value_buffer[1] = '\0'; + } + + /* Write value name and data in the file (for checksum later) */ + fprintf(checksum_fp, "%s=", value_buffer); + switch (data_type) { + case REG_SZ: + case REG_EXPAND_SZ: + fprintf(checksum_fp, "%s\n", data_buffer); + break; + case REG_MULTI_SZ: + /* Print multiple strings */ + mt_data = data_buffer; + + while (*mt_data) { + fprintf(checksum_fp, "%s ", mt_data); + mt_data += strlen(mt_data) + 1; + } + fprintf(checksum_fp, "\n"); + break; + case REG_DWORD: + fprintf(checksum_fp, "%08x\n", (unsigned int)*data_buffer); + break; + default: + for (j = 0; j < data_size; j++) { + fprintf(checksum_fp, "%02x", + (unsigned int)data_buffer[j]); + } + fprintf(checksum_fp, "\n"); + break; + } + } + + /* Generate checksum of the values */ + fclose(checksum_fp); + + if (OS_MD5_SHA1_File(SYS_REG_TMP, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_TEXT) == -1) { + merror(FOPEN_ERROR, ARGV0, SYS_REG_TMP, errno, strerror(errno)); + return; + } + + /* Look for p_key on the reg db */ + if (os_winreg_changed(full_key_name, mf_sum, sf_sum)) { + char reg_changed[MAX_LINE + 1]; + snprintf(reg_changed, MAX_LINE, "0:0:0:0:%s:%s %s", + mf_sum, sf_sum, full_key_name); + + /* Notify server */ + notify_registry(reg_changed, 0); + } + + ig_count++; + } +} + +/* Open the registry key */ +void os_winreg_open_key(char *subkey, char *full_key_name) +{ + int i = 0; + HKEY oshkey; + + /* Sleep X every Y files */ + if (ig_count >= syscheck.sleep_after) { + sleep(syscheck.tsleep + 1); + ig_count = 1; + } + ig_count++; + + /* Registry ignore list */ + if (full_key_name && syscheck.registry_ignore) { + while (syscheck.registry_ignore[i] != NULL) { + if (strcasecmp(syscheck.registry_ignore[i], full_key_name) == 0) { + return; + } + i++; + } + } else if (full_key_name && syscheck.registry_ignore_regex) { + i = 0; + while (syscheck.registry_ignore_regex[i] != NULL) { + if (OSMatch_Execute(full_key_name, strlen(full_key_name), + syscheck.registry_ignore_regex[i])) { + return; + } + i++; + } + } + + if (RegOpenKeyEx(sub_tree, subkey, 0, KEY_READ, &oshkey) != ERROR_SUCCESS) { + merror(SK_REG_OPEN, ARGV0, subkey); + return; + } + + os_winreg_querykey(oshkey, subkey, full_key_name); + RegCloseKey(oshkey); + return; +} + +/* Main function to read the registry */ +void os_winreg_check() +{ + int i = 0; + char *rk; + + /* Debug entries */ + debug1("%s: DEBUG: Starting os_winreg_check", ARGV0); + + /* Zero ig_count before checking */ + ig_count = 1; + + /* Check if the registry fp is open */ + if (syscheck.reg_fp == NULL) { + syscheck.reg_fp = fopen(SYS_WIN_REG, "w+"); + if (!syscheck.reg_fp) { + merror(FOPEN_ERROR, ARGV0, SYS_WIN_REG, errno, strerror(errno)); + return; + } + } + + /* Get sub class and a valid registry entry */ + while (syscheck.registry[i] != NULL) { + sub_tree = NULL; + rk = NULL; + + /* Ignored entries are zeroed */ + if (*syscheck.registry[i] == '\0') { + i++; + continue; + } + + /* Read syscheck registry entry */ + debug1("%s: DEBUG: Attempt to read: %s", ARGV0, syscheck.registry[i]); + + rk = os_winreg_sethkey(syscheck.registry[i]); + if (sub_tree == NULL) { + merror(SK_INV_REG, ARGV0, syscheck.registry[i]); + *syscheck.registry[i] = '\0'; + i++; + continue; + } + + os_winreg_open_key(rk, syscheck.registry[i]); + i++; + sleep(syscheck.tsleep * 5); + } + + /* Notify of db completed */ + if (run_count > 1) { + sleep(syscheck.tsleep * 5); + notify_registry(HC_SK_DB_COMPLETED, 1); + } + + run_count++; + return; +} +#endif /* WIN32 */ + diff --git a/src/systemd/agent/openarmor-agent.target b/src/systemd/agent/openarmor-agent.target new file mode 100644 index 000000000..b8d39c023 --- /dev/null +++ b/src/systemd/agent/openarmor-agent.target @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor HIDS agent +After=network.target +Requires=openarmor-execd.service +Requires=openarmor-syscheckd.service +Requires=openarmor-agentd.service +Requires=openarmor-logcollector.service + +[Install] +WantedBy=multi-user.target diff --git a/src/systemd/agent/openarmor-agentd.service b/src/systemd/agent/openarmor-agentd.service new file mode 100644 index 000000000..553b8b4f3 --- /dev/null +++ b/src/systemd/agent/openarmor-agentd.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Agent +PartOf=openarmor-agent.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-agentd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-agentd -f diff --git a/src/systemd/agent/openarmor-execd.service b/src/systemd/agent/openarmor-execd.service new file mode 100644 index 000000000..6a97762eb --- /dev/null +++ b/src/systemd/agent/openarmor-execd.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Execd +PartOf=openarmor-agent.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-execd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-execd -f diff --git a/src/systemd/agent/openarmor-logcollector.service b/src/systemd/agent/openarmor-logcollector.service new file mode 100644 index 000000000..8ff04d30f --- /dev/null +++ b/src/systemd/agent/openarmor-logcollector.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Logcollector +PartOf=openarmor-agent.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-logcollector -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-logcollector -f diff --git a/src/systemd/agent/openarmor-syscheckd.service b/src/systemd/agent/openarmor-syscheckd.service new file mode 100644 index 000000000..529200617 --- /dev/null +++ b/src/systemd/agent/openarmor-syscheckd.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor syscheckd +PartOf=openarmor-agent.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-syscheckd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-syscheckd -f diff --git a/src/systemd/server/openarmor-agentless.service b/src/systemd/server/openarmor-agentless.service new file mode 100644 index 000000000..1a4e477a8 --- /dev/null +++ b/src/systemd/server/openarmor-agentless.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Agentless +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-agentlessd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-agentlessd -f \ No newline at end of file diff --git a/src/systemd/server/openarmor-analysisd.service b/src/systemd/server/openarmor-analysisd.service new file mode 100644 index 000000000..43612f3ed --- /dev/null +++ b/src/systemd/server/openarmor-analysisd.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Analysisd +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-analysisd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-analysisd -f diff --git a/src/systemd/server/openarmor-csyslog.service b/src/systemd/server/openarmor-csyslog.service new file mode 100644 index 000000000..95f969896 --- /dev/null +++ b/src/systemd/server/openarmor-csyslog.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Syslog client +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-csyslogd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-csyslogd -f \ No newline at end of file diff --git a/src/systemd/server/openarmor-dbd.service b/src/systemd/server/openarmor-dbd.service new file mode 100644 index 000000000..2eff46795 --- /dev/null +++ b/src/systemd/server/openarmor-dbd.service @@ -0,0 +1,10 @@ +[Unit] +Description=The openarmor DBD +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-dbd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-dbd -f diff --git a/src/systemd/server/openarmor-execd.service b/src/systemd/server/openarmor-execd.service new file mode 100644 index 000000000..714103ae9 --- /dev/null +++ b/src/systemd/server/openarmor-execd.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Execd +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-execd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-execd -f diff --git a/src/systemd/server/openarmor-logcollector.service b/src/systemd/server/openarmor-logcollector.service new file mode 100644 index 000000000..fe4652b34 --- /dev/null +++ b/src/systemd/server/openarmor-logcollector.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Logcollector +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-logcollector -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-logcollector -f diff --git a/src/systemd/server/openarmor-maild.service b/src/systemd/server/openarmor-maild.service new file mode 100644 index 000000000..209824268 --- /dev/null +++ b/src/systemd/server/openarmor-maild.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor Maild +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-maild -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-maild -f diff --git a/src/systemd/server/openarmor-monitord.service b/src/systemd/server/openarmor-monitord.service new file mode 100644 index 000000000..12647844e --- /dev/null +++ b/src/systemd/server/openarmor-monitord.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor monitord +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-monitord -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-monitord -f diff --git a/src/systemd/server/openarmor-remoted.service b/src/systemd/server/openarmor-remoted.service new file mode 100644 index 000000000..95e335840 --- /dev/null +++ b/src/systemd/server/openarmor-remoted.service @@ -0,0 +1,11 @@ +[Unit] +Description=openarmor remoted +PartOf=openarmor-server.target + +[Service] +Type=forking +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-remoted -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-remoted -f diff --git a/src/systemd/server/openarmor-server.target b/src/systemd/server/openarmor-server.target new file mode 100644 index 000000000..49f72533c --- /dev/null +++ b/src/systemd/server/openarmor-server.target @@ -0,0 +1,16 @@ +[Unit] +Description=openarmor HIDS server +After=network.target +Wants=openarmor-dbd.service +Wants=openarmor-csyslog.service +Wants=openarmor-agentless.service +Requires=openarmor-maild.service +Requires=openarmor-execd.service +Requires=openarmor-analysisd.service +Requires=openarmor-logcollector.service +Requires=openarmor-remoted.service +Requires=openarmor-syscheckd.service +Requires=openarmor-monitord.service + +[Install] +WantedBy=multi-user.target diff --git a/src/systemd/server/openarmor-syscheckd.service b/src/systemd/server/openarmor-syscheckd.service new file mode 100644 index 000000000..20f62b424 --- /dev/null +++ b/src/systemd/server/openarmor-syscheckd.service @@ -0,0 +1,10 @@ +[Unit] +Description=openarmor syscheckd +PartOf=openarmor-server.target + +[Service] +EnvironmentFile=/etc/openarmor-init.conf +Environment=DIRECTORY=/var/openarmor + +ExecStartPre=/usr/bin/env ${DIRECTORY}/bin/openarmor-syscheckd -t +ExecStart=/usr/bin/env ${DIRECTORY}/bin/openarmor-syscheckd -f diff --git a/src/tests/test_os_crypto.c b/src/tests/test_os_crypto.c new file mode 100644 index 000000000..84d66b8b3 --- /dev/null +++ b/src/tests/test_os_crypto.c @@ -0,0 +1,200 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "headers/defs.h" +#include "../os_crypto/blowfish/bf_op.h" +#include "../os_crypto/md5/md5_op.h" +#include "../os_crypto/sha1/sha1_op.h" +#include "../os_crypto/md5_sha1/md5_sha1_op.h" + +Suite *test_suite(void); + + +START_TEST(test_blowfish) +{ + const char *key = "test_key"; + const char *string = "test string"; + const int buffersize = 1024; + char buffer1[buffersize]; + char buffer2[buffersize]; + + OS_BF_Str(string, buffer1, key, buffersize, OS_ENCRYPT); + OS_BF_Str(buffer1, buffer2, key, buffersize, OS_DECRYPT); + + ck_assert_str_eq(buffer2, string); +} +END_TEST + +START_TEST(test_md5string) +{ + const char *string = "teststring"; + const char *string_md5 = "d67c5cbf5b01c9f91932e3b8def5e5f8"; + os_md5 buffer; + + OS_MD5_Str(string, buffer); + + ck_assert_str_eq(buffer, string_md5); +} +END_TEST + +START_TEST(test_md5file) +{ + const char *string = "teststring"; + const char *string_md5 = "d67c5cbf5b01c9f91932e3b8def5e5f8"; + + /* create tmp file */ + char file_name[256]; + strncpy(file_name, "/tmp/tmp_file-XXXXXX", 256); + int fd = mkstemp(file_name); + + write(fd, string, strlen(string)); + close(fd); + + os_md5 buffer; + ck_assert_int_eq(OS_MD5_File(file_name, buffer, OS_TEXT), 0); + + ck_assert_str_eq(buffer, string_md5); +} +END_TEST + +START_TEST(test_md5file_fail) +{ + os_md5 buffer; + ck_assert_int_eq(OS_MD5_File("not_existing_file", buffer, OS_TEXT), -1); +} +END_TEST + +START_TEST(test_sha1file) +{ + const char *string = "teststring"; + const char *string_sha1 = "b8473b86d4c2072ca9b08bd28e373e8253e865c4"; + + /* create tmp file */ + char file_name[256]; + strncpy(file_name, "/tmp/tmp_file-XXXXXX", 256); + int fd = mkstemp(file_name); + + write(fd, string, strlen(string)); + close(fd); + + os_sha1 buffer; + ck_assert_int_eq(OS_SHA1_File(file_name, buffer, OS_TEXT), 0); + + ck_assert_str_eq(buffer, string_sha1); +} +END_TEST + +START_TEST(test_sha1file_fail) +{ + os_sha1 buffer; + ck_assert_int_eq(OS_SHA1_File("not_existing_file", buffer, OS_TEXT), -1); +} +END_TEST + +START_TEST(test_md5sha1file) +{ + const char *string = "teststring"; + const char *string_md5 = "d67c5cbf5b01c9f91932e3b8def5e5f8"; + const char *string_sha1 = "b8473b86d4c2072ca9b08bd28e373e8253e865c4"; + + /* create tmp file */ + char file_name[256]; + strncpy(file_name, "/tmp/tmp_file-XXXXXX", 256); + int fd = mkstemp(file_name); + + write(fd, string, strlen(string)); + close(fd); + + os_md5 md5buffer; + os_sha1 sha1buffer; + + ck_assert_int_eq(OS_MD5_SHA1_File(file_name, NULL, md5buffer, sha1buffer, OS_TEXT), 0); + + ck_assert_str_eq(md5buffer, string_md5); + ck_assert_str_eq(sha1buffer, string_sha1); +} +END_TEST + +START_TEST(test_md5sha1cmdfile) +{ + const char *string = "teststring"; + const char *string_md5 = "d67c5cbf5b01c9f91932e3b8def5e5f8"; + const char *string_sha1 = "b8473b86d4c2072ca9b08bd28e373e8253e865c4"; + + /* create tmp file */ + char file_name[256]; + strncpy(file_name, "/tmp/tmp_file-XXXXXX", 256); + int fd = mkstemp(file_name); + + write(fd, string, strlen(string)); + close(fd); + + os_md5 md5buffer; + os_sha1 sha1buffer; + + ck_assert_int_eq(OS_MD5_SHA1_File(file_name, "cat ", md5buffer, sha1buffer, OS_TEXT), 0); + + ck_assert_str_eq(md5buffer, string_md5); + ck_assert_str_eq(sha1buffer, string_sha1); +} +END_TEST + +START_TEST(test_md5sha1cmdfile_fail) +{ + os_md5 md5buffer; + os_sha1 sha1buffer; + + ck_assert_int_eq(OS_MD5_SHA1_File("not_existing_file", NULL, md5buffer, sha1buffer, OS_TEXT), -1); +} +END_TEST + +Suite *test_suite(void) +{ + Suite *s = suite_create("os_crypto"); + + TCase *tc_blowfish = tcase_create("blowfish"); + tcase_add_test(tc_blowfish, test_blowfish); + + TCase *tc_md5 = tcase_create("md5"); + tcase_add_test(tc_md5, test_md5string); + tcase_add_test(tc_md5, test_md5file); + tcase_add_test(tc_md5, test_md5file_fail); + + TCase *tc_sha1 = tcase_create("sha1"); + tcase_add_test(tc_sha1, test_sha1file); + tcase_add_test(tc_sha1, test_sha1file_fail); + + TCase *tc_md5sha1 = tcase_create("md5_sha1"); + tcase_add_test(tc_md5sha1, test_md5sha1file); + tcase_add_test(tc_md5sha1, test_md5sha1cmdfile); + tcase_add_test(tc_md5sha1, test_md5sha1cmdfile_fail); + tcase_set_timeout(tc_md5sha1, 7); + + suite_add_tcase(s, tc_blowfish); + suite_add_tcase(s, tc_md5); + suite_add_tcase(s, tc_sha1); + suite_add_tcase(s, tc_md5sha1); + + return (s); +} + +int main(void) +{ + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + int number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return ((number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/src/tests/test_os_net.c b/src/tests/test_os_net.c new file mode 100644 index 000000000..997854ff8 --- /dev/null +++ b/src/tests/test_os_net.c @@ -0,0 +1,383 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include + +#include "../os_net/os_net.h" +#include "../headers/os_err.h" + +#define LOCALHOST4 "127.0.0.1" +#define LOCALHOST6 "::1" +#define PORT "4321" +#define SENDSTRING "Hello World!\n" +#define BUFFERSIZE 1024 + +Suite *test_suite(void); + + +START_TEST(test_tcpv4_local) +{ + int server_root_socket, server_client_socket, client_socket; + char buffer[BUFFERSIZE]; + char *msg; + char ipbuffer[BUFFERSIZE]; + + ck_assert_int_ge((server_root_socket = OS_Bindporttcp(PORT, LOCALHOST4)), 0); + + ck_assert_int_ge((client_socket = OS_ConnectTCP(PORT, LOCALHOST4)) , 0); + + ck_assert_int_ge((server_client_socket = OS_AcceptTCP(server_root_socket, ipbuffer, BUFFERSIZE)), 0); + + ck_assert_str_eq(ipbuffer, LOCALHOST4); + + ck_assert_int_eq(OS_SendTCP(client_socket, SENDSTRING), 0); + + ck_assert_int_eq(OS_RecvTCPBuffer(server_client_socket, buffer, BUFFERSIZE), 0); + + ck_assert_str_eq(buffer, SENDSTRING); + + ck_assert_int_eq(OS_SendTCPbySize(server_client_socket, 5, SENDSTRING), 0); + + ck_assert_ptr_ne((msg = OS_RecvTCP(client_socket, BUFFERSIZE)), NULL); + + ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ + + free(msg); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_client_socket); + OS_CloseSocket(server_root_socket); +} +END_TEST + +START_TEST(test_tcpv4_inet) +{ + int server_root_socket, server_client_socket, client_socket; + char buffer[BUFFERSIZE]; + char *msg; + char ipbuffer[BUFFERSIZE]; + + ck_assert_int_ge((server_root_socket = OS_Bindporttcp(PORT, NULL)), 0); + + ck_assert_int_ge((client_socket = OS_ConnectTCP(PORT, LOCALHOST4)) , 0); + + ck_assert_int_ge((server_client_socket = OS_AcceptTCP(server_root_socket, ipbuffer, BUFFERSIZE)), 0); + + ck_assert_str_eq(ipbuffer, LOCALHOST4); + + ck_assert_int_eq(OS_SendTCP(client_socket, SENDSTRING), 0); + + ck_assert_int_eq(OS_RecvTCPBuffer(server_client_socket, buffer, BUFFERSIZE), 0); + + ck_assert_str_eq(buffer, SENDSTRING); + + ck_assert_int_eq(OS_SendTCPbySize(server_client_socket, 5, SENDSTRING), 0); + + ck_assert_ptr_ne((msg = OS_RecvTCP(client_socket, BUFFERSIZE)), NULL); + + ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ + + free(msg); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_client_socket); + OS_CloseSocket(server_root_socket); +} +END_TEST + +START_TEST(test_tcpv6_local) +{ + int server_root_socket, server_client_socket, client_socket; + char buffer[BUFFERSIZE]; + char *msg; + char ipbuffer[BUFFERSIZE]; + + ck_assert_int_ge((server_root_socket = OS_Bindporttcp(PORT, LOCALHOST6)), 0); + + ck_assert_int_ge((client_socket = OS_ConnectTCP(PORT, LOCALHOST6)) , 0); + + ck_assert_int_ge((server_client_socket = OS_AcceptTCP(server_root_socket, ipbuffer, BUFFERSIZE)), 0); + + ck_assert_str_eq(ipbuffer, LOCALHOST6); + + ck_assert_int_eq(OS_SendTCP(client_socket, SENDSTRING), 0); + + ck_assert_int_eq(OS_RecvTCPBuffer(server_client_socket, buffer, BUFFERSIZE), 0); + + ck_assert_str_eq(buffer, SENDSTRING); + + ck_assert_int_eq(OS_SendTCPbySize(server_client_socket, 5, SENDSTRING), 0); + + ck_assert_ptr_ne((msg = OS_RecvTCP(client_socket, BUFFERSIZE)), NULL); + + ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ + + free(msg); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_client_socket); + OS_CloseSocket(server_root_socket); +} +END_TEST + +START_TEST(test_tcpv6_inet) +{ + int server_root_socket, server_client_socket, client_socket; + char buffer[BUFFERSIZE]; + char *msg; + char ipbuffer[BUFFERSIZE]; + + ck_assert_int_ge((server_root_socket = OS_Bindporttcp(PORT, NULL)), 0); + + ck_assert_int_ge((client_socket = OS_ConnectTCP(PORT, LOCALHOST6)) , 0); + + ck_assert_int_ge((server_client_socket = OS_AcceptTCP(server_root_socket, ipbuffer, BUFFERSIZE)), 0); + + ck_assert_str_eq(ipbuffer, LOCALHOST6); + + ck_assert_int_eq(OS_SendTCP(client_socket, SENDSTRING), 0); + + ck_assert_int_eq(OS_RecvTCPBuffer(server_client_socket, buffer, BUFFERSIZE), 0); + + ck_assert_str_eq(buffer, SENDSTRING); + + ck_assert_int_eq(OS_SendTCPbySize(server_client_socket, 5, SENDSTRING), 0); + + ck_assert_ptr_ne((msg = OS_RecvTCP(client_socket, BUFFERSIZE)), NULL); + + ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ + + free(msg); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_client_socket); + OS_CloseSocket(server_root_socket); +} +END_TEST + +START_TEST(test_tcpinvalidsockets) +{ + char buffer[BUFFERSIZE]; + + ck_assert_int_eq(OS_SendTCP(-1, SENDSTRING), OS_SOCKTERR); + + ck_assert_int_eq(OS_SendTCPbySize(-1, strlen(SENDSTRING), SENDSTRING), OS_SOCKTERR); + + ck_assert_ptr_eq(OS_RecvTCP(-1, BUFFERSIZE), NULL); + + ck_assert_int_eq(OS_RecvTCPBuffer(-1, buffer, BUFFERSIZE), -1); + + ck_assert_int_eq(OS_AcceptTCP(-1, buffer, BUFFERSIZE), -1); +} +END_TEST + +START_TEST(test_udpv4) +{ + int server_socket, client_socket; + char buffer[BUFFERSIZE]; + char *msg; + + ck_assert_int_ge((server_socket = OS_Bindportudp(PORT, LOCALHOST4)), 0); + + ck_assert_int_ge((client_socket = OS_ConnectUDP(PORT, LOCALHOST4)) , 0); + + //TODO: ck_assert_int_eq(OS_SendUDP(client_socket, SENDSTRING), 0); + ck_assert_int_eq(OS_SendUDPbySize(client_socket, strlen(SENDSTRING), SENDSTRING), 0); + + //TODO: not null-terminated + ck_assert_int_eq(OS_RecvConnUDP(server_socket, buffer, BUFFERSIZE), strlen(SENDSTRING)); + + ck_assert_str_eq(buffer, SENDSTRING); + + ck_assert_int_eq(OS_SendUDPbySize(client_socket, 5, SENDSTRING), 0); + + ck_assert_ptr_ne((msg = OS_RecvUDP(server_socket, BUFFERSIZE)), NULL); + + ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ + + free(msg); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_socket); +} +END_TEST + +START_TEST(test_udpv6) +{ + int server_socket, client_socket; + char buffer[BUFFERSIZE]; + char *msg; + + ck_assert_int_ge((server_socket = OS_Bindportudp(PORT, LOCALHOST6)), 0); + + ck_assert_int_ge((client_socket = OS_ConnectUDP(PORT, LOCALHOST6)) , 0); + + //TODO: ck_assert_int_eq(OS_SendUDP(client_socket, SENDSTRING), 0); + ck_assert_int_eq(OS_SendUDPbySize(client_socket, strlen(SENDSTRING), SENDSTRING), 0); + + //TODO: not null-terminated + ck_assert_int_eq(OS_RecvConnUDP(server_socket, buffer, BUFFERSIZE), strlen(SENDSTRING)); + + ck_assert_str_eq(buffer, SENDSTRING); + + ck_assert_int_eq(OS_SendUDPbySize(client_socket, 5, SENDSTRING), 0); + + ck_assert_ptr_ne((msg = OS_RecvUDP(server_socket, BUFFERSIZE)), NULL); + + ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ + + free(msg); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_socket); +} +END_TEST + +START_TEST(test_udpinvalidsockets) +{ + char buffer[BUFFERSIZE]; + + //TODO: ck_assert_int_eq(OS_SendUDP(-1, SENDSTRING), OS_SOCKTERR); + + ck_assert_int_eq(OS_SendUDPbySize(-1, strlen(SENDSTRING), SENDSTRING), OS_SOCKTERR); + + ck_assert_ptr_eq(OS_RecvUDP(-1, BUFFERSIZE), NULL); + + ck_assert_int_eq(OS_RecvConnUDP(-1, buffer, BUFFERSIZE), 0); +} +END_TEST + +START_TEST(test_unix) +{ + int fd; + + /* create socket path */ + char socket_path[256]; + strncpy(socket_path, "/tmp/tmp_file-XXXXXX", 256); + fd = mkstemp(socket_path); + close(fd); + + int server_socket, client_socket; + const int msg_size = 2048; + char buffer[BUFFERSIZE]; + + ck_assert_int_ge((server_socket = OS_BindUnixDomain(socket_path, 0660, msg_size)), 0); + + ck_assert_int_ge(OS_getsocketsize(server_socket), msg_size); + + ck_assert_int_ge((client_socket = OS_ConnectUnixDomain(socket_path, msg_size)), 0); + + ck_assert_int_eq(OS_SendUnix(client_socket, SENDSTRING, 5), 0); + + ck_assert_int_eq(OS_RecvUnix(server_socket, BUFFERSIZE, buffer), 5); + + ck_assert_str_eq(buffer, "Hello"); + + ck_assert_int_eq(OS_SendUnix(client_socket, SENDSTRING, 0), 0); + + ck_assert_int_eq(OS_RecvUnix(server_socket, BUFFERSIZE, buffer), strlen(SENDSTRING) + 1); + + ck_assert_str_eq(buffer, SENDSTRING); + + OS_CloseSocket(client_socket); + OS_CloseSocket(server_socket); + + unlink(socket_path); +} +END_TEST + +START_TEST(test_unixinvalidsockets) +{ + char buffer[BUFFERSIZE]; + + ck_assert_int_eq(OS_SendUnix(-1, SENDSTRING, strlen(SENDSTRING)), OS_SOCKTERR); + + ck_assert_int_eq(OS_RecvUnix(-1, BUFFERSIZE, buffer), 0); +} +END_TEST + +START_TEST(test_gethost_success_ipv4) +{ + char *ret; + + ck_assert_str_eq((ret = OS_GetHost("ipv4.test-ipv6.com", 2)), "216.218.228.119"); + + free(ret); +} +END_TEST + +START_TEST(test_gethost_success_ipv6) +{ + char *ret; + + ck_assert_str_eq((ret = OS_GetHost("ipv6.test-ipv6.com", 2)), "2001:470:1:18::119"); + + free(ret); +} +END_TEST + +START_TEST(test_gethost_fail1) +{ + ck_assert_ptr_eq(OS_GetHost(NULL, 2), NULL); +} +END_TEST + +START_TEST(test_gethost_fail2) +{ + ck_assert_ptr_eq(OS_GetHost("this.should.not.exist", 2), NULL); +} +END_TEST + +Suite *test_suite(void) +{ + Suite *s = suite_create("os_net"); + + TCase *tc_tcp = tcase_create("TCP"); + tcase_add_test(tc_tcp, test_tcpv4_local); + tcase_add_test(tc_tcp, test_tcpv4_inet); + tcase_add_test(tc_tcp, test_tcpv6_local); + tcase_add_test(tc_tcp, test_tcpv6_inet); + tcase_add_test(tc_tcp, test_tcpinvalidsockets); + + TCase *tc_udp = tcase_create("UDP"); + tcase_add_test(tc_udp, test_udpv4); + tcase_add_test(tc_udp, test_udpv6); + tcase_add_test(tc_udp, test_udpinvalidsockets); + + TCase *tc_unix = tcase_create("Unix"); + tcase_add_test(tc_unix, test_unix); + tcase_add_test(tc_unix, test_unixinvalidsockets); + + TCase *tc_gethost = tcase_create("GetHost"); + tcase_add_test(tc_gethost, test_gethost_success_ipv4); + tcase_add_test(tc_gethost, test_gethost_success_ipv6); + tcase_add_test(tc_gethost, test_gethost_fail1); + tcase_add_test(tc_gethost, test_gethost_fail2); + tcase_set_timeout(tc_gethost, 10); + + suite_add_tcase(s, tc_tcp); + suite_add_tcase(s, tc_udp); + suite_add_tcase(s, tc_unix); + suite_add_tcase(s, tc_gethost); + + return (s); +} + +int main(void) +{ + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + int number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return ((number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/src/tests/test_os_regex.c b/src/tests/test_os_regex.c new file mode 100644 index 000000000..de454a3f1 --- /dev/null +++ b/src/tests/test_os_regex.c @@ -0,0 +1,914 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include + +#include "../os_regex/os_regex.h" +#include "../os_regex/os_regex_internal.h" + +Suite *test_suite(void); + + +START_TEST(test_success_match1) +{ + + int i; + const char *tests[][3] = { + {"abc", "abcd", ""}, + {"abcd", "abcd", ""}, + {"a", "a", ""}, + {"a", "aa", ""}, + {"^a", "ab", ""}, + {"test", "testa", ""}, + {"test", "testest", ""}, + {"lalaila", "lalalalaila", ""}, + {"abc|cde", "cde", ""}, + {"^aa|ee|ii|oo|uu", "dfgdsii", ""}, + {"Abc", "abc", ""}, + {"ZBE", "zbe", ""}, + {"ABC", "ABc", ""}, + {"^A", "a", ""}, + {"a|E", "abcdef", ""}, + {"daniel", "daniel", ""}, + {"DANIeL", "daNIel", ""}, + {"^abc ", "abc ", ""}, + {"ddd|eee|fff|ggg|ggg|hhh|iii", "iii", ""}, + {"kwo|fe|fw|wfW|edW|dwDF|WdW|dw|d|^la", "la", ""}, + {"^a", "a", ""}, + {"^ab$", "ab", ""}, + {"c$", "c", ""}, + {"c$", "lalalalac", ""}, + {"^bin$|^shell$", "bin", ""}, + {"^bin$|^shell$", "shell", ""}, + {"^bin$|^shell$|^ftp$", "shell", ""}, + {"^bin$|^shell$|^ftp$", "ftp", ""}, + {NULL, NULL, NULL} + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(OS_Match2(tests[i][0], tests[i][1]), + "%s should have OS_Match2 true with %s: Ref: %s", + tests[i][0], tests[i][1], tests[i][1]); + } +} +END_TEST + +START_TEST(test_fail_match1) +{ + + int i; + const char *tests[][3] = { + {"abc", "abb", ""}, + {"^ab", " ab", ""}, + {"test", "tes", ""}, + {"abcd", "abc", ""}, + {"abbb", "abb", ""}, + {"abbbbbbbb", "abbbbbbb", ""}, + {"a|b|c| ", "def", ""}, + {"lala$", "lalalalalal", ""}, + {"^ab$", "abc", ""}, + {"zzzz$", "zzzzzzzzzzzz ", ""}, + {"^bin$|^shell$", "bina", ""}, + {"^bin$|^shell$", "shella", ""}, + {"^bin$|^shell$", "ashell", ""}, + {NULL, NULL, NULL} + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(!OS_Match2(tests[i][0], tests[i][1]), + "%s should have OS_Match2 false with %s: Ref: %s", + tests[i][0], tests[i][1], tests[i][2]); + } +} +END_TEST + +START_TEST(test_success_regex1) +{ + + int i; + /* + * Please note that all strings are \ escaped + */ + const char *tests[][3] = { + {"abc", "abcd", ""}, + {"abcd", "abcd", ""}, + {"a", "a", ""}, + {"a", "aa", ""}, + {"^a", "ab", ""}, + {"test", "testa", ""}, + {"test", "testest", ""}, + {"lalaila", "lalalalaila", ""}, + {"abc|cde", "cde", ""}, + {"^aa|ee|ii|oo|uu", "dfgdsii", ""}, + {"Abc", "abc", ""}, + {"ZBE", "zbe", ""}, + {"ABC", "ABc", ""}, + {"^A", "a", ""}, + {"a|E", "abcdef", ""}, + {"daniel", "daniel", ""}, + {"DANIeL", "daNIel", ""}, + {"^abc ", "abc ", ""}, + {"ddd|eee|fff|ggg|ggg|hhh|iii", "iii", ""}, + {"kwo|fe|fw|wfW|edW|dwDF|WdW|dw|d|^la", "la", ""}, + {"^a", "a", ""}, + {"^ab$", "ab", ""}, + {"c$", "c", ""}, + {"c$", "lalalalac", ""}, + {"^bin$|^shell$", "bin", ""}, + {"^bin$|^shell$", "shell", ""}, + {"^bin$|^shell$|^ftp$", "shell", ""}, + {"^bin$|^shell$|^ftp$", "ftp", ""}, + {"\\s+123", " 123", ""}, + {"\\s*123", "123", ""}, + {"\\s123", " 123", ""}, + {"\\w+\\s+\\w+", "a 1", ""}, + {"\\w+\\d+\\w+\\s+", "ab12fb12fd12 ", ""}, + {"^\\s*\\w\\s*\\w+", "a l a a", ""}, + {"\\w+\\s+\\w+\\d+\\s$", "a aa11 ", ""}, + {"^su\\S*: BAD su", "su: BAD SU dcid to root on /dev/ttyp0", ""}, + {"^su\\s*: BAD su", "su: BAD SU dcid to root on /dev/ttyp0", ""}, + {"^abc\\sabc", "abc abcd", ""}, + {"^abc\\s\\s*abc", "abc abcd", ""}, + {"^\\s+\\sl", " lala", ""}, + {"^\\s*\\sl", " lala", ""}, + {"^\\s\\s+l", " lala", ""}, + {"^\\s+\\s l", " lala", ""}, + {"^\\s*\\s lal\\w$", " lala", ""}, + {"test123test\\d+$", "test123test123", ""}, + {"^kernel: \\S+ \\.+ SRC=\\S+ DST=\\S+ \\.+ PROTO=\\w+ SPT=\\d+ DPT=\\d+ ", "kernel: IPTABLE IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:03:93:db:2e:b4:08:00 SRC=10.4.11.40 DST=255.255.255.255 LEN=180 TOS=0x00 PREC=0x00 TTL=64 ID=4753 PROTO=UDP SPT=49320 DPT=2222 LEN=160", ""}, + {"test (\\w+)la", "test abclala", ""}, + {"(\\w+) (\\w+)", "wofl wofl", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:469:3] ICMP PING NMAP [Classification: Attempted Information Leak] [Priority: 2]: {ICMP} 10.4.12.26 -> 10.4.10.231", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:408:5] ICMP Echo Reply [Classification: Misc Activity] [Priority: 3]: {ICMP} 10.4.10.231 -> 10.4.12.26", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:162", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37021 -> 10.4.10.231:162", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:669 -> 10.4.3.20:111", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:670 -> 10.4.3.20:111", ""}, + {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1421:11] SNMP AgentX/tcp request [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:705", ""}, + {NULL, NULL, NULL} + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(OS_Regex(tests[i][0], tests[i][1]), + "%s should have OS_Regex true with %s: Ref: %s", + tests[i][0], tests[i][1], tests[i][2]); + } +} +END_TEST + +START_TEST(test_fail_regex1) +{ + + int i; + /* + * Please note that all strings are \ escaped + */ + const char *tests[][3] = { + {"abc", "abb", ""}, + {"^ab", " ab", ""}, + {"test", "tes", ""}, + {"abcd", "abc", ""}, + {"abbb", "abb", ""}, + {"abbbbbbbb", "abbbbbbb", ""}, + {"a|b|c| ", "def", ""}, + {"lala$", "lalalalalal", ""}, + {"^ab$", "abc", ""}, + {"zzzz$", "zzzzzzzzzzzz ", ""}, + {"^bin$|^shell$", "bina", ""}, + {"^bin$|^shell$", "shella", ""}, + {"^bin$|^shell$", "ashell", ""}, + {"\\w+\\s+\\w+\\d+\\s$", "a aa11 ", ""}, + {"^\\s+\\s l", " lala", ""}, + {"test123test\\d+", "test123test", ""}, + {"test123test\\d+$", "test123test", ""}, + {"(lalala", "lalala", ""}, + {"test123(\\d)", "test123a", ""}, + {"\\(test)", "test", ""}, + {"(\\w+)(\\d+)", "1 1", ""}, + {NULL, NULL, NULL}, + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(!OS_Regex(tests[i][0], tests[i][1]), + "%s should have OS_Regex false with %s: Ref: %s", + tests[i][0], tests[i][1], tests[i][2]); + } +} +END_TEST + +START_TEST(test_success_wordmatch) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[][2] = { + { "test", "this is a test" }, + { "test", "thistestiswithoutspaces" }, + { "test|not", "test" }, + { "test|not", "not" }, + { "^test", "test on start" }, + {NULL, NULL}, + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(OS_WordMatch(tests[i][0], tests[i][1]), + "%s should match positive with %s by OS_WordMatch", + tests[i][0], tests[i][1]); + } + +} +END_TEST + +START_TEST(test_fail_wordmatch) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[][2] = { + { "-test", "this is a test" }, + { "", "test" }, + { "test|not", "negative" }, + { "test", "" }, + { "^test", "starttest" }, + {NULL, NULL}, + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(!OS_WordMatch(tests[i][0], tests[i][1]), + "%s should not match positive with %s by OS_WordMatch", + tests[i][0], tests[i][1]); + } + +} +END_TEST + +START_TEST(test_success_strisnum) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[] = { + "1", + "0123", + NULL, + }; + + for (i = 0; tests[i] != NULL ; i++) { + ck_assert_msg(OS_StrIsNum(tests[i]), + "%s should match positive by OS_StrIsNum", + tests[i]); + } + +} +END_TEST + +START_TEST(test_fail_strisnum) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[] = { + "test", + "1234e", + "-1", + "+1", + NULL, + }; + + for (i = 0; tests[i] != NULL ; i++) { + ck_assert_msg(!OS_StrIsNum(tests[i]), + "%s should not match positive by OS_StrIsNum", + tests[i]); + } + +} +END_TEST + +START_TEST(test_strhowclosedmatch) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[][3] = { + { "test", "test1234", "4" }, + { "test1234", "test", "4" }, + { "test", "test", "4" }, + { "test", "", "0" }, + { "", "test", "0" }, + {NULL, NULL, NULL}, + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_uint_eq(OS_StrHowClosedMatch(tests[i][0], tests[i][1]) + , (unsigned) atoi(tests[i][2])); + } + +} +END_TEST + +START_TEST(test_strbreak) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[][15] = { + { "X", "testX1234", "4", "test", "1234", NULL}, + { "X", "XtestX1234X", "4", "", "test", "1234", "", NULL}, + { "Y", "testX1234", "4", "testX1234", NULL}, + { "X", "testXX1234", "4", "test", "", "1234", NULL}, + { "X", "testX1234", "1", "testX1234", NULL}, + { "X", "testX1234X5678", "2", "test", "1234X5678", NULL}, + { "X", "testX1234", "0", NULL}, + {NULL}, + }; + + for (i = 0; tests[i][0] != NULL; i++) { + char **result = OS_StrBreak(tests[i][0][0], tests[i][1], (unsigned) atoi(tests[i][2])); + + int j = 3; + if (tests[i][j] == NULL) { + ck_assert_ptr_eq(result, NULL); + continue; + } + + int k; + for (k = 0; tests[i][j] != NULL; j++, k++) { + ck_assert_ptr_ne(result[k], NULL); + ck_assert_str_eq(result[k], tests[i][j]); + } + ck_assert_ptr_eq(result[k], NULL); + + k = 0; + while (result[k]) { + free(result[k++]); + } + free(result); + } + +} +END_TEST + +START_TEST(test_regexextraction) +{ + + int i; + /* + * Please note that all strings are \ escaped + */ + const char *tests[][15] = { + { "123(\\w+\\s+)abc", "123sdf abc", "sdf ", NULL}, + { "123(\\w+\\s+)abc", "abc123sdf abc", "sdf ", NULL}, + { "123 (\\d+.\\d.\\d.\\d\\d*\\d*)", "123 45.6.5.567", "45.6.5.567", NULL}, + { "from (\\S*\\d+.\\d+.\\d+.\\d\\d*\\d*)", "sshd[21576]: Illegal user web14 from ::ffff:212.227.60.55", "::ffff:212.227.60.55", NULL}, + { "^sshd[\\d+]: Accepted \\S+ for (\\S+) from (\\S+) port ", "sshd[21405]: Accepted password for root from 192.1.1.1 port 6023", "root", "192.1.1.1", NULL}, + { ": \\((\\S+)@(\\S+)\\) [", "pure-ftpd: (?@enigma.lab.theopenarmor.org) [INFO] New connection from enigma.lab.theopenarmor.org", "?", "enigma.lab.theopenarmor.org", NULL}, + {NULL, NULL, NULL} + }; + + for (i = 0; tests[i][0] != NULL; i++) { + OSRegex reg; + ck_assert_int_eq(OSRegex_Compile(tests[i][0], ®, OS_RETURN_SUBSTRING), 1); + ck_assert_ptr_ne((void *)OSRegex_Execute(tests[i][1], ®), NULL); + + + + char **result = reg.sub_strings; + + int j; + int k; + for (j = 2, k = 0; tests[i][j] != NULL; j++, k++) { + ck_assert_ptr_ne(result[k], NULL); + ck_assert_str_eq(result[k], tests[i][j]); + } + ck_assert_ptr_eq(result[k], NULL); + + OSRegex_FreePattern(®); + } +} +END_TEST + +START_TEST(test_hostnamemap) +{ + unsigned char test = 0; + + while (1) { + if ((test >= 48 && test <= 57) // 0-9 + || (test >= 65 && test <= 90) // A-Z + || (test >= 97 && test <= 122) // a-z + || test == '(' || test == ')' || test == '-' + || test == '.' || test == '@' || test == '/' + || test == '_') { + ck_assert_msg(isValidChar(test) == 1, "char %d should be a valid hostname char", test); + } else { + ck_assert_msg(isValidChar(test) != 1, "char %d should not be a valid hostname char", test); + } + + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_caseinsensitivecharmap) +{ + unsigned char test = 0; + + while (1) { + if (test >= 65 && test <= 90) { // A-Z + ck_assert_msg(charmap[test] == test + 32, "char %d should resolve to lowercase version %d and not to %d", test, test + 32, charmap[test]); + } else { + ck_assert_msg(charmap[test] == test, "char %d should resolve to itself and not to %d", test, charmap[test]); + } + + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_digit) +{ + unsigned char test = 0; + + while (1) { + if (test >= '0' && test <= '9') { + ck_assert_msg(regexmap[1][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[1][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_word) +{ + unsigned char test = 0; + + while (1) { + if ((test >= 'a' && test <= 'z') + || (test >= 'A' && test <= 'Z') + || (test >= '0' && test <= '9') + || test == '-' || test == '@' + || test == '_') { + ck_assert_msg(regexmap[2][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[2][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_space) +{ + unsigned char test = 0; + + while (1) { + if (test == ' ') { + ck_assert_msg(regexmap[3][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[3][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_punctuation) +{ + unsigned char test = 0; + + while (1) { + if (test == '<' || test == '>' || test == '!' || test == '?' + || test == '"' || test == '\'' || test == '#' + || test == '$' || test == '%' || test == '&' + || test == '(' || test == ')' || test == '+' + || test == '*' || test == ',' || test == '-' + || test == '-' || test == ':' || test == '|' + || test == '.' || test == ';' || test == '=' + || test == '[' || test == ']' || test == '{' + || test == '}') { + ck_assert_msg(regexmap[4][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[4][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_lparenthesis) +{ + unsigned char test = 0; + + while (1) { + if (test == '(') { + ck_assert_msg(regexmap[5][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[5][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_rparenthesis) +{ + unsigned char test = 0; + + while (1) { + if (test == ')') { + ck_assert_msg(regexmap[6][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[6][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_backslash) +{ + unsigned char test = 0; + + while (1) { + if (test == '\\') { + ck_assert_msg(regexmap[7][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[7][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + + +START_TEST(test_regexmap_nondigit) +{ + unsigned char test = 0; + + while (1) { + if (!(test >= '0' && test <= '9')) { + ck_assert_msg(regexmap[8][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[8][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_nonword) +{ + unsigned char test = 0; + + while (1) { + if (!((test >= 'a' && test <= 'z') + || (test >= 'A' && test <= 'Z') + || (test >= '0' && test <= '9') + || test == '-' || test == '@' + || test == '_')) { + ck_assert_msg(regexmap[9][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[9][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_nonspace) +{ + unsigned char test = 0; + + while (1) { + if (test != ' ') { + ck_assert_msg(regexmap[10][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[10][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_all) +{ + unsigned char test = 0; + + while (1) { + ck_assert_msg(regexmap[11][test] == 1, "char %d should match", test); + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_tab) +{ + unsigned char test = 0; + + while (1) { + if (test == '\t') { + ck_assert_msg(regexmap[12][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[12][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_dollar) +{ + unsigned char test = 0; + + while (1) { + if (test == '$') { + ck_assert_msg(regexmap[13][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[13][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_or) +{ + unsigned char test = 0; + + while (1) { + if (test == '|') { + ck_assert_msg(regexmap[14][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[14][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_regexmap_lt) +{ + unsigned char test = 0; + + while (1) { + if (test == '<') { + ck_assert_msg(regexmap[15][test] == 1, "char %d should match", test); + } else { + ck_assert_msg(regexmap[15][test] != 1, "char %d should not match", test); + } + + + if (test == 255) { + break; + } + test++; + } + +} +END_TEST + +START_TEST(test_success_strstartswith) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[][2] = { + { "test1234", "test" }, + { "test", "test" }, + { "test", "" }, + { "", "" }, + {NULL, NULL}, + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(OS_StrStartsWith(tests[i][0], tests[i][1]), + "%s should match positive with %s by OS_StrStartsWith", + tests[i][0], tests[i][1]); + } + +} +END_TEST + +START_TEST(test_fail_strstartswith) +{ + int i; + + /* + * Please note that all strings are \ escaped + */ + const char *tests[][2] = { + { "test", "test1234" }, + { "", "test" }, + {NULL, NULL}, + }; + + for (i = 0; tests[i][0] != NULL ; i++) { + ck_assert_msg(!OS_StrStartsWith(tests[i][0], tests[i][1]), + "%s should not match positive with %s by OS_StrStartsWith", + tests[i][0], tests[i][1]); + } + +} +END_TEST + +Suite *test_suite(void) +{ + Suite *s = suite_create("os_regex"); + + /* Core test case */ + TCase *tc_match = tcase_create("Match"); + TCase *tc_regex = tcase_create("Regex"); + TCase *tc_wordmatch = tcase_create("WordMatch"); + TCase *tc_strisnum = tcase_create("StrIsNum"); + TCase *tc_strhowclosedmatch = tcase_create("StrHowClosedMatch"); + TCase *tc_strbreak = tcase_create("StrBreak"); + TCase *tc_regexextraction = tcase_create("RegexExtraction"); + TCase *tc_hostnamemap = tcase_create("HostnameMap"); + TCase *tc_caseinsensitivecharmap = tcase_create("CaseInsensitiveCharmap"); + TCase *tc_regexmap = tcase_create("RegexMap"); + TCase *tc_strstartswith = tcase_create("StrStartsWith"); + + tcase_add_test(tc_match, test_success_match1); + tcase_add_test(tc_match, test_fail_match1); + + tcase_add_test(tc_regex, test_success_regex1); + tcase_add_test(tc_regex, test_fail_regex1); + + tcase_add_test(tc_wordmatch, test_success_wordmatch); + tcase_add_test(tc_wordmatch, test_fail_wordmatch); + + tcase_add_test(tc_strisnum, test_success_strisnum); + tcase_add_test(tc_strisnum, test_fail_strisnum); + + tcase_add_test(tc_strhowclosedmatch, test_strhowclosedmatch); + + tcase_add_test(tc_strbreak, test_strbreak); + + tcase_add_test(tc_regexextraction, test_regexextraction); + + tcase_add_test(tc_hostnamemap, test_hostnamemap); + + tcase_add_test(tc_caseinsensitivecharmap, test_caseinsensitivecharmap); + + tcase_add_test(tc_regexmap, test_regexmap_digit); + tcase_add_test(tc_regexmap, test_regexmap_word); + tcase_add_test(tc_regexmap, test_regexmap_space); + tcase_add_test(tc_regexmap, test_regexmap_punctuation); + tcase_add_test(tc_regexmap, test_regexmap_lparenthesis); + tcase_add_test(tc_regexmap, test_regexmap_rparenthesis); + tcase_add_test(tc_regexmap, test_regexmap_backslash); + tcase_add_test(tc_regexmap, test_regexmap_nondigit); + tcase_add_test(tc_regexmap, test_regexmap_nonword); + tcase_add_test(tc_regexmap, test_regexmap_nonspace); + tcase_add_test(tc_regexmap, test_regexmap_all); + tcase_add_test(tc_regexmap, test_regexmap_tab); + tcase_add_test(tc_regexmap, test_regexmap_dollar); + tcase_add_test(tc_regexmap, test_regexmap_or); + tcase_add_test(tc_regexmap, test_regexmap_lt); + + tcase_add_test(tc_strstartswith, test_success_strstartswith); + tcase_add_test(tc_strstartswith, test_fail_strstartswith); + + suite_add_tcase(s, tc_match); + suite_add_tcase(s, tc_regex); + suite_add_tcase(s, tc_wordmatch); + suite_add_tcase(s, tc_strisnum); + suite_add_tcase(s, tc_strhowclosedmatch); + suite_add_tcase(s, tc_strbreak); + suite_add_tcase(s, tc_regexextraction); + suite_add_tcase(s, tc_hostnamemap); + suite_add_tcase(s, tc_caseinsensitivecharmap); + suite_add_tcase(s, tc_regexmap); + suite_add_tcase(s, tc_strstartswith); + + return (s); +} + +int main(void) +{ + Suite *s = test_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + int number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return ((number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/src/tests/test_os_xml.c b/src/tests/test_os_xml.c new file mode 100644 index 000000000..55e307ea3 --- /dev/null +++ b/src/tests/test_os_xml.c @@ -0,0 +1,982 @@ +/* Copyright (C) 2014 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include + +#include "../os_xml/os_xml.h" +#include "../os_xml/os_xml_internal.h" + +Suite *test_suite(void); + + +static void create_xml_file(const char *str, char file_name[], size_t length) +{ + strncpy(file_name, "/tmp/tmp_file-XXXXXX", length); + int fd = mkstemp(file_name); + + write(fd, str, strlen(str)); + close(fd); +} + +static void nodecat(XML_NODE node, OS_XML *xml, char *buffer) +{ + int i = 0; + /* write node */ + while (node[i]) { + strncat(buffer, "<", 1); + ck_assert_ptr_ne(node[i]->element, NULL); + strncat(buffer, node[i]->element, strlen(node[i]->element)); + /* write attributes */ + if (node[i]->attributes) { + ck_assert_ptr_ne(node[i]->values, NULL); + int j = 0; + while (node[i]->attributes[j]) { + strncat(buffer, " ", 1); + ck_assert_ptr_ne(node[i]->values[j], NULL); + strncat(buffer, node[i]->attributes[j], strlen(node[i]->attributes[j])); + strncat(buffer, "=", 1); + strncat(buffer, "\"", 1); + strncat(buffer, node[i]->values[j], strlen(node[i]->values[j])); + strncat(buffer, "\"", 1); + j++; + } + ck_assert_ptr_eq(node[i]->values[j], NULL); + } else { + ck_assert_ptr_eq(node[i]->values, NULL); + } + strncat(buffer, ">", 1); + ck_assert_ptr_ne(node[i]->content, NULL); + strncat(buffer, node[i]->content, strlen(node[i]->content)); + + /* write children */ + XML_NODE child = OS_GetElementsbyNode(xml, node[i]); + if (child != NULL) { + nodecat(child, xml, buffer); + OS_ClearNode(child); + } + + /* close node */ + strncat(buffer, "element, strlen(node[i]->element)); + strncat(buffer, ">", 1); + i++; + } +} + +static void assert_os_xml_eq_str(OS_XML *xml, const char *xml_str) +{ + XML_NODE node = OS_GetElementsbyNode(xml, NULL); + if (node == NULL) { + ck_assert_str_eq(xml_str, ""); + return; + } + + char *buffer = (char *) malloc(6144 * sizeof(char)); + buffer[0] = '\0'; + nodecat(node, xml, buffer); + OS_ClearNode(node); + + ck_assert_str_eq(buffer, xml_str); + + free(buffer); +} + +#define assert_os_xml_eq(PARSE_STR, XML_STR) do { \ + char _ck_xml_file_name[256]; \ + create_xml_file(PARSE_STR, _ck_xml_file_name, 256); \ + OS_XML _ck_xml; \ + ck_assert_int_eq(OS_ReadXML(_ck_xml_file_name, &_ck_xml), 0); \ + ck_assert_int_eq(OS_ApplyVariables(&_ck_xml), 0); \ + assert_os_xml_eq_str(&_ck_xml, XML_STR); \ + OS_ClearXML(&_ck_xml); \ + unlink(_ck_xml_file_name); \ +} while (0) + +START_TEST(test_simplenodes) +{ + assert_os_xml_eq("", ""); + assert_os_xml_eq("", ""); + assert_os_xml_eq("", ""); + assert_os_xml_eq("", ""); +} +END_TEST + + +START_TEST(test_multiplenodes) +{ + assert_os_xml_eq( + "" + "" + "", + "" + "" + ""); +} +END_TEST + +START_TEST(test_children) +{ + assert_os_xml_eq( + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""); +} +END_TEST + +START_TEST(test_multiplecontent) +{ + assert_os_xml_eq( + "" + "value1" + "" + "", + ""); + assert_os_xml_eq( + "" + "value1" + "" + "value2" + "", + "value2"); +} +END_TEST + + +START_TEST(test_attributes) +{ + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); +} +END_TEST + +START_TEST(test_variables) +{ + assert_os_xml_eq( + "value1" + "value2" + "$var2" + "blah$var2" + "blah$var2$var1 blah", + "value2" + "blahvalue2" + "blahvalue2value1 blah"); +} +END_TEST + +START_TEST(test_comments) +{ + assert_os_xml_eq( + "", + ""); + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); + + assert_os_xml_eq( + "", + ""); +} +END_TEST + +START_TEST(test_specialchars) +{ + assert_os_xml_eq( + "value1" + "\\", + "\\"); +} +END_TEST + +START_TEST(test_linecounter) +{ + char xml_file_name[256]; + create_xml_file("\n\n" , xml_file_name, 256); + OS_XML xml; + XML_NODE node; + ck_assert_int_eq(OS_ReadXML(xml_file_name, &xml), 0); + ck_assert_int_eq(OS_ApplyVariables(&xml), 0); + ck_assert_ptr_ne(node = OS_GetElementsbyNode(&xml, NULL), NULL); + ck_assert_int_eq(xml.ln[0], 1); + ck_assert_int_eq(xml.ln[1], 2); + ck_assert_int_eq(xml.ln[2], 3); + + OS_ClearNode(node); + OS_ClearXML(&xml); + unlink(xml_file_name); +} +END_TEST + +START_TEST(test_invalidfile) +{ + OS_XML xml; + ck_assert_int_ne(OS_ReadXML("invalid_file.inv", &xml), 0); + ck_assert_str_eq(xml.err, "XMLERR: File 'invalid_file.inv' not found."); + ck_assert_int_eq(xml.err_line, 0); + + OS_ClearXML(&xml); +} +END_TEST + +START_TEST(test_unclosednode) +{ + char xml_file_name[256]; + create_xml_file("", xml_file_name, 256); + OS_XML xml; + ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); + ck_assert_str_eq(xml.err, "XMLERR: End of file and some elements were not closed."); + ck_assert_int_eq(xml.err_line, 1); + + OS_ClearXML(&xml); + unlink(xml_file_name); +} +END_TEST + +START_TEST(test_unclosednode2) +{ + char xml_file_name[256]; + create_xml_file("", xml_file_name, 256); + OS_XML xml; + ck_assert_int_ne(OS_ReadXML(xml_file_name, &xml), 0); + ck_assert_str_eq(xml.err, "XMLERR: Element 'root' not closed."); + ck_assert_int_eq(xml.err_line, 1); + + OS_ClearXML(&xml); + unlink(xml_file_name); +} +END_TEST + +START_TEST(test_unclosedcomment) +{ + char xml_file_name[256]; + create_xml_file("\r\n" + "\r\n" + " \r\n" + " %s\r\n" + " syslog\r\n" + " \r\n" + "\r\n\r\n", file); + + printf("%s: Action completed.\n", name); + fclose(fp); + + return (0); +} + +/* Setup Windows after install */ +int main(int argc, char **argv) +{ + int quiet = 0; + + if (argc < 2) { + printf("%s: Invalid syntax.\n", argv[0]); + printf("Try: '%s '\n\n", argv[0]); + } + + /* Look for the quiet option */ + if ((argc == 3) && (strcmp(argv[2], "--quiet") == 0)) { + quiet = 1; + } + + /* Check if openarmor-HIDS was installed already */ + if (!fileexist(openarmorCONF)) { + printf("%s: Unable to find openarmor config: '%s'.\n", argv[0], openarmorCONF); + } else { + config_file(argv[0], argv[1], quiet); + } + + return (0); +} diff --git a/src/win32/agent_auth.c b/src/win32/agent_auth.c new file mode 100644 index 000000000..957110286 --- /dev/null +++ b/src/win32/agent_auth.c @@ -0,0 +1,479 @@ +#define SECURITY_WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include "headers/shared.h" +#include "debug_op.h" +#include "file_op.h" +#include "os_net/os_net.h" +#include "os_regex/os_regex.h" +#include "defs.h" +#include "addagent/manage_agents.h" + +#define IO_BUFFER_SIZE 0x10000 + +void report_help() +{ + printf("\n%s %s: Connects to the manager to extract the agent key.\n", __openarmor_name, ARGV0); + printf("Available options:\n"); + printf("\t-h This help message.\n"); + printf("\t-m Manager IP Address.\n"); + printf("\t-p Manager port (default 1515).\n"); + printf("\t-A Agent name (default is the hostname).\n"); + printf("\t-P Authorization password.\n"); + exit(1); +} + +void SendSecurityToken(const int socket, SecBuffer *OutBuffers) +{ + int sent = 0; + + if (OutBuffers[0].cbBuffer != 0 && OutBuffers[0].pvBuffer != NULL) + { + sent = send(socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer, 0); + if (sent <= 0) + ErrorExit("%s: Could not send security token to server (is openarmor-authd running ?)", ARGV0); + + // Free Output Buffer + FreeContextBuffer(OutBuffers[0].pvBuffer); + OutBuffers[0].pvBuffer = NULL; + OutBuffers[0].cbBuffer = 0; + } +} + +void CreateSecureConnection(char *manager, char *port, int *socket, CtxtHandle *context, CredHandle *cred) +{ + SECURITY_STATUS status; + SCHANNEL_CRED auth_cred; + DWORD input_flags = 0; + DWORD output_flags = 0; + DWORD read = 0; + DWORD total_read = 0; + SecBufferDesc OutBuffer; + SecBuffer OutBuffers[1]; + SecBufferDesc InBuffer; + SecBuffer InBuffers[2]; + PCHAR buffer = NULL; + + // Get manager IP address + + manager = OS_GetHost(manager, 3); + if (manager == NULL) + ErrorExit("%s: Could not resolve manager's hostname", ARGV0); + + + + // Connect via TCP + + *socket = OS_ConnectTCP(port, manager); + + if (socket == 0) + ErrorExit("%s: Unable to connect to %s:%s", ARGV0, manager, port); + + + + // Setting authentication credentials + + ZeroMemory(&auth_cred, sizeof (auth_cred)); + auth_cred.dwVersion = SCHANNEL_CRED_VERSION; + auth_cred.dwSessionLifespan = 60000; + auth_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SERVERNAME_CHECK; + + status = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_cred, NULL, NULL, cred, NULL); + if (status != SEC_E_OK) + ErrorExit("%s: Could not acquire credentials (AcquireCredentialsHandle failed with error code 0x%lX", ARGV0, status); + + + // + // Initialize security context + + OutBuffers[0].pvBuffer = NULL; + OutBuffers[0].BufferType = SECBUFFER_TOKEN; + OutBuffers[0].cbBuffer = 0; + + OutBuffer.cBuffers = 1; + OutBuffer.pBuffers = OutBuffers; + OutBuffer.ulVersion = SECBUFFER_VERSION; + + InBuffers[1].pvBuffer = NULL; + InBuffers[1].cbBuffer = 0; + InBuffers[1].BufferType = SECBUFFER_EMPTY; + + buffer = LocalAlloc(LMEM_FIXED, IO_BUFFER_SIZE); + if (buffer == NULL) + ErrorExit("%s: out of memory !", ARGV0); + + input_flags = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM; + status = InitializeSecurityContext(cred, NULL, NULL, input_flags, 0, 0, NULL, 0, context, &OutBuffer, &output_flags, NULL); + + while (status != SEC_E_OK) + { + // See if we have a token to send to the server + if (status == SEC_I_CONTINUE_NEEDED) + { + SendSecurityToken(*socket, OutBuffers); + total_read = 0; + } + + // See if we have data to retrieve from server + if ((total_read == 0) || (status == SEC_E_INCOMPLETE_MESSAGE)) + { + read = recv(*socket, buffer + total_read, IO_BUFFER_SIZE - total_read, 0); + if (read <= 0) + ErrorExit("%s: Could not get security token from server", ARGV0); + + total_read += read; + } + + InBuffers[0].pvBuffer = buffer; + InBuffers[0].cbBuffer = total_read; + InBuffers[0].BufferType = SECBUFFER_TOKEN; + + InBuffers[1].pvBuffer = NULL; + InBuffers[1].cbBuffer = 0; + InBuffers[1].BufferType = SECBUFFER_EMPTY; + + InBuffer.cBuffers = 2; + InBuffer.pBuffers = InBuffers; + InBuffer.ulVersion = SECBUFFER_VERSION; + + status = InitializeSecurityContext(cred, context, NULL, input_flags, 0, 0, &InBuffer, 0, context, &OutBuffer, &output_flags, NULL); + } + + // Send remaining tokens if any + SendSecurityToken(*socket, OutBuffers); + + printf("INFO: Connected to %s:%s\n", manager, port); + LocalFree(buffer); +} + +void SendSecureMessage(const int socket, CtxtHandle *context, const char *format, ...) +{ + va_list args; + char *buffer; + unsigned int buffer_length = 0; + unsigned int msg_length = 0; + int sent = 0; + SecPkgContext_StreamSizes sizes; + SECURITY_STATUS status; + SecBufferDesc msg; + SecBuffer msg_buffers[4]; + + va_start(args, format); + + // Get sizes for given context + status = QueryContextAttributes(context, SECPKG_ATTR_STREAM_SIZES, &sizes); + if (status != SEC_E_OK) + ErrorExit("%s: Could not get message sizes (QueryContextAttributes failed with error code 0x%lX)", ARGV0, status); + + // Construct message + buffer_length = sizes.cbHeader + sizes.cbMaximumMessage + sizes.cbTrailer; + buffer = LocalAlloc(LMEM_FIXED, buffer_length); + if (buffer == NULL) + ErrorExit("%s: out of memory !", ARGV0); + vsnprintf(buffer + sizes.cbHeader, buffer_length - sizes.cbHeader, format, args); + msg_length = strlen(buffer + sizes.cbHeader); + + // Encrypt message in place + msg_buffers[0].pvBuffer = buffer; + msg_buffers[0].cbBuffer = sizes.cbHeader; + msg_buffers[0].BufferType = SECBUFFER_STREAM_HEADER; + + msg_buffers[1].pvBuffer = buffer + sizes.cbHeader; + msg_buffers[1].cbBuffer = msg_length; + msg_buffers[1].BufferType = SECBUFFER_DATA; + + msg_buffers[2].pvBuffer = buffer + sizes.cbHeader + msg_length; + msg_buffers[2].cbBuffer = sizes.cbTrailer; + msg_buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; + + msg_buffers[3].BufferType = SECBUFFER_EMPTY; + + msg.ulVersion = SECBUFFER_VERSION; + msg.cBuffers = 4; + msg.pBuffers = msg_buffers; + + status = EncryptMessage(context, 0, &msg, 0); + if (status != SEC_E_OK) + ErrorExit("%s: Could not encrypt message (EncryptMessage failed with error code %lX)", ARGV0, status); + + sent = send(socket, buffer, msg_buffers[0].cbBuffer + msg_buffers[1].cbBuffer + msg_buffers[2].cbBuffer, 0); + if (sent <= 0) + ErrorExit("%s: Could not send message to server", ARGV0); + + va_end(args); +} + +char *ReceiveSecureMessage(const int socket, CtxtHandle *context) +{ + char *buffer; + unsigned int buffer_length = 0; + int read = 0; + int i = 0; + char has_extra_data = 0; + SECURITY_STATUS status = SEC_E_INCOMPLETE_MESSAGE; + SecBufferDesc msg; + SecBuffer msg_buffers[4]; + + buffer = LocalAlloc(LMEM_FIXED, IO_BUFFER_SIZE); + + while ((status == SEC_E_INCOMPLETE_MESSAGE) || (has_extra_data)) + { + if (status == SEC_E_INCOMPLETE_MESSAGE) + { + read = recv(socket, buffer + buffer_length, IO_BUFFER_SIZE - buffer_length, 0); + if (read <= 0) + ErrorExit("%s: Could not receive message from server (or invalid password)", ARGV0); + + buffer_length += read; + } + + msg_buffers[0].pvBuffer = buffer; + msg_buffers[0].cbBuffer = buffer_length; + msg_buffers[0].BufferType = SECBUFFER_DATA; + + msg_buffers[1].BufferType = SECBUFFER_EMPTY; + msg_buffers[2].BufferType = SECBUFFER_EMPTY; + msg_buffers[3].BufferType = SECBUFFER_EMPTY; + + msg.ulVersion = SECBUFFER_VERSION; + msg.cBuffers = 4; + msg.pBuffers = msg_buffers; + + status = DecryptMessage(context, &msg, 0, NULL); + + if ((status != SEC_E_OK) && (status != SEC_E_INCOMPLETE_MESSAGE)) + ErrorExit("%s: Could not decrypt received message (DecryptMessage failed with error code 0x%lX)", ARGV0, status); + + if (status == SEC_E_OK) + { + has_extra_data = 0; + for (i = 1; i < 4; ++i) + if (msg_buffers[i].BufferType == SECBUFFER_EXTRA) + { + has_extra_data = 1; + memcpy(buffer, msg_buffers[i].pvBuffer, msg_buffers[i].cbBuffer); + buffer_length = msg_buffers[i].cbBuffer; + } + } + } + + for (i = 1; i < 4; ++i) + if (msg_buffers[i].BufferType == SECBUFFER_DATA) + return msg_buffers[i].pvBuffer; + + return NULL; +} + +void InstallAuthKeys(char *msg) +{ + if (strncmp(msg, "ERROR", 5) == 0) + ErrorExit("%s: %s (from manager)", ARGV0, msg); + else if (strncmp(msg, "openarmor K:'", 9) == 0) + { + char *key; + char *tmpstr; + char **entry; + FILE *fp; + + printf("INFO: Received response with agent key\n"); + + key = msg + 9; + tmpstr = strchr(key, '\''); + + if (!tmpstr) + ErrorExit("%s: Invalid key received. Closing connection.", ARGV0); + + *tmpstr = '\0'; + entry = OS_StrBreak(' ', key, 4); + + if (!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) || + !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3])) + ErrorExit("%s: Invalid key received (2). Closing connection.", ARGV0); + + fp = fopen(KEYSFILE_PATH, "w"); + + if (!fp) + ErrorExit("%s: Unable to open key file: %s", ARGV0, KEYSFILE_PATH); + + fprintf(fp, "%s\n", key); + fclose(fp); + + printf("INFO: Valid key created. Finished.\n"); + } + else + ErrorExit("%s: Unknown message received (%s)", ARGV0, msg); +} + +void DisconnectFromServer(const int socket, CtxtHandle *context, CredHandle *cred) +{ + SecBufferDesc OutBuffer; + SecBuffer OutBuffers[1]; + DWORD dwType; + SECURITY_STATUS status; + DWORD input_flags; + DWORD output_flags; + int sent = 0; + + dwType = SCHANNEL_SHUTDOWN; + + OutBuffers[0].pvBuffer = &dwType; + OutBuffers[0].BufferType = SECBUFFER_TOKEN; + OutBuffers[0].cbBuffer = sizeof(dwType); + + OutBuffer.cBuffers = 1; + OutBuffer.pBuffers = OutBuffers; + OutBuffer.ulVersion = SECBUFFER_VERSION; + + status = ApplyControlToken(context, &OutBuffer); + if (status != SEC_E_OK) + ErrorExit("%s: Could not correclty close connection", ARGV0); + + input_flags = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM; + OutBuffers[0].pvBuffer = NULL; + OutBuffers[0].BufferType = SECBUFFER_TOKEN; + OutBuffers[0].cbBuffer = 0; + + OutBuffer.cBuffers = 1; + OutBuffer.pBuffers = OutBuffers; + OutBuffer.ulVersion = SECBUFFER_VERSION; + + status = InitializeSecurityContext(cred, context, NULL, input_flags, 0, 0, NULL, 0, context, &OutBuffer, &output_flags, NULL); + if (status != SEC_E_OK) + ErrorExit("%s: Could not correclty close connection (2)", ARGV0); + + sent = send(socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer, 0); + if (sent <= 0) + ErrorExit("%s: Could not correclty close connection (3)", ARGV0); + + FreeContextBuffer(OutBuffers[0].pvBuffer); + DeleteSecurityContext(context); + close(socket); +} + +int main(int argc, char **argv) +{ + int error = 0; + int socket = 0; + char *port = "1515"; + char c = 0; + char *manager = NULL; + char *agentname = NULL; + char hostname[512]; + char *msg = NULL; + char *authpass = NULL; + char buf[4096 + 1] = { '\0' }; + WSADATA wsa; + CtxtHandle context; + CredHandle cred; + + /* Setting the name */ + OS_SetName(ARGV0); + + while((c = getopt(argc, argv, "hm:p:A:P:")) != -1) + { + switch(c){ + case 'h': + report_help(); + break; + case 'm': + if(!optarg) + ErrorExit("%s: -%c needs an argument",ARGV0, c); + manager = optarg; + break; + case 'A': + if(!optarg) + ErrorExit("%s: -%c needs an argument",ARGV0, c); + agentname = optarg; + break; + case 'p': { + if(!optarg) + ErrorExit("%s: -%c needs an argument",ARGV0, c); + int tmp_port; + tmp_port = atoi(optarg); + if(tmp_port <= 0 || tmp_port >= 65536) + { + ErrorExit("%s: Invalid port: %s", ARGV0, optarg); + } + port = optarg; + break; + } + case 'P': + if (!optarg) + ErrorExit("%s: -%c needs an argument", ARGV0, c); + + authpass = optarg; + break; + default: + report_help(); + break; + } + } + + // Initialize Windows Networking + error = WSAStartup(MAKEWORD(2, 2), &wsa); + if (error) + ErrorExit("%s: Could not initialize networking (WSAStartup failed with error code %u)", ARGV0, error); + + // Determine agent_name + if(agentname == NULL) + { + if(gethostname(hostname, 512) != 0) + ErrorExit("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0); + + agentname = hostname; + } + + /* Checking if there is a custom password file */ + if (authpass == NULL) { + FILE *fp; + fp = fopen(AUTHDPASS_PATH, "r"); + buf[0] = '\0'; + + if (fp) { + buf[4096] = '\0'; + char *ret = fgets(buf, 4095, fp); + + if (ret && strlen(buf) > 2) { + authpass = buf; + } + + fclose(fp); + printf("INFO: Using password specified on file: %s\n", AUTHDPASS_PATH); + } + } + if (!authpass) { + printf("WARN: No authentication password provided. Insecure mode started.\n"); + + } + + // Connect to socket and init security context + CreateSecureConnection(manager, port, &socket, &context, &cred); + + printf("INFO: Using agent name as: %s\n", agentname); + + // Send request + + if (authpass) + SendSecureMessage(socket, &context, "openarmor PASS: %s openarmor A:'%s'\n", authpass, agentname); + else + SendSecureMessage(socket, &context, "openarmor A:'%s'\n", agentname); + + printf("INFO: Sent request to manager. Waiting for reply.\n"); + + // Get response + msg = ReceiveSecureMessage(socket, &context); + + // Install received keys + InstallAuthKeys(msg); + + // Disconnect + DisconnectFromServer(socket, &context, &cred); + + return (0); +} diff --git a/src/win32/doc.html b/src/win32/doc.html new file mode 100644 index 000000000..d6555b500 --- /dev/null +++ b/src/win32/doc.html @@ -0,0 +1,13 @@ + + + + + + + Redirecting to the online documentation at + http://www.theopenarmor.org/doc/index.html...
+ + diff --git a/src/win32/favicon.ico b/src/win32/favicon.ico new file mode 100644 index 000000000..d7f3a12b0 Binary files /dev/null and b/src/win32/favicon.ico differ diff --git a/src/win32/help.txt b/src/win32/help.txt new file mode 100644 index 000000000..685919fcb --- /dev/null +++ b/src/win32/help.txt @@ -0,0 +1,50 @@ +** openarmor Windows Agent v3.8.0 ** +** Copyright (C) 2014 Trend Micro Inc. ** + + +Thanks for installing the 'openarmor Windows Agent'. Before you continue, +make sure that you have an instance of the openarmor server running and configured +to accept this system as an agent. + +For more information on how to install the server version of openarmor, look at: +http://www.theopenarmor.org/doc/manual/installation/index.html + + + +** Table of contents ** + +1- How to obtain more information +2- What this agent does +3- Questions/Support + + + +** Responses ** + +1- How to obtain more information + +You can obtain more information about openarmor on the following links: +http://www.theopenarmor.org/doc/manual/index.html +http://www.theopenarmor.org/doc/faq/index.html (FAQ) +http://www.theopenarmor.org (openarmor site) + + +2- What this agent does + +The Windows agent does the following tasks: + +-Monitors the Windows event log in real time. +-Monitors IIS logs (Web, FTP, SMTP) and any other logs present on your + system (including Symantec Anti-Virus, MySQL, Apache, etc) in real time. +-Periodically checks the Windows Registry for changes. +-Periodically, or in real-time, checks your Windows folders for changes. +-Periodically does policy verifications to make sure your system is + configured properly. + + +3- Questions/Support + +Visit the following link for information on how to get help or +support for openarmor: + +http://www.theopenarmor.org/main/support/ diff --git a/src/win32/icofile.rc b/src/win32/icofile.rc new file mode 100644 index 000000000..4bd5cec4f --- /dev/null +++ b/src/win32/icofile.rc @@ -0,0 +1 @@ +101 ICON favicon.ico diff --git a/src/win32/nsProcess/nsProcess.nsh b/src/win32/nsProcess/nsProcess.nsh new file mode 100644 index 000000000..c040448a4 --- /dev/null +++ b/src/win32/nsProcess/nsProcess.nsh @@ -0,0 +1,21 @@ +!define nsProcess::FindProcess `!insertmacro nsProcess::FindProcess` + +!macro nsProcess::FindProcess _FILE _ERR + nsProcess::_FindProcess /NOUNLOAD `${_FILE}` + Pop ${_ERR} +!macroend + + +!define nsProcess::KillProcess `!insertmacro nsProcess::KillProcess` + +!macro nsProcess::KillProcess _FILE _ERR + nsProcess::_KillProcess /NOUNLOAD `${_FILE}` + Pop ${_ERR} +!macroend + + +!define nsProcess::Unload `!insertmacro nsProcess::Unload` + +!macro nsProcess::Unload + nsProcess::_Unload +!macroend diff --git a/src/win32/openarmor-installer.nsi b/src/win32/openarmor-installer.nsi new file mode 100644 index 000000000..e7757199b --- /dev/null +++ b/src/win32/openarmor-installer.nsi @@ -0,0 +1,441 @@ +; include Modern UI +!include "MUI.nsh" + +; standard NSIS includes +!include "LogicLib.nsh" +!include "WinVer.nsh" + +; include nsProcess +!addincludedir "nsProcess" +!addplugindir "nsProcess" +!include "nsProcess.nsh" + +; include SimpleSC +!addplugindir "SimpleSC" + +; include GetTime +!include "FileFunc.nsh" +!insertmacro GetTime + +; output file +!ifndef OutFile + !define OutFile "openarmor-win32-agent.exe" +!endif + +; general +!define MUI_ICON favicon.ico +!define MUI_UNICON openarmor-uninstall.ico +!define VERSION "3.8.0" +!define NAME "openarmor HIDS" +!define SERVICE "openarmorSvc" + +Name "${NAME} Windows Agent v${VERSION}" +BrandingText "Copyright (C) 2003 - 2014 Trend Micro Inc." +OutFile "${OutFile}" + +InstallDir "$PROGRAMFILES\openarmor-agent" +InstallDirRegKey HKLM Software\openarmor "" + +; show (un)installation details +ShowInstDetails show +ShowUninstDetails show + +; do not close details pages immediately +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +; interface settings +!define MUI_ABORTWARNING + +; pages +!define MUI_WELCOMEPAGE_TITLE_3LINES +!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the install of ${Name}.\r\n\r\nClick next to continue." +!define MUI_FINISHPAGE_TITLE_3LINES +!define MUI_FINISHPAGE_RUN "$INSTDIR\win32ui.exe" +!define MUI_FINISHPAGE_RUN_TEXT "Run openarmor Agent Manager" + +; page for choosing components +!define MUI_COMPONENTSPAGE_TEXT_TOP "Select the options you want to be executed. Click next to continue." +!define MUI_COMPONENTSPAGE_NODESC + +; pages to display to user +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "LICENSE.txt" +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +; these have to be defined again to work with the uninstall pages +!define MUI_WELCOMEPAGE_TITLE_3LINES +!define MUI_FINISHPAGE_TITLE_3LINES +!insertmacro MUI_UNPAGE_WELCOME +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + +; languages +!insertmacro MUI_LANGUAGE "English" + +; function to stop openarmor service if running +Function .onInit + ; stop service + SimpleSC::ExistsService "${SERVICE}" + Pop $0 + ${If} $0 = 0 + SimpleSC::ServiceIsStopped "${SERVICE}" + Pop $0 + Pop $1 + ${If} $0 = 0 + ${If} $1 <> 1 + MessageBox MB_OKCANCEL "${NAME} is already installed and the ${SERVICE} service is running. \ + It will be stopped before continuing." /SD IDOK IDOK ServiceStop + SetErrorLevel 2 + Abort + + ServiceStop: + SimpleSC::StopService "${SERVICE}" 1 30 + Pop $0 + ${If} $0 <> 0 + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure stopping the ${SERVICE} service ($0).$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ServiceStopped IDRETRY ServiceStop + + SetErrorLevel 2 + Abort + ${EndIf} + ${EndIf} + ${Else} + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure checking status of the ${SERVICE} service ($0).$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ServiceStopped IDRETRY ServiceStop + + SetErrorLevel 2 + Abort + ${EndIf} + ${EndIf} + ServiceStopped: +FunctionEnd + +; main install section +Section "openarmor Agent (required)" MainSec + ; set install type and cwd + SectionIn RO + SetOutPath $INSTDIR + + ; clear any errors + ClearErrors + + ; use real date modified times + SetDateSave off + + ; overwrite existing files + SetOverwrite on + + ; create necessary directories + CreateDirectory "$INSTDIR\bookmarks" + CreateDirectory "$INSTDIR\rids" + CreateDirectory "$INSTDIR\syscheck" + CreateDirectory "$INSTDIR\shared" + CreateDirectory "$INSTDIR\active-response" + CreateDirectory "$INSTDIR\active-response\bin" + CreateDirectory "$INSTDIR\tmp" + + ; install files + ;File openarmor-lua.exe + ;File openarmor-luac.exe + File openarmor-agent.exe + File openarmor-agent-eventchannel.exe + File agent-auth.exe + File default-openarmor.conf + File manage_agents.exe + File /oname=win32ui.exe os_win32ui.exe + File openarmor-rootcheck.exe + File internal_options.conf + File default-local_internal_options.conf + File setup-windows.exe + File setup-syscheck.exe + File setup-iis.exe + File doc.html + File /oname=shared\rootkit_trojans.txt ../rootcheck/db/rootkit_trojans.txt + File /oname=shared\rootkit_files.txt ../rootcheck/db/rootkit_files.txt + File add-localfile.exe + File LICENSE.txt + File /oname=shared\win_applications_rcl.txt ../rootcheck\db\win_applications_rcl.txt + File /oname=shared\win_malware_rcl.txt ../rootcheck\db\win_malware_rcl.txt + File /oname=shared\win_audit_rcl.txt ../rootcheck\db\win_audit_rcl.txt + File help.txt + File vista_sec.txt + File /oname=active-response\bin\route-null.cmd route-null.cmd + File /oname=active-response\bin\restart-openarmor.cmd restart-openarmor.cmd + + ; use appropriate version of "openarmor-agent.exe" + ${If} ${AtLeastWinVista} + Delete "$INSTDIR\openarmor-agent.exe" + Rename "$INSTDIR\openarmor-agent-eventchannel.exe" "$INSTDIR\openarmor-agent.exe" + ${Else} + Delete "$INSTDIR\openarmor-agent-eventchannel.exe" + ${Endif} + + ; write registry keys + WriteRegStr HKLM SOFTWARE\openarmor "Install_Dir" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "DisplayName" "${NAME} ${VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "DisplayVersion" "${VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "DisplayIcon" "${MUI_ICON}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "HelpLink" "http://www.theopenarmor.org/main/support/" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "URLInfoAbout" "http://www.theopenarmor.org" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + + ; get current local time + ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6 + var /global CURRENTTIME + StrCpy $CURRENTTIME "$2-$1-$0 $4:$5:$6" + + ; write version and install information + VersionInstall: + FileOpen $0 "$INSTDIR\VERSION.txt" w + FileWrite $0 "${NAME} v${VERSION} - Installed on $CURRENTTIME" + FileClose $0 + IfErrors VersionError VersionComplete + VersionError: + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure saving version to file.$\r$\n$\r$\n\ + File:$\r$\n$\r$\n$INSTDIR\VERSION.txt$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE VersionComplete IDRETRY VersionInstall + + SetErrorLevel 2 + Abort + VersionComplete: + ClearErrors + + ; create log file + LogInstall: + ClearErrors + IfFileExists "$INSTDIR\openarmor.log" LogComplete + FileOpen $0 "$INSTDIR\openarmor.log" w + FileClose $0 + IfErrors LogError LogComplete + LogError: + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure creating the openarmor.log file.$\r$\n$\r$\n\ + File:$\r$\n$\r$\n$INSTDIR\openarmor.log$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE LogComplete IDRETRY LogInstall + + SetErrorLevel 2 + Abort + LogComplete: + ClearErrors + + ; rename local_internal_options.conf if it does not already exist + ConfInstallInternal: + ClearErrors + IfFileExists "$INSTDIR\local_internal_options.conf" ConfPresentInternal + Rename "$INSTDIR\default-local_internal_options.conf" "$INSTDIR\local_internal_options.conf" + IfErrors ConfErrorInternal ConfPresentInternal + ConfErrorInternal: + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure renaming configuration file.$\r$\n$\r$\n\ + From:$\r$\n$\r$\n\ + $INSTDIR\default-local_internal_options.conf$\r$\n$\r$\n\ + To:$\r$\n$\r$\n\ + $INSTDIR\local_internal_options.conf$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ConfPresentInternal IDRETRY ConfInstallInternal + + SetErrorLevel 2 + Abort + ConfPresentInternal: + ClearErrors + + ; rename openarmor.conf if it does not already exist + ConfInstallopenarmor: + ClearErrors + IfFileExists "$INSTDIR\openarmor.conf" ConfPresentopenarmor + Rename "$INSTDIR\default-openarmor.conf" "$INSTDIR\openarmor.conf" + IfErrors ConfErroropenarmor ConfPresentopenarmor + ConfErroropenarmor: + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure renaming configuration file.$\r$\n$\r$\n\ + From:$\r$\n$\r$\n\ + $INSTDIR\default-openarmor.conf$\r$\n$\r$\n\ + To:$\r$\n$\r$\n\ + $INSTDIR\openarmor.conf$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ConfPresentopenarmor IDRETRY ConfInstallopenarmor + + SetErrorLevel 2 + Abort + ConfPresentopenarmor: + ClearErrors + + ; handle shortcuts + ; http://nsis.sourceforge.net/Shortcuts_removal_fails_on_Windows_Vista + SetShellVarContext all + + ; remove shortcuts + Delete "$SMPROGRAMS\openarmor\Edit.lnk" + Delete "$SMPROGRAMS\openarmor\Uninstall.lnk" + Delete "$SMPROGRAMS\openarmor\Documentation.lnk" + Delete "$SMPROGRAMS\openarmor\Edit Config.lnk" + Delete "$SMPROGRAMS\openarmor\*.*" + RMDir "$SMPROGRAMS\openarmor" + + ; create shortcuts + CreateDirectory "$SMPROGRAMS\openarmor" + CreateShortCut "$SMPROGRAMS\openarmor\Manage Agent.lnk" "$INSTDIR\win32ui.exe" "" "$INSTDIR\win32ui.exe" 0 + CreateShortCut "$SMPROGRAMS\openarmor\Documentation.lnk" "$INSTDIR\doc.html" "" "$INSTDIR\doc.html" 0 + CreateShortCut "$SMPROGRAMS\openarmor\Edit Config.lnk" "$INSTDIR\openarmor.conf" "" "$INSTDIR\openarmor.conf" 0 + CreateShortCut "$SMPROGRAMS\openarmor\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + + ; install openarmor service + ServiceInstall: + nsExec::ExecToLog '"$INSTDIR\openarmor-agent.exe" install-service' + Pop $0 + ${If} $0 <> 1 + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure setting up the ${SERVICE} service.$\r$\n$\r$\n\ + Check the details for information about the error.$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ServiceInstallComplete IDRETRY ServiceInstall + + SetErrorLevel 2 + Abort + ${EndIf} + ServiceInstallComplete: + + ; install files + Setup: + nsExec::ExecToLog '"$INSTDIR\setup-windows.exe" "$INSTDIR"' + Pop $0 + ${If} $0 <> 1 + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure running setup-windows.exe.$\r$\n$\r$\n\ + Check the details for information about the error.$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE SetupComplete IDRETRY Setup + + SetErrorLevel 2 + Abort + ${EndIf} + SetupComplete: +SectionEnd + +; add IIS logs +Section "Scan and monitor IIS logs (recommended)" IISLogs + nsExec::ExecToLog '"$INSTDIR\setup-iis.exe" "$INSTDIR"' +SectionEnd + +; add integrity checking +Section "Enable integrity checking (recommended)" IntChecking + nsExec::ExecToLog '"$INSTDIR\setup-syscheck.exe" "$INSTDIR" "enable"' +SectionEnd + +; uninstall section +Section "Uninstall" + ; uninstall the services + ; this also stops the service as well so it should be done early + ServiceUninstall: + nsExec::ExecToLog '"$INSTDIR\openarmor-agent.exe" uninstall-service' + Pop $0 + ${If} $0 <> 1 + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Failure uninstalling the ${SERVICE} service.$\r$\n$\r$\n\ + Check the details for information about the error.$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ServiceUninstallComplete IDRETRY ServiceUninstall + + SetErrorLevel 2 + Abort + ${EndIf} + ServiceUninstallComplete: + + ; make sure manage_agents.exe is not running + ManageAgents: + ${nsProcess::FindProcess} "manage_agents.exe" $0 + ${If} $0 = 0 + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Found manage_agents.exe is still running.$\r$\n$\r$\n\ + Please close it before continuing.$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE ManageAgentsClosed IDRETRY ManageAgents + + ${nsProcess::Unload} + SetErrorLevel 2 + Abort + ${EndIf} + ManageAgentsClosed: + + ; make sure win32ui.exe is not running + win32ui: + ${nsProcess::FindProcess} "win32ui.exe" $0 + ${If} $0 = 0 + MessageBox MB_ABORTRETRYIGNORE|MB_ICONSTOP "$\r$\n\ + Found win32ui.exe is still running.$\r$\n$\r$\n\ + Please close it before continuing.$\r$\n$\r$\n\ + Click Abort to stop the installation,$\r$\n\ + Retry to try again, or$\r$\n\ + Ignore to skip this file." /SD IDABORT IDIGNORE win32uiClosed IDRETRY win32ui + + ${nsProcess::Unload} + SetErrorLevel 2 + Abort + ${EndIf} + win32uiClosed: + + ; unload nsProcess + ${nsProcess::Unload} + + ; remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\openarmor" + DeleteRegKey HKLM SOFTWARE\openarmor + + ; remove files and uninstaller + Delete "$INSTDIR\openarmor-agent.exe" + ;Delete "$INSTDIR\openarmor-lua.exe" + ;Delete "$INSTDIR\openarmor-luac.exe" + Delete "$INSTDIR\manage_agents.exe" + Delete "$INSTDIR\openarmor.conf" + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\*" + Delete "$INSTDIR\bookmarks\*" + Delete "$INSTDIR\rids\*" + Delete "$INSTDIR\syscheck\*" + Delete "$INSTDIR\shared\*" + Delete "$INSTDIR\active-response\bin\*" + Delete "$INSTDIR\active-response\*" + Delete "$INSTDIR\tmp\*" + Delete "$INSTDIR" + + ; remove shortcuts + SetShellVarContext all + Delete "$SMPROGRAMS\openarmor\*.*" + Delete "$SMPROGRAMS\openarmor\*" + RMDir "$SMPROGRAMS\openarmor" + + ; remove directories used + RMDir "$INSTDIR\shared" + RMDir "$INSTDIR\syscheck" + RMDir "$INSTDIR\bookmarks" + RMDir "$INSTDIR\rids" + RMDir "$INSTDIR\active-response\bin" + RMDir "$INSTDIR\active-response" + RMDir "$INSTDIR\tmp" + RMDir "$INSTDIR" +SectionEnd diff --git a/src/win32/openarmor-uninstall.ico b/src/win32/openarmor-uninstall.ico new file mode 100644 index 000000000..8bd2d18dc Binary files /dev/null and b/src/win32/openarmor-uninstall.ico differ diff --git a/src/win32/openarmor.conf b/src/win32/openarmor.conf new file mode 100644 index 000000000..96a267f3e --- /dev/null +++ b/src/win32/openarmor.conf @@ -0,0 +1,171 @@ + + + + + + + + + Application + eventlog + + + + Security + eventlog + + + + System + eventlog + + + + Windows PowerShell + eventlog + + + + + ./shared/win_audit_rcl.txt + ./shared/win_applications_rcl.txt + ./shared/win_malware_rcl.txt + + + + + + + 72000 + + + yes + + + %WINDIR%/win.ini + %WINDIR%/system.ini + C:\autoexec.bat + C:\config.sys + C:\boot.ini + + %WINDIR%/SysNative/at.exe + %WINDIR%/SysNative/attrib.exe + %WINDIR%/SysNative/cacls.exe + %WINDIR%/SysNative/cmd.exe + %WINDIR%/SysNative/drivers/etc + %WINDIR%/SysNative/eventcreate.exe + %WINDIR%/SysNative/ftp.exe + %WINDIR%/SysNative/lsass.exe + %WINDIR%/SysNative/net.exe + %WINDIR%/SysNative/net1.exe + %WINDIR%/SysNative/netsh.exe + %WINDIR%/SysNative/reg.exe + %WINDIR%/SysNative/regedt32.exe + %WINDIR%/SysNative/regsvr32.exe + %WINDIR%/SysNative/runas.exe + %WINDIR%/SysNative/sc.exe + %WINDIR%/SysNative/schtasks.exe + %WINDIR%/SysNative/sethc.exe + %WINDIR%/SysNative/subst.exe + %WINDIR%/SysNative/wbem/WMIC.exe + %WINDIR%/SysNative/WindowsPowerShell\v1.0\powershell.exe + %WINDIR%/SysNative/winrm.vbs + + %WINDIR%/System32/CONFIG.NT + %WINDIR%/System32/AUTOEXEC.NT + %WINDIR%/System32/at.exe + %WINDIR%/System32/attrib.exe + %WINDIR%/System32/cacls.exe + %WINDIR%/System32/debug.exe + %WINDIR%/System32/drwatson.exe + %WINDIR%/System32/drwtsn32.exe + %WINDIR%/System32/edlin.exe + %WINDIR%/System32/eventcreate.exe + %WINDIR%/System32/eventtriggers.exe + %WINDIR%/System32/ftp.exe + %WINDIR%/System32/net.exe + %WINDIR%/System32/net1.exe + %WINDIR%/System32/netsh.exe + %WINDIR%/System32/rcp.exe + %WINDIR%/System32/reg.exe + %WINDIR%/regedit.exe + %WINDIR%/System32/regedt32.exe + %WINDIR%/System32/regsvr32.exe + %WINDIR%/System32/rexec.exe + %WINDIR%/System32/rsh.exe + %WINDIR%/System32/runas.exe + %WINDIR%/System32/sc.exe + %WINDIR%/System32/subst.exe + %WINDIR%/System32/telnet.exe + %WINDIR%/System32/tftp.exe + %WINDIR%/System32/tlntsvr.exe + %WINDIR%/System32/drivers/etc + %WINDIR%/System32/wbem/WMIC.exe + %WINDIR%/System32/WindowsPowerShell\v1.0\powershell.exe + %WINDIR%/System32/winrm.vbs + + %PROGRAMDATA%/Microsoft/Windows/Start Menu/Programs/Startup + + .log$|.htm$|.jpg$|.png$|.chm$|.pnf$|.evtx$ + + + HKEY_LOCAL_MACHINE\Software\Classes\batfile + HKEY_LOCAL_MACHINE\Software\Classes\cmdfile + HKEY_LOCAL_MACHINE\Software\Classes\comfile + HKEY_LOCAL_MACHINE\Software\Classes\exefile + HKEY_LOCAL_MACHINE\Software\Classes\piffile + HKEY_LOCAL_MACHINE\Software\Classes\AllFilesystemObjects + HKEY_LOCAL_MACHINE\Software\Classes\Directory + HKEY_LOCAL_MACHINE\Software\Classes\Folder + HKEY_LOCAL_MACHINE\Software\Classes\Protocols + HKEY_LOCAL_MACHINE\Software\Policies + HKEY_LOCAL_MACHINE\Security + HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer + + HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services + HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs + HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\winreg + + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\URL + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows + HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon + + HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components + + + HKEY_LOCAL_MACHINE\Security\Policy\Secrets + HKEY_LOCAL_MACHINE\Security\SAM\Domains\Account\Users + \Enum$ + + + + yes + + + + + diff --git a/src/win32/os_win.h b/src/win32/os_win.h new file mode 100644 index 000000000..fa368522b --- /dev/null +++ b/src/win32/os_win.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#ifndef _OS_WIN__H +#define _OS_WIN__H + +/* Install the openarmor-HIDS agent service */ +int InstallService(char *path); + +/* Uninstall the openarmor-HIDS agent service */ +int UninstallService(); + +/* Check if the openarmor-HIDS agent service is running + * Returns 1 on success (running) or 0 if not running + */ +int CheckServiceRunning(); + +/* Start openarmor-HIDS service */ +int os_start_service(); + +/* Stop openarmor-HIDS service */ +int os_stop_service(); + +/* Start the process from the services */ +int os_WinMain(int argc, char **argv); + +/* Locally start the process (after the services initialization) */ +int local_start(); + +#endif diff --git a/src/win32/read-registry.c b/src/win32/read-registry.c new file mode 100644 index 000000000..0949aa48c --- /dev/null +++ b/src/win32/read-registry.c @@ -0,0 +1,189 @@ +#include "shared.h" +#include "os_crypto/md5/md5_op.h" +#include "os_crypto/sha1/sha1_op.h" + +/* Default values */ +#define MAX_KEY_LENGTH 255 +#define MAX_KEY 2048 +#define MAX_VALUE_NAME 16383 + +char *(os_winreg_ignore_list[]) = {"SOFTWARE\\Classes", "test123", NULL}; + +HKEY sub_tree; +void os_winreg_open_key(char *subkey); + + +void os_winreg_querykey(HKEY hKey, char *p_key) +{ + int i, rc; + DWORD j; + + /* QueryInfo and EnumKey variables */ + TCHAR sub_key_name_b[MAX_KEY_LENGTH + 1]; + TCHAR class_name_b[MAX_PATH + 1]; + DWORD sub_key_name_s; + DWORD class_name_s = MAX_PATH; + + /* Number of sub keys */ + DWORD subkey_count = 0; + + /* Number of values */ + DWORD value_count; + + /* Variables for RegEnumValue */ + TCHAR value_buffer[MAX_VALUE_NAME + 1]; + TCHAR data_buffer[MAX_VALUE_NAME + 1]; + DWORD value_size; + DWORD data_size; + + /* Data type for RegEnumValue */ + DWORD data_type = 0; + + /* Initialize the memory for some variables */ + class_name_b[0] = '\0'; + class_name_b[MAX_PATH] = '\0'; + sub_key_name_b[0] = '\0'; + sub_key_name_b[MAX_KEY_LENGTH] = '\0'; + + /* We only use the class_name, subkey_count and value count */ + rc = RegQueryInfoKey(hKey, class_name_b, &class_name_s, NULL, + &subkey_count, NULL, NULL, &value_count, + NULL, NULL, NULL, NULL); + + /* Check return code of QueryInfo */ + if (rc != ERROR_SUCCESS) { + return; + } + + /* Check if we have sub keys */ + if (subkey_count) { + /* Open each subkey and call open_key */ + for (i = 0; i < subkey_count; i++) { + sub_key_name_s = MAX_KEY_LENGTH; + rc = RegEnumKeyEx(hKey, i, sub_key_name_b, &sub_key_name_s, + NULL, NULL, NULL, NULL); + + /* Check for the rc */ + if (rc == ERROR_SUCCESS) { + char new_key[MAX_KEY_LENGTH + 2]; + new_key[MAX_KEY_LENGTH + 1] = '\0'; + + if (p_key) { + snprintf(new_key, MAX_KEY_LENGTH, + "%s\\%s", p_key, sub_key_name_b); + } else { + snprintf(new_key, MAX_KEY_LENGTH, "%s", sub_key_name_b); + } + + /* Open subkey */ + os_winreg_open_key(new_key); + } + } + } + + /* Get Values (if available) */ + if (value_count) { + /* MD5 and SHA-1 */ + os_md5 mf_sum; + os_sha1 sf_sum; + + /* Clear the values for value_size and data_size */ + value_buffer[MAX_VALUE_NAME] = '\0'; + data_buffer[MAX_VALUE_NAME] = '\0'; + + for (i = 0; i < value_count; i++) { + value_size = MAX_VALUE_NAME; + data_size = MAX_VALUE_NAME; + + value_buffer[0] = '\0'; + data_buffer[0] = '\0'; + + rc = RegEnumValue(hKey, i, value_buffer, &value_size, + NULL, &data_type, data_buffer, &data_size); + + /* No more values available */ + if (rc != ERROR_SUCCESS) { + break; + } + + /* Check if no value name is specified */ + if (value_buffer[0] == '\0') { + value_buffer[0] = '@'; + value_buffer[1] = '\0'; + } + printf(" (%d) %s=", i + 1, value_buffer); + switch (data_type) { + case REG_SZ: + case REG_EXPAND_SZ: + printf("%s\n", data_buffer); + break; + case REG_MULTI_SZ: + /* Print multiple strings */ + printf("MULTI_SZ:"); + char *mt_data; + + mt_data = data_buffer; + while (*mt_data) { + printf("%s ", mt_data); + mt_data += strlen(mt_data) + 1; + } + printf("\n"); + break; + case REG_DWORD: + printf("%08x\n", (unsigned int)*data_buffer); + break; + default: + printf("UNSUPPORTED(%d-%d):", (int)data_type, data_size); + for (j = 0; j < data_size; j++) { + printf("%02x", (unsigned int)data_buffer[j]); + } + printf("\n"); + break; + } + } + } +} + +/* Open the registry key */ +void os_winreg_open_key(char *subkey) +{ + int i = 0; + HKEY oshkey; + + /* Registry ignore list */ + if (subkey) { + while (os_winreg_ignore_list[i] != NULL) { + if (strcasecmp(os_winreg_ignore_list[i], subkey) == 0) { + return; + } + i++; + } + } + + if(RegOpenKeyEx(sub_tree, subkey, 0, (KEY_READ | KEY_WOW64_64KEY), &oshkey) != ERROR_SUCCESS) + { + merror(SK_REG_OPEN64, ARGV0, subkey); + return; + } + + if(RegOpenKeyEx(sub_tree, subkey, 0, (KEY_READ | KEY_WOW64_32KEY), &oshkey) != ERROR_SUCCESS) + { + merror(SK_REG_OPEN, ARGV0, subkey); + return; + } + + os_winreg_querykey(oshkey, subkey); + RegCloseKey(sub_tree); +} + +/* Main function to read the registry */ +int main(void) +{ + sub_tree = HKEY_LOCAL_MACHINE; + char *rk = NULL; + + os_winreg_open_key(rk); + + return (0); +} + diff --git a/src/win32/setup-iis.c b/src/win32/setup-iis.c new file mode 100644 index 000000000..355f198d0 --- /dev/null +++ b/src/win32/setup-iis.c @@ -0,0 +1,295 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "os_regex/os_regex.h" + + +#define openarmorCONF "openarmor.conf" +#define OS_MAXSTR 1024 + +int total; + + +int direxist(char *dir) +{ + DIR *dp; + + /* Open dir */ + dp = opendir(dir); + if (dp == NULL) { + return (0); + } + + closedir(dp); + return (1); +} + +int fileexist(char *file) +{ + FILE *fp; + + /* Open file */ + fp = fopen(file, "r"); + if (!fp) { + return (0); + } + + fclose(fp); + return (1); +} + +int dogrep(char *file, char *str) +{ + char line[OS_MAXSTR + 1]; + FILE *fp; + + /* Open file */ + fp = fopen(file, "r"); + if (!fp) { + return (0); + } + + /* Clear memory */ + memset(line, '\0', OS_MAXSTR + 1); + + /* Read file and look for str */ + while (fgets(line, OS_MAXSTR, fp) != NULL) { + if (OS_Match(str, line)) { + fclose(fp); + return (1); + } + } + + fclose(fp); + return (0); +} + +/* Get Windows directory */ +static void get_win_dir(char *file, int f_size) +{ + ExpandEnvironmentStrings("%WINDIR%", file, f_size); + + if (!direxist(file)) { + strncpy(file, "C:\\WINDOWS", f_size); + } +} + +int config_dir(char *name, char *dir, char *vfile) +{ + FILE *fp; + + if (!direxist(dir)) { + return (0); + } + + if (dogrep(openarmorCONF, vfile)) { + printf("%s: Log file already configured: '%s'.\n", + name, vfile); + return (1); + } + + printf("%s: IIS directory found, but no valid log.\n", name); + printf("%s: You may have it configured in a format different\n" + " than W3C Extended or you just don't have today's\n" + " log available.\n", name); + printf("%s: http://www.theopenarmor.org/en/manual.html#iis\n\n", name); + + /* Add IIS config */ + fp = fopen(openarmorCONF, "a"); + if (!fp) { + printf("%s: Unable to edit configuration file.\n", name); + return (1); + } + + fprintf(fp, "\r\n" + "\r\n" + "\r\n" + "\r\n" + " \r\n" + " %s\r\n" + " iis\r\n" + " \r\n" + "\r\n\r\n", vfile); + + printf("%s: Action completed.\n", name); + + total++; + fclose(fp); + + return (1); +} + +/* Check if the IIS file is present in the config */ +int config_iis(char *name, char *file, char *vfile) +{ + FILE *fp; + + if (!fileexist(file)) { + return (0); + } + + total++; + + if (dogrep(openarmorCONF, vfile)) { + printf("%s: Log file already configured: '%s'.\n", + name, vfile); + return (1); + } + + printf("%s: Adding IIS log file to be monitored: '%s'.\n", name, vfile); + + /* Add iis config config */ + fp = fopen(openarmorCONF, "a"); + if (!fp) { + printf("%s: Unable to edit configuration file.\n", name); + return (1); + } + + fprintf(fp, "\r\n" + "\r\n" + "\r\n" + "\r\n" + " \r\n" + " %s\r\n" + " iis\r\n" + " \r\n" + "\r\n\r\n", vfile); + + printf("%s: Action completed.\n", name); + fclose(fp); + + return (1); +} + +/* Setup Windows after install */ +int main(int argc, char **argv) +{ + int i = 0; + time_t tm; + struct tm *p; + char win_dir[2048]; + + if (argc >= 2) { + if (chdir(argv[1]) != 0) { + printf("%s: Invalid directory: '%s'.\n", argv[0], argv[1]); + return (0); + } + } + + /* Check if openarmor was installed already */ + if (!fileexist(openarmorCONF)) { + printf("%s: Unable to find openarmor config: '%s'", argv[0], openarmorCONF); + exit(0); + } + + /* Get today's day */ + tm = time(NULL); + p = localtime(&tm); + + total = 0; + + printf("%s: Looking for IIS log files to monitor.\r\n", + argv[0]); + printf("%s: For more information: http://www.theopenarmor.org/en/win.html\r\n", + argv[0]); + printf("\r\n"); + + /* Get Window directory */ + get_win_dir(win_dir, sizeof(win_dir) - 1); + + /* Look for IIS log files */ + while (i <= 254) { + char lfile[OS_MAXSTR + 1]; + char vfile[OS_MAXSTR + 1]; + + i++; + + /* Search for NCSA */ + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\W3SVC%d\\nc%02d%02d%02d.log", + win_dir, i, (p->tm_year + 1900) - 2000, p->tm_mon + 1, p->tm_mday); + snprintf(vfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\W3SVC%d\\nc%%y%%m%%d.log", + win_dir, i); + + /* Try dir-based */ + config_iis(argv[0], lfile, vfile); + + /* Search for W3C extended */ + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\W3SVC%d\\ex%02d%02d%02d.log", + win_dir, i, (p->tm_year + 1900) - 2000, p->tm_mon + 1, p->tm_mday); + + snprintf(vfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\W3SVC%d\\ex%%y%%m%%d.log", + win_dir, i); + + /* Try dir-based */ + if (config_iis(argv[0], lfile, vfile) == 0) { + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\W3SVC%d", win_dir, i); + config_dir(argv[0], lfile, vfile); + } + + /* Search for FTP Extended format */ + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\MSFTPSVC%d\\ex%02d%02d%02d.log", + win_dir, i, (p->tm_year + 1900) - 2000, p->tm_mon + 1, p->tm_mday); + + snprintf(vfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\MSFTPSVC%d\\ex%%y%%m%%d.log", + win_dir, i); + if (config_iis(argv[0], lfile, vfile) == 0) { + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\MSFTPSVC%d", win_dir, i); + config_dir(argv[0], lfile, vfile); + } + + /* Search for IIS SMTP logs */ + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\SMTPSVC%d\\ex%02d%02d%02d.log", + win_dir, i, (p->tm_year + 1900) - 2000, p->tm_mon + 1, p->tm_mday); + + snprintf(vfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\SMTPSVC%d\\ex%%y%%m%%d.log", + win_dir, i); + if (config_iis(argv[0], lfile, vfile) == 0) { + snprintf(lfile, + OS_MAXSTR, + "%s\\System32\\LogFiles\\SMTPSVC%d", win_dir, i); + config_dir(argv[0], lfile, vfile); + } + } + + if (total == 0) { + printf("%s: No IIS log added. Look at the link above for more " + "information.\r\n", argv[0]); + } + + return (0); +} diff --git a/src/win32/setup-shared.c b/src/win32/setup-shared.c new file mode 100644 index 000000000..548f3d918 --- /dev/null +++ b/src/win32/setup-shared.c @@ -0,0 +1,90 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "os_regex/os_regex.h" + +#define openarmorCONF "openarmor.conf" +#define OS_MAXSTR 1024 + + +/* Check if a file exists */ +int fileexist(char *file) +{ + FILE *fp; + + /* Open file */ + fp = fopen(file, "r"); + if (!fp) { + return (0); + } + + fclose(fp); + return (1); +} + +/* Grep for a string in a file */ +int dogrep(char *file, char *str) +{ + char line[OS_MAXSTR + 1]; + FILE *fp; + + /* Open file */ + fp = fopen(file, "r"); + if (!fp) { + return (0); + } + + /* Clear memory */ + memset(line, '\0', OS_MAXSTR + 1); + + /* Read file and look for str */ + while (fgets(line, OS_MAXSTR, fp) != NULL) { + if (OS_Match(str, line)) { + fclose(fp); + return (1); + } + } + + fclose(fp); + return (0); +} + +/* Check if dir exists */ +int direxist(char *dir) +{ + DIR *dp; + + /* Open dir */ + dp = opendir(dir); + if (dp == NULL) { + return (0); + } + + closedir(dp); + return (1); +} + +/* Get Windows main directory */ +void get_win_dir(char *file, int f_size) +{ + ExpandEnvironmentStrings("%WINDIR%", file, f_size); + + if (!direxist(file)) { + strncpy(file, "C:\\WINDOWS", f_size); + } +} diff --git a/src/win32/setup-shared.h b/src/win32/setup-shared.h new file mode 100644 index 000000000..3c9bd15cd --- /dev/null +++ b/src/win32/setup-shared.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "os_regex/os_regex.h" +#include "headers/file_op.h" + +#define openarmorCONF "openarmor.conf" +#define openarmorDEF "default-openarmor.conf" +#define openarmorLAST "openarmor.conf.bak" +#define CLIENTKEYS "client.keys" +#define OS_MAXSTR 1024 + + +/* Check if a file exists */ +int fileexist(char *file); + +/* Grep for a string in a file */ +int dogrep(char *file, char *str); + +/* Check if dir exists */ +int direxist(char *dir); + +/* Get Windows main directory */ +void get_win_dir(char *file, int f_size); diff --git a/src/win32/setup-syscheck.c b/src/win32/setup-syscheck.c new file mode 100644 index 000000000..ca7aa0809 --- /dev/null +++ b/src/win32/setup-syscheck.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "setup-shared.h" +#include "os_xml/os_xml.h" + +#define openarmor_CONFIG_TMP ".tmp.openarmor.conf" + + +/* Enable Syscheck */ +int main(int argc, char **argv) +{ + char *status; + const char *(xml_syscheck_status[]) = {"openarmor_config", "syscheck", "disabled", NULL}; + + if (argc < 3) { + printf("%s: Invalid syntax.\n", argv[0]); + printf("Try: '%s [enable|disable]'\n\n", argv[0]); + return (0); + } + + /* Check for directory */ + if (chdir(argv[1]) != 0) { + printf("%s: Invalid directory: '%s'.\n", argv[0], argv[1]); + return (0); + } + + /* Check if openarmor-HIDS was installed already */ + if (!fileexist(openarmorCONF)) { + printf("%s: openarmor not installed yet. Exiting.\n", argv[0]); + return (0); + } + + /* Check status */ + if (strcmp(argv[2], "enable") == 0) { + status = "no"; + } else { + status = "yes"; + } + + /* Write to the config file */ + if (OS_WriteXML(openarmorCONF, openarmor_CONFIG_TMP, xml_syscheck_status, + "no", status) != 0) { + printf("%s: Error writing to the Config file. Exiting.\n", argv[0]); + return (0); + } + + /* Rename config files */ + unlink(openarmorLAST); + rename(openarmorCONF, openarmorLAST); + rename(openarmor_CONFIG_TMP, openarmorCONF); + + return (0); +} diff --git a/src/win32/setup-win.c b/src/win32/setup-win.c new file mode 100644 index 000000000..ef2c5e1d3 --- /dev/null +++ b/src/win32/setup-win.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +#include "setup-shared.h" + + +/* Set up Windows after installation */ +int main(int argc, char **argv) +{ + /* Set the name */ + OS_SetName(ARGV0); + + if (argc < 2) { + printf("%s: Invalid syntax.\n", argv[0]); + printf("Try: '%s directory'\n\n", argv[0]); + return (0); + } + + /* Try to chdir to the openarmor directory */ + if (chdir(argv[1]) != 0) { + printf("%s: Invalid directory: '%s'.\n", argv[0], argv[1]); + return (0); + } + + /* Configure openarmor for automatic startup */ + system("sc config openarmorSvc start= auto"); + + /* Change permissions */ + checkVista(); + + if (isVista) { + char cmd[OS_MAXSTR + 1]; + + /* Copy some files to outside */ + snprintf(cmd, OS_MAXSTR, "move os_win32ui.exe ../"); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move win32ui.exe ../"); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move uninstall.exe ../"); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move doc.html ../"); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move help.txt ../"); + system(cmd); + + /* Change permissions */ + system("echo y|icacls * /T \"*S-1-5-32-544:F\" "); + + /* Copy them back */ + snprintf(cmd, OS_MAXSTR, "move ..\\os_win32ui.exe ."); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move ..\\win32ui.exe ."); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move ..\\uninstall.exe ."); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move ..\\doc.html ."); + system(cmd); + + snprintf(cmd, OS_MAXSTR, "move ..\\help.txt ."); + system(cmd); + } else { + system("echo y|icacls . /T /G \"*S-1-5-32-544:F\" "); + } + + return (1); +} diff --git a/src/win32/ui/common.c b/src/win32/ui/common.c new file mode 100644 index 000000000..8d0262f55 --- /dev/null +++ b/src/win32/ui/common.c @@ -0,0 +1,515 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include "shared.h" +#include "os_win32ui.h" +#include "../os_win.h" +#include "os_xml/os_xml.h" +#include "os_net/os_net.h" +#include "validate_op.h" + + +/* Generate server info (for the main status) */ +int gen_server_info(HWND hwnd) +{ + memset(ui_server_info, '\0', 2048 + 1); + snprintf(ui_server_info, 2048, + "Agent: %s (%s) - %s\r\n\r\n" + "Status: %s", + config_inst.agentname, + config_inst.agentid, + config_inst.agentip, + config_inst.status); + + /* Initialize top */ + if (config_inst.version) { + SetDlgItemText(hwnd, UI_SERVER_TOP, config_inst.version); + SetDlgItemText(hwnd, UI_SERVER_INFO, ui_server_info); + } + + /* Initialize auth key */ + SetDlgItemText(hwnd, UI_SERVER_AUTH, config_inst.key); + + /* Initialize server IP */ + SetDlgItemText(hwnd, UI_SERVER_TEXT, config_inst.server); + + /* Set status data */ + SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"http://www.theopenarmor.org"); + if (config_inst.install_date) { + SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)config_inst.install_date); + } + + return (0); +} + +/* Read the first line of a specific file --must free after */ +char *cat_file(char *file, FILE *fp2) +{ + FILE *fp; + + if (!fp2) { + fp = fopen(file, "r"); + } else { + fp = fp2; + } + + if (fp) { + char buf[1024 + 1]; + char *ret = NULL; + + buf[1024] = '\0'; + if (fgets(buf, 1024, fp) != NULL) { + ret = strchr(buf, '\n'); + if (ret) { + *ret = '\0'; + } + ret = strchr(buf, '\r'); + if (ret) { + *ret = '\0'; + } + + ret = strdup(buf); + } + + if (!fp2) { + fclose(fp); + } + return (ret); + } + + return (NULL); +} + + +/* Check if a file exists */ +int is_file(char *file) +{ + FILE *fp; + fp = fopen(file, "r"); + if (fp) { + fclose(fp); + return (1); + } + return (0); +} + +/* Clear configuration */ +void config_clear() +{ + if (config_inst.version) { + free(config_inst.version); + } + + if (config_inst.key) { + free(config_inst.key); + } + + if (config_inst.agentid) { + free(config_inst.agentid); + } + + if (config_inst.server) { + free(config_inst.server); + } + + if (config_inst.install_date) { + free(config_inst.install_date); + } + + /* Initialize config instance */ + config_inst.dir = NULL; + config_inst.key = FL_NOKEY; + config_inst.server = strdup(FL_NOSERVER); + config_inst.config = NULL; + + config_inst.agentid = NULL; + config_inst.agentname = NULL; + config_inst.agentip = NULL; + + config_inst.version = NULL; + config_inst.install_date = NULL; + config_inst.status = ST_UNKNOWN; + config_inst.msg_sent = 0; +} + +/* Initialize the config */ +void init_config() +{ + /* Initialize config instance */ + config_inst.dir = NULL; + config_inst.key = FL_NOKEY; + config_inst.server = NULL; + config_inst.config = NULL; + + config_inst.agentid = NULL; + config_inst.agentname = NULL; + config_inst.agentip = NULL; + + config_inst.version = NULL; + config_inst.install_date = NULL; + config_inst.status = ST_UNKNOWN; + config_inst.msg_sent = 0; + config_inst.admin_access = 1; + + /* Check if ui is on the right path and has the proper permissions */ + if (!is_file(CONFIG)) { + if (chdir(DEFDIR)) { + config_inst.admin_access = 0; + } + + if (!is_file(CONFIG)) { + config_inst.admin_access = 0; + } + } +} + +/* Read openarmor config */ +int config_read(__attribute__((unused)) HWND hwnd) +{ + char *tmp_str; + char *delim = " - "; + + /* Clear config */ + config_clear(); + + /* Get openarmor status */ + if (CheckServiceRunning()) { + config_inst.status = ST_RUNNING; + } else { + config_inst.status = ST_STOPPED; + } + + /* Get version/install date */ + config_inst.version = cat_file(VERSION_FILE, NULL); + if (config_inst.version) { + config_inst.install_date = strstr(config_inst.version, delim); + if (config_inst.install_date) { + *config_inst.install_date = '\0'; + config_inst.install_date += strlen(delim); + } + } + + /* Get number of messages sent */ + tmp_str = cat_file(SENDER_FILE, NULL); + if (tmp_str) { + unsigned long int tmp_val = 0; + char *to_free = tmp_str; + + tmp_val = atol(tmp_str); + if (tmp_val) { + config_inst.msg_sent = tmp_val * 9999; + + tmp_str = strchr(tmp_str, ':'); + if (tmp_str) { + tmp_str++; + tmp_val = atol(tmp_str); + config_inst.msg_sent += tmp_val; + } + } + + free(to_free); + } + + /* Get agent ID, name and IP */ + tmp_str = cat_file(AUTH_FILE, NULL); + if (tmp_str) { + /* Get base 64 */ + config_inst.key = encode_base64(strlen(tmp_str), tmp_str); + if (config_inst.key == NULL) { + config_inst.key = FL_NOKEY; + } + + /* Get ID */ + config_inst.agentid = tmp_str; + + tmp_str = strchr(tmp_str, ' '); + if (tmp_str) { + *tmp_str = '\0'; + tmp_str++; + + /* Get name */ + config_inst.agentname = tmp_str; + tmp_str = strchr(tmp_str, ' '); + if (tmp_str) { + *tmp_str = '\0'; + tmp_str++; + + /* Get IP */ + config_inst.agentip = tmp_str; + + tmp_str = strchr(tmp_str, ' '); + if (tmp_str) { + *tmp_str = '\0'; + } + } + } + } + + if (config_inst.agentip == NULL) { + config_inst.agentid = strdup(ST_NOTSET); + config_inst.agentname = strdup("Auth key not imported."); + config_inst.agentip = ST_NOTSET; + + config_inst.status = ST_MISSING_IMPORT; + } + + /* Get server IP */ + if (!get_openarmor_server()) { + if (strcmp(config_inst.status, ST_MISSING_IMPORT) == 0) { + config_inst.status = ST_MISSING_ALL; + } else { + config_inst.status = ST_MISSING_SERVER; + } + } + + return (0); +} + +/* Get openarmor Server IP */ +int get_openarmor_server() +{ + OS_XML xml; + char *str = NULL; + + /* Definitions */ + const char *(xml_serverip[]) = {"openarmor_config", "client", "server-ip", NULL}; + const char *(xml_serverhost[]) = {"openarmor_config", "client", "server-hostname", NULL}; + + /* Read XML */ + if (OS_ReadXML(CONFIG, &xml) < 0) { + return (0); + } + + /* We need to remove the entry for the server */ + if (config_inst.server) { + free(config_inst.server); + config_inst.server = NULL; + } + config_inst.server_type = 0; + + /* Get IP */ + str = OS_GetOneContentforElement(&xml, xml_serverip); + if (str && (OS_IsValidIP(str, NULL) == 1)) { + config_inst.server_type = SERVER_IP_USED; + config_inst.server = str; + + OS_ClearXML(&xml); + return (1); + } + /* If we don't find the IP, try the server hostname */ + else { + if (str) { + free(str); + str = NULL; + } + + str = OS_GetOneContentforElement(&xml, xml_serverhost); + if (str) { + char *s_ip; + s_ip = OS_GetHost(str, 0); + if (s_ip) { + /* Clear the host memory */ + free(s_ip); + + /* Assign the hostname to the server info */ + config_inst.server_type = SERVER_HOST_USED; + config_inst.server = str; + OS_ClearXML(&xml); + return (1); + } + free(str); + } + } + + /* Set up final server name when not available */ + config_inst.server = strdup(FL_NOSERVER); + + OS_ClearXML(&xml); + return (0); +} + +/* Run a cmd.exe command */ +int run_cmd(char *cmd, HWND hwnd) +{ + int result; + int cmdlen; + STARTUPINFO si; + PROCESS_INFORMATION pi; + DWORD exit_code; + + /* Build command */ + cmdlen = strlen(COMSPEC) + 5 + strlen(cmd); + char finalcmd[cmdlen]; + snprintf(finalcmd, cmdlen, "%s /c %s", COMSPEC, cmd); + + /* Log command being run */ + log2file("%s: INFO: Running the following command (%s)", ARGV0, finalcmd); + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + if (!CreateProcess(NULL, finalcmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, + &si, &pi)) { + MessageBox(hwnd, "Unable to run command.", + "Error -- Failure Running Command", MB_OK); + return (0); + } + + /* Wait until process exits */ + WaitForSingleObject(pi.hProcess, INFINITE); + + /* Get exit code from command */ + result = GetExitCodeProcess(pi.hProcess, &exit_code); + + /* Close process and thread */ + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + if (!result) { + MessageBox(hwnd, "Could not determine exit code from command.", + "Error -- Failure Running Command", MB_OK); + + return (0); + } + + return (exit_code); +} + +/* Set openarmor Server IP */ +int set_openarmor_server(char *ip, HWND hwnd) +{ + const char **xml_pt = NULL; + const char *(xml_serverip[]) = {"openarmor_config", "client", "server-ip", NULL}; + const char *(xml_serverhost[]) = {"openarmor_config", "client", "server-hostname", NULL}; + + char config_tmp[] = CONFIG; + char *conf_file = basename_ex(config_tmp); + + char tmp_path[strlen(TMP_DIR) + 1 + strlen(conf_file) + 6 + 1]; + + snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, conf_file); + + /* Verify IP Address */ + if (OS_IsValidIP(ip, NULL) != 1) { + char *s_ip; + s_ip = OS_GetHost(ip, 0); + + if (!s_ip) { + MessageBox(hwnd, "Invalid Server.\r\n" + "It must be the valid address of the " + "openarmor server or the resolvable hostname.", + "Error -- Failure Setting IP", MB_OK); + return (0); + } + config_inst.server_type = SERVER_HOST_USED; + xml_pt = xml_serverhost; + } else { + config_inst.server_type = SERVER_IP_USED; + xml_pt = xml_serverip; + } + + /* Create temporary file */ + if (mkstemp_ex(tmp_path) == -1) { + MessageBox(hwnd, "Could not create temporary file.", + "Error -- Failure Setting IP", MB_OK); + return (0); + } + + /* Read the XML. Print error and line number. */ + if (OS_WriteXML(CONFIG, tmp_path, xml_pt, NULL, ip) != 0) { + MessageBox(hwnd, "Unable to set openarmor Server IP Address.\r\n" + "(Internal error on the XML Write).", + "Error -- Failure Setting IP", MB_OK); + + if (unlink(tmp_path)) { + MessageBox(hwnd, "Could not delete temporary file.", + "Error -- Failure Deleting Temporary File", MB_OK); + } + + return (0); + } + + /* Rename config files */ + if (rename_ex(CONFIG, LASTCONFIG)) { + MessageBox(hwnd, "Unable to backup configuration.", + "Error -- Failure Backing Up Configuration", MB_OK); + + if (unlink(tmp_path)) { + MessageBox(hwnd, "Could not delete temporary file.", + "Error -- Failure Deleting Temporary File", MB_OK); + } + + return (0); + } + + if (rename_ex(tmp_path, CONFIG)) { + MessageBox(hwnd, "Unable rename temporary file.", + "Error -- Failure Renaming Temporary File", MB_OK); + + if (unlink(tmp_path)) { + MessageBox(hwnd, "Could not delete temporary file.", + "Error -- Failure Deleting Temporary File", MB_OK); + } + + return (0); + } + + return (1); +} + +/* Set openarmor Authentication Key */ +int set_openarmor_key(char *key, HWND hwnd) +{ + FILE *fp; + + char auth_file_tmp[] = AUTH_FILE; + char *keys_file = basename_ex(auth_file_tmp); + + char tmp_path[strlen(TMP_DIR) + 1 + strlen(keys_file) + 6 + 1]; + + snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, keys_file); + + /* Create temporary file */ + if (mkstemp_ex(tmp_path) == -1) { + MessageBox(hwnd, "Could not create temporary file.", + "Error -- Failure Setting IP", MB_OK); + return (0); + } + + fp = fopen(tmp_path, "w"); + if (fp) { + fprintf(fp, "%s", key); + fclose(fp); + } else { + MessageBox(hwnd, "Could not open temporary file for write.", + "Error -- Failure Importing Key", MB_OK); + + if (unlink(tmp_path)) { + MessageBox(hwnd, "Could not delete temporary file.", + "Error -- Failure Deleting Temporary File", MB_OK); + } + + return (0); + } + + if (rename_ex(tmp_path, AUTH_FILE)) { + MessageBox(hwnd, "Unable to rename temporary file.", + "Error -- Failure Renaming Temporary File", MB_OK); + + if (unlink(tmp_path)) { + MessageBox(hwnd, "Could not delete temporary file.", + "Error -- Failure Deleting Temporary File", MB_OK); + } + + return (0); + } + + return (1); +} diff --git a/src/win32/ui/favicon.ico b/src/win32/ui/favicon.ico new file mode 100644 index 000000000..d7f3a12b0 Binary files /dev/null and b/src/win32/ui/favicon.ico differ diff --git a/src/win32/ui/os_win32ui.c b/src/win32/ui/os_win32ui.c new file mode 100644 index 000000000..253c7285d --- /dev/null +++ b/src/win32/ui/os_win32ui.c @@ -0,0 +1,407 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include + +#include "os_win32ui.h" +#include +#include "../os_win.h" + + +/* Dialog -- About openarmor */ +BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, + WPARAM wParam, + __attribute__((unused))LPARAM lParam) +{ + switch (Message) { + case WM_CREATE: + case WM_INITDIALOG: + + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case UI_ID_CLOSE: + EndDialog(hwnd, IDOK); + break; + } + break; + + case WM_CLOSE: + EndDialog(hwnd, IDOK); + break; + default: + return FALSE; + } + return TRUE; +} + +/* Main Dialog */ +BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, + __attribute__((unused))LPARAM lParam) +{ + int ret_code = 0; + + + switch (Message) { + case WM_INITDIALOG: { + int statwidths[] = {130, -1}; + HMENU hMenu, hSubMenu; + + UINT menuflags = MF_STRING; + + if (config_inst.admin_access == 0) { + menuflags = MF_STRING | MF_GRAYED; + } + + hMenu = CreateMenu(); + + /* Creating management menu */ + hSubMenu = CreatePopupMenu(); + AppendMenu(hSubMenu, menuflags, UI_MENU_MANAGE_START, "&Start openarmor"); + AppendMenu(hSubMenu, menuflags, UI_MENU_MANAGE_STOP, "&Stop openarmor"); + AppendMenu(hSubMenu, MF_SEPARATOR, UI_MENU_NONE, ""); + AppendMenu(hSubMenu, menuflags, UI_MENU_MANAGE_RESTART, "&Restart"); + AppendMenu(hSubMenu, menuflags, UI_MENU_MANAGE_STATUS, "&Status"); + AppendMenu(hSubMenu, MF_SEPARATOR, UI_MENU_NONE, ""); + AppendMenu(hSubMenu, MF_STRING, UI_MENU_MANAGE_EXIT, "&Exit"); + AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Manage"); + + /* Create view menu */ + hSubMenu = CreatePopupMenu(); + AppendMenu(hSubMenu, MF_STRING, UI_MENU_VIEW_LOGS, "&View Logs"); + AppendMenu(hSubMenu, MF_STRING, UI_MENU_VIEW_CONFIG, "V&iew Config"); + AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&View"); + + hSubMenu = CreatePopupMenu(); + AppendMenu(hSubMenu, MF_STRING, UI_MENU_HELP_ABOUT, "A&bout"); + AppendMenu(hSubMenu, MF_STRING, UI_MENU_HELP_HELP, "Help"); + AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help"); + + + AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); + SetMenu(hwnd, hMenu); + + + hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, + WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, + hwnd, (HMENU)IDC_MAIN_STATUS, + GetModuleHandle(NULL), NULL); + + SendMessage(hStatus, SB_SETPARTS, + sizeof(statwidths) / sizeof(int), + (LPARAM)statwidths); + SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"http://www.theopenarmor.org"); + + + /* Initializing config */ + config_read(hwnd); + gen_server_info(hwnd); + + + /* Setting the icons */ + SendMessage(hwnd, WM_SETICON, ICON_SMALL, + (LPARAM)LoadIcon(GetModuleHandle(NULL), + MAKEINTRESOURCE(IDI_openarmorICON))); + SendMessage(hwnd, WM_SETICON, ICON_BIG, + (LPARAM)LoadIcon(GetModuleHandle(NULL), + MAKEINTRESOURCE(IDI_openarmorICON))); + + if (config_inst.admin_access == 0) { + MessageBox(hwnd, "Admin access required. Some features may not work properly. \n\n" + "**If on Vista (or Server 2008), choose the \"Run as administrator\" option.", + "Admin Access Required", MB_OK); + break; + } + + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + /* In case of SAVE */ + case IDC_ADD: { + int chd = 0; + int len; + + if (config_inst.admin_access == 0) { + MessageBox(hwnd, "Unable to edit configuration. " + "Admin access required.", + "Error Saving.", MB_OK); + break; + } + + /* Get server IP */ + len = GetWindowTextLength(GetDlgItem(hwnd, UI_SERVER_TEXT)); + if (len > 0) { + char *buf; + + /* Allocate buffer */ + buf = (char *)GlobalAlloc(GPTR, len + 1); + if (!buf) { + exit(-1); + } + + GetDlgItemText(hwnd, UI_SERVER_TEXT, buf, len + 1); + + /* If auth key changed, set it */ + if (strcmp(buf, config_inst.server) != 0) { + if (set_openarmor_server(buf, hwnd)) { + chd = 1; + } + } else { + GlobalFree(buf); + } + } + + /* Get auth key */ + len = GetWindowTextLength(GetDlgItem(hwnd, UI_SERVER_AUTH)); + if (len > 0) { + char *buf; + + /* Allocate buffer */ + buf = (char *)GlobalAlloc(GPTR, len + 1); + if (!buf) { + exit(-1); + } + + GetDlgItemText(hwnd, UI_SERVER_AUTH, buf, len + 1); + + /* If auth key changed, set it */ + if (strcmp(buf, config_inst.key) != 0) { + int ret; + char *tmp_str; + char *decd_buf = NULL; + char *decd_to_write = NULL; + char *id = NULL; + char *name = NULL; + char *ip = NULL; + + /* Get new fields */ + decd_buf = decode_base64(buf); + if (decd_buf) { + decd_to_write = strdup(decd_buf); + + /* Get ID, name and IP */ + id = decd_buf; + name = strchr(id, ' '); + if (name) { + *name = '\0'; + name++; + + ip = strchr(name, ' '); + if (ip) { + *ip = '\0'; + ip++; + + tmp_str = strchr(ip, ' '); + if (tmp_str) { + *tmp_str = '\0'; + } + } + } + } + + /* If IP isn't set, it is because we have an invalid + * auth key. + */ + if (!ip) { + MessageBox(hwnd, "Unable to import " + "authentication key because it was invalid.", + "Error -- Failure Saving Auth Key", MB_OK); + } else { + char mbox_msg[1024 + 1]; + mbox_msg[1024] = '\0'; + + snprintf(mbox_msg, 1024, "Adding key for:\r\n\r\n" + "Agent ID: %s\r\n" + "Agent Name: %s\r\n" + "IP Address: %s\r\n", + id, name, ip); + + ret = MessageBox(hwnd, mbox_msg, + "Confirm Importing Key", MB_OKCANCEL); + if (ret == IDOK) { + if (set_openarmor_key(decd_to_write, hwnd)) { + chd += 2; + } + } + } + + /* Free used memory */ + if (decd_buf) { + free(decd_to_write); + free(decd_buf); + } + } else { + GlobalFree(buf); + } + + } /* Finished adding AUTH KEY */ + + /* Re-print messages */ + if (chd) { + config_read(hwnd); + + /* Set status to restart */ + if (strcmp(config_inst.status, ST_RUNNING) == 0) { + config_inst.status = ST_RUNNING_RESTART; + } + + gen_server_info(hwnd); + + if (chd == 1) { + SendMessage(hStatus, SB_SETTEXT, 0, + (LPARAM)"Server IP saved"); + } else if (chd == 2) { + SendMessage(hStatus, SB_SETTEXT, 0, + (LPARAM)"Auth key imported"); + + } else { + SendMessage(hStatus, SB_SETTEXT, 0, + (LPARAM)"Auth key and IP saved"); + + } + } + } + break; + + case UI_MENU_MANAGE_EXIT: + PostMessage(hwnd, WM_CLOSE, 0, 0); + break; + + case UI_MENU_VIEW_LOGS: + _spawnlp( _P_NOWAIT, "notepad", "notepad " openarmorLOGS, NULL ); + break; + case UI_MENU_VIEW_CONFIG: + _spawnlp( _P_NOWAIT, "notepad", "notepad " CONFIG, NULL ); + break; + case UI_MENU_HELP_HELP: + _spawnlp( _P_NOWAIT, "notepad", "notepad " HELPTXT, NULL ); + break; + case UI_MENU_HELP_ABOUT: { + DialogBox(GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc); + } + break; + case IDC_CANCEL: + config_read(hwnd); + gen_server_info(hwnd); + break; + + case UI_MENU_MANAGE_START: + + /* Start openarmor -- must have a valid config before */ + if ((strcmp(config_inst.key, FL_NOKEY) != 0) && + (strcmp(config_inst.server, FL_NOSERVER) != 0)) { + ret_code = os_start_service(); + } else { + ret_code = 0; + } + + if (ret_code == 0) { + MessageBox(hwnd, "Unable to start agent (check config)", + "Error -- Unable to Start Agent", MB_OK); + } else if (ret_code == 1) { + config_read(hwnd); + gen_server_info(hwnd); + + SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Started"); + + MessageBox(hwnd, "Agent started", + "Agent Started", MB_OK); + } else { + MessageBox(hwnd, "Agent already running (try restart)", + "Agent Running", MB_OK); + } + break; + case UI_MENU_MANAGE_STOP: + + /* Stop openarmor */ + ret_code = os_stop_service(); + if (ret_code == 1) { + config_read(hwnd); + gen_server_info(hwnd); + + SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Stopped"); + MessageBox(hwnd, "Agent stopped", + "Agent Stopped", MB_OK); + } else { + MessageBox(hwnd, "Agent already stopped", + "Agent Stopped", MB_OK); + } + break; + case UI_MENU_MANAGE_STATUS: + if (CheckServiceRunning()) { + MessageBox(hwnd, "Agent running", + "Agent Running", MB_OK); + + } else { + MessageBox(hwnd, "Agent stopped", + "Agent Stopped", MB_OK); + } + break; + case UI_MENU_MANAGE_RESTART: + + if ((strcmp(config_inst.key, FL_NOKEY) == 0) || + (strcmp(config_inst.server, FL_NOSERVER) == 0)) { + MessageBox(hwnd, "Unable to restart agent (check config)", + "Error -- Unable to Restart Agent", MB_OK); + break; + + } + + ret_code = os_stop_service(); + + /* Start openarmor */ + ret_code = os_start_service(); + if (ret_code == 0) { + MessageBox(hwnd, "Unable to restart agent (check config)", + "Error -- Unable to Restart Agent", MB_OK); + } else { + config_read(hwnd); + gen_server_info(hwnd); + + SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Restarted"); + MessageBox(hwnd, "Agent restarted", + "Agent Restarted", MB_OK); + } + break; + } + break; + + case WM_CLOSE: + EndDialog(hwnd, 0); + break; + + default: + return FALSE; + } + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance, __attribute__((unused))HINSTANCE hPrevInstance, + __attribute__((unused))LPSTR lpCmdLine, __attribute__((unused))int nCmdShow) +{ + WSADATA wsaData; + + /* Start Winsock -- for name resolution */ + WSAStartup(MAKEWORD(2, 0), &wsaData); + + /* Initialize config */ + init_config(); + + /* Initialize controls */ + InitCommonControls(); + + /* Create main dialogbox */ + DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc); + + return (0); +} diff --git a/src/win32/ui/os_win32ui.exe.manifest b/src/win32/ui/os_win32ui.exe.manifest new file mode 100644 index 000000000..e78defb28 --- /dev/null +++ b/src/win32/ui/os_win32ui.exe.manifest @@ -0,0 +1,15 @@ + + + openarmor win32 Agent UI + + + + + + + + diff --git a/src/win32/ui/os_win32ui.h b/src/win32/ui/os_win32ui.h new file mode 100644 index 000000000..a99b579a4 --- /dev/null +++ b/src/win32/ui/os_win32ui.h @@ -0,0 +1,142 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifndef WIN_32UI_H +#define WIN_32UI_H + +#include +#include +#include +#include +#include + +/* Default values */ +#define CONFIG "openarmor.conf" +#define LASTCONFIG "last-openarmor.conf" +#define VERSION_FILE "VERSION.txt" +#define openarmorLOGS "openarmor.log" +#define HELPTXT "help.txt" +#define SENDER_FILE "rids\\sender_counter" +#define DEFDIR "C:\\Program Files\\openarmor-agent" + +/* Status messages */ +#define ST_RUNNING "Running" +#define ST_RUNNING_RESTART "Running (pending restart)" +#define ST_STOPPED "Stopped" +#define ST_UNKNOWN "Unknown" +#define ST_NOTSET "0" +#define ST_MISSING_IMPORT "Require import of authentication key.\r\n" \ + " - Not Running" +#define ST_MISSING_SERVER "Require openarmor Server IP address.\r\n" \ + " - Not Running" +#define ST_MISSING_ALL "Require import of authentication key.\r\n" \ + " Missing openarmor Server IP address.\r\n" \ + " - Not Running" + +/* Pre-def fields */ +#define FL_NOKEY "" +#define FL_NOSERVER "" +#define SERVER_IP_USED 1 +#define SERVER_HOST_USED 2 + +/* Prototypes */ +char *decode_base64(const char *src); +char *encode_base64(int size, char *src); + +/* Global openarmor config structure */ +typedef struct _openarmor_config { + unsigned short int server_type; + unsigned short int admin_access; + unsigned long int msg_sent; + char *dir; + char *config; + char *key; + char *server; + + char *agentid; + char *agentname; + char *agentip; + + char *version; + char *install_date; + char *status; +} openarmor_config; + + +/** Global variables **/ + +/* Agent status */ +char ui_server_info[2048 + 1]; + +/* Configuration */ +openarmor_config config_inst; + +/* Status bar */ +HWND hStatus; + +/* openarmor icon */ +#define IDI_openarmorICON 201 +#define UI_MANIFEST_ID 202 + +/* User input */ +#define UI_SERVER_TEXT 1501 +#define UI_SERVER_AUTH 1502 +#define UI_SERVER_MSG 1503 +#define UI_SERVER_TOP 1504 +#define UI_SERVER_INFO 1505 +#define UI_ID_CLOSE 1510 + +/* Menu values */ +#define UI_MENU_MANAGE_STOP 1601 +#define UI_MENU_MANAGE_START 1602 +#define UI_MENU_MANAGE_STATUS 1603 +#define UI_MENU_MANAGE_RESTART 1604 +#define UI_MENU_MANAGE_EXIT 1605 +#define UI_MENU_VIEW_LOGS 1606 +#define UI_MENU_VIEW_CONFIG 1607 +#define UI_MENU_HELP_HELP 1608 +#define UI_MENU_HELP_ABOUT 1609 +#define UI_MENU_NONE 1610 + +#define IDD_MAIN 1700 +#define IDC_MAIN_STATUS 1701 +#define IDC_ADD 1702 +#define IDC_CANCEL 1703 +#define IDD_ABOUT 1704 +#define IDC_STATIC -1 + +/** Prototypes **/ + +/* Generate server info */ +int gen_server_info(HWND hwnd); + +char *cat_file(char *file, FILE *fp2); + +int is_file(char *file); + +/* Reads openarmor config */ +int config_read(HWND hwnd); + +/* Initializes the config */ +void init_config(); + +/* Run command using cmd.exe */ +int run_cmd(char *cmd, HWND hwnd); + +/* Set openarmor Server IP */ +int set_openarmor_server(char *ip, HWND hwnd); + +/* Set openarmor Auth Key */ +int set_openarmor_key(char *key, HWND hwnd); + +/* Get openarmor Server IP */ +int get_openarmor_server(); + + +#endif diff --git a/src/win32/ui/win32ui.rc b/src/win32/ui/win32ui.rc new file mode 100644 index 000000000..2dc19e3da --- /dev/null +++ b/src/win32/ui/win32ui.rc @@ -0,0 +1,52 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#include + +#include "os_win32ui.h" + +IDI_openarmorICON ICON "favicon.ico" +UI_MANIFEST_ID RT_MANIFEST "os_win32ui.exe.manifest" + + + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 259, 106 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About openarmor" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "&Close",UI_ID_CLOSE,90,90,50,14 + GROUPBOX " Copyright (C) 2014 Trend Micro Inc.", + IDC_STATIC,7,7,245,82 + CTEXT "This program is a free software; you can redistribute it" \ + " and/or modify it under the terms of the GNU General" \ + " Public License (GPL) version 2 as published by the FSF" \ + " - Free Software Foundation\r\n\r\n" \ + "For more information, visit us online at http://www.theopenarmor.org", + IDC_STATIC,16,18,200,63 +END + + +IDD_MAIN DIALOG DISCARDABLE 0, 0, 212, 156 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "openarmor Agent Manager" +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX " ~openarmor Windows Agent Manager~ ", UI_SERVER_TOP, 7,7, 193, 57 + LTEXT " No Information available.", UI_SERVER_INFO, 16, 22, 150, 40 + + LTEXT "openarmor Server IP: ",IDC_STATIC,7,76,62,8 + EDITTEXT UI_SERVER_TEXT,75,74,105,12,ES_AUTOHSCROLL + + LTEXT "Authentication key: ",IDC_STATIC,7,92,62,8 + EDITTEXT UI_SERVER_AUTH,75,90,105,12,ES_AUTOHSCROLL + + PUSHBUTTON "&Save",IDC_ADD,50,112,50,14 + PUSHBUTTON "&Refresh",IDC_CANCEL,105,112,50,14 +END diff --git a/src/win32/unix2dos.pl b/src/win32/unix2dos.pl new file mode 100644 index 000000000..33a8146a0 --- /dev/null +++ b/src/win32/unix2dos.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +my $file; + +if(@ARGV < 1) +{ + die "$0: \n"; +} + +$file = shift (@ARGV); + +# File +open(FILE,"<$file")|| die "Unable to open file: $file\n"; + +while() +{ + my $line = $_; + + $line =~ s/\n/\r\n/; + print $line; +} diff --git a/src/win32/vista_sec.txt b/src/win32/vista_sec.txt new file mode 100644 index 000000000..dc66ca6b3 --- /dev/null +++ b/src/win32/vista_sec.txt @@ -0,0 +1,355 @@ +4608, Windows is starting up. This event is logged when LSASS.EXE starts and the auditing subsystem is initialized. +4609, Windows is shutting down. All logon sessions will be terminated by this shutdown. +4610, An authentication package has been loaded by the Local Security Authority. This authentication package will be used to authenticate logon attempts. Authentication Package Name: %1 +4611, This logon process will be trusted to submit logon requests. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Logon Process Name: %5 +4612, Internal resources allocated for the queuing of audit messages have been exhausted, leading to the loss of some audits. Number of audit messages discarded: %1 This event is generated when audit queues are filled and events must be discarded. This most commonly occurs when security events are being generated faster than they are being written to disk, or when the auditing system loses connectivity to the event log, such as when the event log service is stopped. +4614, A notification package has been loaded by the Security Account Manager. This package will be notified of any account or password changes. Notification Package Name: %1 +4615, Invalid use of LPC port. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process Information: PID: %7 Name: %8 Invalid Use: %5 LPC Server Port Name: %6 Windows Local Security Authority (LSA) communicates with the Windows kernel using Local Procedure Call (LPC) ports. If you see this event, an application has inadvertently or intentionally accessed this port which is reserved exclusively for LSA's use. The application (process) should be investigated to ensure that it is not attempting to tamper with this communications channel. +4616, The system time was changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process Information: Process ID: %9 Name: %10 Previous Time: %6 %5 New Time: %8 %7 This event is generated when the system time is changed. It is normal for the Windows Time Service, which runs with System privilege, to change the system time on a regular basis. Other system time changes may be indicative of attempts to tamper with the computer. +4618, A monitored security event pattern has occurred. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Alert Information: Computer: %2 Event ID: %1 Number of Events: %7 Duration: %8 This event is generated when Windows is configured to generate alerts in accordance with the Common Criteria Security Audit Analysis requirements (FAU_SAA) and an auditable event pattern occurs. +4621, Administrator recovered system from CrashOnAuditFail. Users who are not administrators will now be allowed to log on. Some auditable activity might not have been recorded. Value of CrashOnAuditFail: %1 This event is logged after a system reboots following CrashOnAuditFail. +4622, A security package has been loaded by the Local Security Authority. Security Package Name: %1 +4624, An account was successfully logged on. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Logon Type: %9 New Logon: Security ID: %5 Account Name: %6 Account Domain: %7 Logon ID: %8 Logon GUID: %13 Process Information: Process ID: %17 Process Name: %18 Network Information: Workstation Name: %12 Source Network Address: %19 Source Port: %20 Detailed Authentication Information: Logon Process: %10 Authentication Package: %11 Transited Services: %14 Package Name (NTLM only): %15 Key Length: %16 This event is generated when a logon session is created. It is generated on the computer that was accessed. +4625, An account failed to log on. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Logon Type: %11 Account For Which Logon Failed: Security ID: %5 Account Name: %6 Account Domain: %7 Failure Information: Failure Reason: %9 Status: %8 Sub Status: %10 Process Information: Caller Process ID: %18 Caller Process Name: %19 Network Information: Workstation Name: %14 Source Network Address: %20 Source Port: %21 Detailed Authentication Information: Logon Process: %12 Authentication Package: %13 Transited Services: %15 Package Name (NTLM only): %16 Key Length: %17 This event is generated when a logon request fails. It is generated on the computer where access was attempted. +4634, An account was logged off. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Logon Type: %5 This event is generated when a logon session is destroyed. It may be positively correlated with a logon event using the Logon ID value. Logon IDs are only unique between reboots on the same computer. +4647, User initiated logoff: Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 This event is generated when a logoff is initiated but the token reference count is not zero and the logon session cannot be destroyed. No further user-initiated activity can occur. This event can be interpreted as a logoff event. +4648, A logon was attempted using explicit credentials. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Logon GUID: %5 Account Whose Credentials Were Used: Account Name: %6 Account Domain: %7 Logon GUID: %8 Target Server: Target Server Name: %9 Additional Information: %10 Process Information: Process ID: %11 Process Name: %12 Network Information: Network Address: %13 Port: %14 This event is generated when a process attempts to log on an account by explicitly specifying that account’s credentials. This most commonly occurs in batch-type configurations such as scheduled tasks, or when using the RUNAS command. +4649, A replay attack was detected. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Credentials Which Were Replayed: Account Name: %5 Account Domain: %6 Process Information: Process ID: %12 Process Name: %13 Network Information: Workstation Name: %10 Detailed Authentication Information: Request Type: %7 Logon Process: %8 Authentication Package: %9 Transited Services: %11 This event indicates that a Kerberos replay attack was detected- a request was received twice with identical information. This condition could be caused by network misconfiguration. +4650, An IPsec Main Mode security association was established. Extended Mode was not enabled. Certificate authentication was not used. Local Endpoint: Principal Name: %1 Network Address: %3 Keying Module Port: %4 Remote Endpoint: Principal Name: %2 Network Address: %5 Keying Module Port: %6 Security Association Information: Lifetime (minutes): %12 Quick Mode Limit: %13 Main Mode SA ID: %17 Cryptographic Information: Cipher Algorithm: %9 Integrity Algorithm: %10 Diffie-Hellman Group: %11 Additional Information: Keying Module Name: %7 Authentication Method: %8 Role: %14 Impersonation State: %15 Main Mode Filter ID: %16 +4651, An IPsec Main Mode security association was established. Extended Mode was not enabled. A certificate was used for authentication. Local Endpoint: Principal Name: %1 Network Address: %9 Keying Module Port: %10 Local Certificate: SHA Thumbprint: %2 Issuing CA: %3 Root CA: %4 Remote Endpoint: Principal Name: %5 Network Address: %11 Keying Module Port: %12 Remote Certificate: SHA thumbprint: %6 Issuing CA: %7 Root CA: %8 Cryptographic Information: Cipher Algorithm: %15 Integrity Algorithm: %16 Diffie-Hellman Group: %17 Security Association Information: Lifetime (minutes): %18 Quick Mode Limit: %19 Main Mode SA ID: %23 Additional Information: Keying Module Name: %13 Authentication Method: %14 Role: %20 Impersonation State: %21 Main Mode Filter ID: %22 +4652, An IPsec Main Mode negotiation failed. Local Endpoint: Principal Name: %1 Network Address: %9 Keying Module Port: %10 Local Certificate: SHA Thumbprint: %2 Issuing CA: %3 Root CA: %4 Remote Endpoint: Principal Name: %5 Network Address: %11 Keying Module Port: %12 Remote Certificate: SHA thumbprint: %6 Issuing CA: %7 Root CA: %8 Additional Information: Keying Module Name: %13 Authentication Method: %16 Role: %18 Impersonation State: %19 Main Mode Filter ID: %20 Failure Information: Failure Point: %14 Failure Reason: %15 State: %17 Initiator Cookie: %21 Responder Cookie: %22 +4653, An IPsec Main Mode negotiation failed. Local Endpoint: Local Principal Name: %1 Network Address: %3 Keying Module Port: %4 Remote Endpoint: Principal Name: %2 Network Address: %5 Keying Module Port: %6 Additional Information: Keying Module Name: %7 Authentication Method: %10 Role: %12 Impersonation State: %13 Main Mode Filter ID: %14 Failure Information: Failure Point: %8 Failure Reason: %9 State: %11 Initiator Cookie: %15 Responder Cookie: %16 +4654, An IPsec Quick Mode negotiation failed. Local Endpoint: Network Address: %1 Network Address mask: %2 Port: %3 Tunnel Endpoint: %4 Remote Endpoint: Network Address: %5 Address Mask: %6 Port: %7 Tunnel Endpoint: %8 Private Address: %10 Additional Information: Protocol: %9 Keying Module Name: %11 Mode: %14 Role: %16 Quick Mode Filter ID: %18 Main Mode SA ID: %19 Failure Information: State: %15 Message ID: %17 Failure Point: %12 Failure Reason: %13 +4655, An IPsec Main Mode security association ended. Local Network Address: %1 Remote Network Address: %2 Keying Module Name: %3 Main Mode SA ID: %4 +4656, A handle to an object was requested. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %8 Process Information: Process ID: %14 Process Name: %15 Access Request Information: Transaction ID: %9 Accesses: %10 Access Mask: %11 Privileges Used for Access Check: %12 Restricted SID Count: %13 +4657, A registry value was modified. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Name: %5 Object Value Name: %6 Handle ID: %7 Operation Type: %8 Process Information: Process ID: %13 Process Name: %14 Change Information: Old Value Type: %9 Old Value: %10 New Value Type: %11 New Value: %12 +4658, The handle to an object was closed. Subject : Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Handle ID: %6 Process Information: Process ID: %7 Process Name: %8 +4659, A handle to an object was requested with intent to delete. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %8 Process Information: Process ID: %13 Access Request Information: Transaction ID: %9 Accesses: %10 Access Mask: %11 Privileges Used for Access Check: %12 +4660, An object was deleted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Handle ID: %6 Process Information: Process ID: %7 Process Name: %8 Transaction ID: %9 +4661, A handle to an object was requested. Subject : Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %8 Process Information: Process ID: %15 Process Name: %16 Access Request Information: Transaction ID: %9 Accesses: %10 Access Mask: %11 Privileges Used for Access Check: %12 Properties: %13 Restricted SID Count: %14 +4662, An operation was performed on an object. Subject : Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %9 Operation: Operation Type: %8 Accesses: %10 Access Mask: %11 Properties: %12 Additional Information: Parameter 1: %13 Parameter 2: %14 +4663, An attempt was made to access an object. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %8 Process Information: Process ID: %11 Process Name: %12 Access Request Information: Accesses: %9 Access Mask: %10 +4664, An attempt was made to create a hard link. Subject: Account Name: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Link Information: File Name: %5 Link Name: %6 Transaction ID: %7 +4665, An attempt was made to create an application client context. Subject: Client Name: %3 Client Domain: %4 Client Context ID: %5 Application Information: Application Name: %1 Application Instance ID: %2 Status: %6 +4666, An application attempted an operation: Subject: Client Name: %5 Client Domain: %6 Client Context ID: %7 Object: Object Name: %3 Scope Names: %4 Application Information: Application Name: %1 Application Instance ID: %2 Access Request Information: Role: %8 Groups: %9 Operation Name: %10 (%11) +4667, An application client context was deleted. Subject: Client Name: %3 Client Domain: %4 Client Context ID: %5 Application Information: Application Name: %1 Application Instance ID: %2 +4668, An application was initialized. Subject: Client Name: %3 Client Domain: %4 Client ID: %5 Application Information: Application Name: %1 Application Instance ID: %2 Additional Information: Policy Store URL: %6 +4670, Permissions on an object were changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %8 Process: Process ID: %11 Process Name: %12 Permissions Change: Original Security Descriptor: %9 New Security Descriptor: %10 +4671, An application attempted to access a blocked ordinal through the TBS. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Ordinal: %5 +4672, Special privileges assigned to new logon. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Privileges: %5 +4673, A privileged service was called. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Service: Server: %5 Service Name: %6 Process: Process ID: %8 Process Name: %9 Service Request Information: Privileges: %7 +4674, An operation was attempted on a privileged object. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Object Handle: %8 Process Information: Process ID: %11 Process Name: %12 Requested Operation: Desired Access: %9 Privileges: %10 +4675, SIDs were filtered. Target Account: Security ID: %1 Account Name: %2 Account Domain: %3 Trust Information: Trust Direction: %4 Trust Attributes: %5 Trust Type: %6 TDO Domain SID: %7 Filtered SIDs: %8 +4688, A new process has been created. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process Information: New Process ID: %5 New Process Name: %6 Token Elevation Type: %7 Creator Process ID: %8 +4689, A process has exited. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process Information: Process ID: %6 Process Name: %7 Exit Status: %5 +4690, An attempt was made to duplicate a handle to an object. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Source Handle Information: Source Handle ID: %5 Source Process ID: %6 New Handle Information: Target Handle ID: %7 Target Process ID: %8 +4691, Indirect access to an object was requested. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Type: %5 Object Name: %6 Process Information: Process ID: %9 Access Request Information: Accesses: %7 Access Mask: %8 +4692, Backup of data protection master key was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Key Information: Key Identifier: %5 Recovery Server: %6 Recovery Key ID: %7 Status Information: Status Code: %8 +4693, Recovery of data protection master key was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Key Information: Key Identifier: %5 Recovery Server: %6 Recovery Key ID: %8 Recovery Reason: %7 Status Information: Status Code: %9 +4694, Protection of auditable protected data was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Protected Data: Data Description: %6 Key Identifier: %5 Protected Data Flags: %7 Protection Algorithms: %8 Status Information: Status Code: %9 +4695, Unprotection of auditable protected data was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Protected Data: Data Description: %6 Key Identifier: %5 Protected Data Flags: %7 Protection Algorithms: %8 Status Information: Status Code: %9 +4696, A primary token was assigned to process. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process Information: Process ID: %11 Process Name: %12 Target Process: Target Process ID: %9 Target Process Name: %10 New Token Information: Security ID: %5 Account Name: %6 Account Domain: %7 Logon ID: %8 +4697, A service was installed in the system. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Service Information: Service Name: %5 Service File Name: %6 Service Type: %7 Service Start Type: %8 Service Account: %9 +4698, A scheduled task was created. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Task Information: Task Name: %5 Task Content: %6 +4699, A scheduled task was deleted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Task Information: Task Name: %5 Task Content: %6 +4700, A scheduled task was enabled. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Task Information: Task Name: %5 Task Content: %6 +4701, A scheduled task was disabled. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Task Information: Task Name: %5 Task Content: %6 +4702, A scheduled task was updated. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Task Information: Task Name: %5 Task New Content: %6 +4704, A user right was assigned. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Target Account: Account Name: %5 New Right: User Right: %6 +4705, A user right was removed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Target Account: Account Name: %5 Removed Right: User Right: %6 +4706, A new trust was created to a domain. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Trusted Domain: Domain Name: %1 Domain ID: %2 Trust Information: Trust Type: %7 Trust Direction: %8 Trust Attributes: %9 SID Filtering: %10 +4707, A trust to a domain was removed. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Domain Information: Domain Name: %1 Domain ID: %2 +4709, IPsec Services was started. %1 Policy Source: %2 %3 +4710, IPsec Services was disabled. %1 %2 +4712, IPsec Services encountered a potentially serious failure.%1 +4713, Kerberos policy was changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Changes Made: ('--' means no changes, otherwise each change is shown as: (Parameter Name): (new value) (old value)) %5 +4714, Encrypted data recovery policy was changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Changes Made: ('--' means no changes, otherwise each change is shown as: (Parameter Name): (new value) (old value)) %5 +4715, The audit policy (SACL) on an object was changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Audit Policy Change: Original Security Descriptor: %5 New Security Descriptor: %6 +4716, Trusted domain information was modified. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Trusted Domain: Domain Name: %5 Domain ID: %6 New Trust Information: Trust Type: %7 Trust Direction: %8 Trust Attributes: %9 SID Filtering: %10 +4717, System security access was granted to an account. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Account Modified: Account Name: %5 Access Granted: Access Right: %6 +4718, System security access was removed from an account. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Account Modified: Account Name: %5 Access Removed: Access Right: %6 +4719, System audit policy was changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Audit Policy Change: Category: %5 Subcategory: %6 Subcategory GUID: %7 Changes: %8 +4720, A user account was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 New Account: Security ID: %3 Account Name: %1 Account Domain: %2 Attributes: SAM Account Name: %9 Display Name: %10 User Principal Name: %11 Home Directory: %12 Home Drive: %13 Script Path: %14 Profile Path: %15 User Workstations: %16 Password Last Set: %17 Account Expires: %18 Primary Group ID: %19 Allowed To Delegate To: %20 Old UAC Value: %21 New UAC Value: %22 User Account Control: %23 User Parameters: %24 SID History: %25 Logon Hours: %26 Additional Information: Privileges %8 +4722, A user account was enabled. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 +4723, An attempt was made to change an account's password. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 Additional Information: Privileges %8 +4724, An attempt was made to reset an account's password. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 +4725, A user account was disabled. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 +4726, A user account was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 Additional Information: Privileges %8 +4727, A security-enabled global group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 New Group: Security ID: %3 Group Name: %1 Group Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4728, A member was added to a security-enabled global group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4729, A member was removed from a security-enabled global group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4730, A security-enabled global group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Deleted Group: Security ID: %3 Group Name: %1 Group Domain: %2 Additional Information: Privileges: %8 +4731, A security-enabled local group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 New Group: Security ID: %3 Group Name: %1 Group Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4732, A member was added to a security-enabled local group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4733, A member was removed from a security-enabled local group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4734, A security-enabled local group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Additional Information: Privileges: %8 +4735, A security-enabled local group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Changed Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4737, A security-enabled global group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Changed Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4738, A user account was changed. Subject: Security ID: %5 Account Name: %6 Account Domain: %7 Logon ID: %8 Target Account: Security ID: %4 Account Name: %2 Account Domain: %3 Changed Attributes: SAM Account Name: %10 Display Name: %11 User Principal Name: %12 Home Directory: %13 Home Drive: %14 Script Path: %15 Profile Path: %16 User Workstations: %17 Password Last Set: %18 Account Expires: %19 Primary Group ID: %20 AllowedToDelegateTo: %21 Old UAC Value: %22 New UAC Value: %23 User Account Control: %24 User Parameters: %25 SID History: %26 Logon Hours: %27 Additional Information: Privileges: %9 +4739, Domain Policy was changed. Change Type: %1 modified Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Domain: Domain Name: %2 Domain ID: %3 Changed Attributes: Min. Password Age: %9 Max. Password Age: %10 Force Logoff: %11 Lockout Threshold: %12 Lockout Observation Window: %13 Lockout Duration: %14 Password Properties: %15 Min. Password Length: %16 Password History Length: %17 Machine Account Quota: %18 Mixed Domain Mode: %19 Domain Behavior Version: %20 OEM Information: %21 Additional Information: Privileges: %8 +4740, 0x8000000000000000 message: A user account was locked out. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Account That Was Locked Out: Security ID: %3 Account Name: %1 Additional Information: Caller Computer Name: %2 +4741, A computer account was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 New Computer Account: Security ID: %3 Account Name: %1 Account Domain: %2 Attributes: SAM Account Name: %9 Display Name: %10 User Principal Name: %11 Home Directory: %12 Home Drive: %13 Script Path: %14 Profile Path: %15 User Workstations: %16 Password Last Set: %17 Account Expires: %18 Primary Group ID: %19 AllowedToDelegateTo: %20 Old UAC Value: %21 New UAC Value: %22 User Account Control: %23 User Parameters: %24 SID History: %25 Logon Hours: %26 DNS Host Name: %27 Service Principal Names: %28 Additional Information: Privileges %8 +4742, A computer account was changed. Subject: Security ID: %5 Account Name: %6 Account Domain: %7 Logon ID: %8 Computer Account That Was Changed: Security ID: %4 Account Name: %2 Account Domain: %3 Changed Attributes: SAM Account Name: %10 Display Name: %11 User Principal Name: %12 Home Directory: %13 Home Drive: %14 Script Path: %15 Profile Path: %16 User Workstations: %17 Password Last Set: %18 Account Expires: %19 Primary Group ID: %20 AllowedToDelegateTo: %21 Old UAC Value: %22 New UAC Value: %23 User Account Control: %24 User Parameters: %25 SID History: %26 Logon Hours: %27 DNS Host Name: %28 Service Principal Names: %29 Additional Information: Privileges: %9 +4743, A computer account was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Computer: Security ID: %3 Account Name: %1 Account Domain: %2 Additional Information: Privileges: %8 +4744, A security-disabled local group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 New Group: Security ID: %3 Group Name: %1 Group Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4745, A security-disabled local group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Changed Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4746, A member was added to a security-disabled local group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4747, A member was removed from a security-disabled local group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4748, A security-disabled local group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Additional Information: Privileges: %8 +4749, A security-disabled global group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4750, A security-disabled global group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Changed Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4751, A member was added to a security-disabled global group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4752, A member was removed from a security-disabled global group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4753, A security-disabled global group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Additional Information: Privileges: %8 +4754, A security-enabled universal group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4755, A security-enabled universal group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Changed Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4756, A member was added to a security-enabled universal group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Account Name: %3 Account Domain: %4 Additional Information: Privileges: %10 +4757, A member was removed from a security-enabled universal group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4758, A security-enabled universal group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Additional Information: Privileges: %8 +4759, A security-disabled universal group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4760, A security-disabled universal group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Changed Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4761, A member was added to a security-disabled universal group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4762, A member was removed from a security-disabled universal group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4763, A security-disabled universal group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Group Name: %1 Group Domain: %2 Additional Information: Privileges: %8 +4764, A group’s type was changed. Subject: Security ID: %5 Account Name: %6 Account Domain: %7 Logon ID: %8 Change Type: %1 Group: Security ID: %4 Group Name: %2 Group Domain: %3 Additional Information: Privileges: %9 +4765, SID History was added to an account. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Target Account: Security ID: %5 Account Name: %3 Account Domain: %4 Source Account: Security ID: %2 Account Name: %1 Additional Information: Privileges: %10 SID List: %11 +4766, An attempt to add SID History to an account failed. Subject: Security ID: Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %4 Account Name: %2 Account Domain: %3 Source Account Account Name: %1 Additional Information: Privileges: %8 +4767, A user account was unlocked. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 +4768, A Kerberos authentication ticket (TGT) was requested. Account Information: Account Name: %1 Supplied Realm Name: %2 User ID: %3 Service Information: Service Name: %4 Service ID: %5 Network Information: Client Address: %10 Client Port: %11 Additional Information: Ticket Options: %6 Result Code: %7 Ticket Encryption Type: %8 Pre-Authentication Type: %9 Certificate Information: Certificate Issuer Name: %12 Certificate Serial Number: %13 Certificate Thumbprint: %14 Certificate information is only provided if a certificate was used for pre-authentication. Pre-authentication types, ticket options, encryption types and result codes are defined in RFC 4120. +4769, A Kerberos service ticket was requested. Account Information: Account Name: %1 Account Domain: %2 Logon GUID: %10 Service Information: Service Name: %3 Service ID: %4 Network Information: Client Address: %7 Client Port: %8 Additional Information: Ticket Options: %5 Ticket Encryption Type: %6 Failure Code: %9 Transited Services: %11 This event is generated every time access is requested to a resource such as a computer or a Windows service. The service name indicates the resource to which access was requested. +4770, A Kerberos service ticket was renewed. Account Information: Account Name: %1 Account Domain: %2 Service Information: Service Name: %3 Service ID: %4 Network Information: Client Address: %7 Client Port: %8 Additional Information: Ticket Options: %5 Ticket Encryption Type: %6 Ticket options and encryption types are defined in RFC 4120. +4771, Kerberos pre-authentication failed. Account Information: Security ID: %2 Account Name: %1 Service Information: Service Name: %3 Network Information: Client Address: %7 Client Port: %8 Additional Information: Ticket Options: %4 Failure Code: %5 Pre-Authentication Type: %6 Certificate Information: Certificate Issuer Name: %9 Certificate Serial Number: %10 Certificate Thumbprint: %11 Certificate information is only provided if a certificate was used for pre-authentication. Pre-authentication types, ticket options and failure codes are defined in RFC 4120. If the ticket was malformed or damaged during transit and could not be decrypted, then many fields in this event might not be present. +4772, A Kerberos authentication ticket request failed. Account Information: Account Name: %1 Supplied Realm Name: %2 Service Information: Service Name: %3 Network Information: Client Address: %6 Client Port: %7 Additional Information: Ticket Options: %4 Failure Code: %5 Ticket options and failure codes are defined in RFC 4120. +4773, A Kerberos service ticket request failed. Account Information: Account Name: %1 Account Domain: %2 Service Information: Service Name: %3 Network Information: Client Address: %6 Client Port: %7 Additional Information: Ticket Options: %4 Failure Code: %5 Ticket options and failure codes are defined in RFC 4120. +4774, An account was mapped for logon. Authentication Package: %1 Account UPN: %2 Mapped Name: %3 +4775, An account could not be mapped for logon. Authentication Package: %1 Account Name: %2 +4776, The domain controller attempted to validate the credentials for an account. Authentication Package: %1 Logon Account: %2 Source Workstation: %3 Error Code: %4 +4777, The domain controller failed to validate the credentials for an account. Authentication Package: %1 Logon Account: %2 Source Workstation: %3 Error Code: %4 +4778, A session was reconnected to a Window Station. Subject: Account Name: %1 Account Domain: %2 Logon ID: %3 Session: Session Name: %4 Additional Information: Client Name: %5 Client Address: %6 This event is generated when a user reconnects to an existing Terminal Services session, or when a user switches to an existing desktop using Fast User Switching. +4779, A session was disconnected from a Window Station. Subject: Account Name: %1 Account Domain: %2 Logon ID: %3 Session: Session Name: %4 Additional Information: Client Name: %5 Client Address: %6 This event is generated when a user disconnects from an existing Terminal Services session, or when a user switches away from an existing desktop using Fast User Switching. +4780, The ACL was set on accounts which are members of administrators groups. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Target Account: Security ID: %3 Account Name: %1 Account Domain: %2 Additional Information: Privileges: %8 +4781, The name of an account was changed: Subject: Security ID: %5 Account Name: %6 Account Domain: %7 Logon ID: %8 Target Account: Security ID: %4 Account Domain: %3 Old Account Name: %1 New Account Name: %2 Additional Information: Privileges: %9 +4782, The password hash an account was accessed. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Target Account: Account Name: %1 Account Domain: %2 +4783, A basic application group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Account Name: %1 Account Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4784, A basic application group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Account Name: %1 Account Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4785, A member was added to a basic application group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4786, A member was removed from a basic application group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Group Name: %3 Group Domain: %4 Additional Information: Privileges: %10 +4787, A non-member was added to a basic application group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Account Name: %3 Account Domain: %4 Additional Information: Privileges: %10 A non-member is an account that is explicitly excluded from membership in a basic application group. Even if the account is specified as a member of the application group, either explicitly or through nested group membership, the account will not be treated as a group member if it is listed as a non-member. +4788, A non-member was removed from a basic application group. Subject: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Member: Security ID: %2 Account Name: %1 Group: Security ID: %5 Account Name: %3 Account Domain: %4 Additional Information: Privileges: %10 A non-member is an account that is explicitly excluded from membership in a basic application group. Even if the account is specified as a member of the application group, either explicitly or through nested group membership, the account will not be treated as a group member if it is listed as a non-member. +4789, A basic application group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Account Name: %1 Account Domain: %2 Additional Information: Privileges: %8 +4790, An LDAP query group was created. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Account Name: %1 Account Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4791, A basic application group was changed. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Account Name: %1 Account Domain: %2 Attributes: SAM Account Name: %9 SID History: %10 Additional Information: Privileges: %8 +4792, An LDAP query group was deleted. Subject: Security ID: %4 Account Name: %5 Account Domain: %6 Logon ID: %7 Group: Security ID: %3 Account Name: %1 Account Domain: %2 Additional Information: Privileges: %8 +4793, The Password Policy Checking API was called. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Additional Information: Caller Workstation: %5 Provided Account Name (unauthenticated): %6 Status Code: %7 +4794, An attempt was made to set the Directory Services Restore Modeadministrator password. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Additional Information: Caller Workstation: %5 Status Code: %6 +4800, The workstation was locked. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Session ID: %5 +4801, The workstation was unlocked. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Session ID: %5 +4802, The screen saver was invoked. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Session ID: %5 +4803, The screen saver was dismissed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Session ID: %5 +4816, RPC detected an integrity violation while decrypting an incoming message. Peer Name: %1 Protocol Sequence: %2 Security Error: %3 +4864, A namespace collision was detected. Target Type: %1 Target Name: %2 Forest Root: %3 Top Level Name: %4 DNS Name: %5 NetBIOS Name: %6 Security ID: %7 New Flags: %8 +4865, A trusted forest information entry was added. Subject: Security ID: %10 Account Name: %11 Account Domain: %12 Logon ID: %13 Trust Information: Forest Root: %1 Forest Root SID: %2 Operation ID: %3 Entry Type: %4 Flags: %5 Top Level Name: %6 DNS Name: %7 NetBIOS Name: %8 Domain SID: %9 +4866, A trusted forest information entry was removed. Subject: Security ID: %10 Account Name: %11 Account Domain: %12 Logon ID: %13 Trust Information: Forest Root: %1 Forest Root SID: %2 Operation ID: %3 Entry Type: %4 Flags: %5 Top Level Name: %6 DNS Name: %7 NetBIOS Name: %8 Domain SID: %9 +4867, A trusted forest information entry was modified. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Trust Information: Forest Root: %5 Forest Root SID: %6 Operation ID: %7 Entry Type: %8 Flags: %9 Top Level Name: %10 DNS Name: %11 NetBIOS Name: %12 Domain SID: %13 +4868, The certificate manager denied a pending certificate request. Request ID: %1 +4869, Certificate Services received a resubmitted certificate request. Request ID: %1 +4870, Certificate Services revoked a certificate. Serial Number: %1 Reason: %2 +4871, Certificate Services received a request to publish the certificate revocation list (CRL). Next Update: %1 Publish Base: %2 Publish Delta: %3 +4872, Certificate Services published the certificate revocation list (CRL). Base CRL: %1 CRL Number: %2 Key Container: %3 Next Publish: %4 Publish URLs: %5 +4873, A certificate request extension changed. Request ID: %1 Name: %2 Type: %3 Flags: %4 Data: %5 +4874, One or more certificate request attributes changed. Request ID: %1 Attributes: %2 +4875, Certificate Services received a request to shut down +4876, Certificate Services backup started. Backup Type: %1 +4877, Certificate Services backup completed +4878, Certificate Services restore started +4879, Certificate Services restore completed +4880, Certificate Services started. Certificate Database Hash: %1 Private Key Usage Count: %2 CA Certificate Hash: %3 CA Public Key Hash: %4 +4881, Certificate Services stopped. Certificate Database Hash: %1 Private Key Usage Count: %2 CA Certificate Hash: %3 CA Public Key Hash: %4 +4882, The security permissions for Certificate Services changed. %1 +4883, Certificate Services retrieved an archived key. Request ID: %1 +4884, Certificate Services imported a certificate into its database. Certificate: %1 Request ID: %2 +4885, The audit filter for Certificate Services changed. Filter: %1 +4886, Certificate Services received a certificate request. Request ID: %1 Requester: %2 Attributes: %3 +4887, Certificate Services approved a certificate request and issued a certificate. Request ID: %1 Requester: %2 Attributes: %3 Disposition: %4 SKI: %5 Subject: %6 +4888, Certificate Services denied a certificate request. Request ID: %1 Requester: %2 Attributes: %3 Disposition: %4 SKI: %5 Subject: %6 +4889, Certificate Services set the status of a certificate request to pending. Request ID: %1 Requester: %2 Attributes: %3 Disposition: %4 SKI: %5 Subject: %6 +4890, The certificate manager settings for Certificate Services changed. Enable: %1 %2 +4891, A configuration entry changed in Certificate Services. Node: %1 Entry: %2 Value: %3 +4892, A property of Certificate Services changed. Property: %1 Index: %2 Type: %3 Value: %4 +4893, Certificate Services archived a key. Request ID: %1 Requester: %2 KRA Hashes: %3 +4894, Certificate Services imported and archived a key. Request ID: %1 +4895, Certificate Services published the CA certificate to Active Directory Domain Services. Certificate Hash: %1 Valid From: %2 Valid To: %3 +4896, One or more rows have been deleted from the certificate database. Table ID: %1 Filter: %2 Rows Deleted: %3 +4897, Role separation enabled: % +4898, Certificate Services loaded a template. %1 v%2 (Schema V%3) %4 %5 Template Information: Template Content: %7 Security Descriptor: %8 Additional Information: Domain Controller: %6 +4899, A Certificate Services template was updated. %1 v%2 (Schema V%3) %4 %5 Template Change Information: Old Template Content: %8 New Template Content: %7 Additional Information: Domain Controller: %6 +4900, Certificate Services template security was updated. %1 v%2 (Schema V%3) %4 %5 Template Change Information: Old Template Content: %9 New Template Content: %7 Old Security Descriptor: %10 New Security Descriptor: %8 Additional Information: Domain Controller: %6 +4902, The Per-user audit policy table was created. Number of Elements: %1 Policy ID: %2 +4904, An attempt was made to register a security event source. Subject : Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process: Process ID: %7 Process Name: %8 Event Source: Source Name: %5 Event Source ID: %6 +4905, An attempt was made to unregister a security event source. Subject Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Process: Process ID: %7 Process Name: %8 Event Source: Source Name: %5 Event Source ID: %6 +4906, The CrashOnAuditFail value has changed. New Value of CrashOnAuditFail: %1 +4907, Auditing settings on object were changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Object Server: %5 Object Type: %6 Object Name: %7 Handle ID: %8 Process Information: Process ID: %11 Process Name: %12 Auditing Settings: Original Security Descriptor: %9 New Security Descriptor: %10 +4908, Special Groups Logon table modified. Special Groups: %1 This event is generated when the list of special groups is updated in the registry or through security policy. The updated list of special groups is indicated in the event. +4909, The local policy settings for the TBS were changed. Old Blocked Ordinals: %1 New Blocked Ordinals: %2 +4910, The group policy settings for the TBS were changed. Group Policy Setting: Ignore Default Settings Old Value: %1 New Value: %2 Group Policy Setting: Ignore Local Settings Old Value: %3 New Value: %4 Old Blocked Ordinals: %5 New Blocked Ordinals: %6 +4912, Per User Audit Policy was changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Policy For Account: Security ID: %5 Policy Change Details: Category: %6 Subcategory: %7 Subcategory GUID: %8 Changes: %9 +4928, An Active Directory replica source naming context was established. Destination DRA: %1 Source DRA: %2 Source Address: %3 Naming Context: %4 Options: %5 Status Code: %6 +4929, An Active Directory replica source naming context was removed. Destination DRA: %1 Source DRA: %2 Source Address: %3 Naming Context: %4 Options: %5 Status Code: %6 +4930, An Active Directory replica source naming context was modified. Destination DRA: %1 Source DRA: %2 Source Address: %3 Naming Context: %4 Options: %5 Status Code: %6 +4931, An Active Directory replica destination naming context was modified. Destination DRA: %1 Source DRA: %2 Destination Address: %3 Naming Context: %4 Options: %5 Status Code: %6 +4932, Synchronization of a replica of an Active Directory naming context has begun. Destination DRA: %1 Source DRA: %2 Naming Context: %3 Options: %4 Session ID: %5 Start USN: %6 +4933, Synchronization of a replica of an Active Directory naming context has ended. Destination DRA: %1 Source DRA: %2 Naming Context: %3 Options: %4 Session ID: %5 End USN: %6 Status Code: %7 +4934, Attributes of an Active Directory object were replicated. Session ID: %1 Object: %2 Attribute: %3 Type of change: %4 New Value: %5 USN: %6 Status Code: %7 +4935, Replication failure begins. Replication Event: %1 Audit Status Code: %2 +4936, Replication failure ends. Replication Event: %1 Audit Status Code: %2 Replication Status Code: %3 +4937, A lingering object was removed from a replica. Destination DRA: %1 Source DRA: %2 Object: %3 Options: %4 Status Code: %5 +4944, The following policy was active when the Windows Firewall started. Group Policy Applied: %1 Profile Used: %2 Operational mode: %3 Allow Remote Administration: %4 Allow Unicast Responses to Multicast/Broadcast Traffic: %5 Security Logging: Log Dropped Packets: %6 Log Successful Connections: %7 +4945, A rule was listed when the Windows Firewall started. Profile used: %1 Rule: Rule ID: %2 Rule Name: %3 +4946, A change has been made to Windows Firewall exception list. A rule was added. Profile Changed: %1 Added Rule: Rule ID: %2 Rule Name: %3 +4947, A change has been made to Windows Firewall exception list. A rule was modified. Profile Changed: %1 Modified Rule: Rule ID: %2 Rule Name: %3 +4948, A change has been made to Windows Firewall exception list. A rule was deleted. Profile Changed: %1 Deleted Rule: Rule ID: %2 Rule Name: %3 +4949, Windows Firewall settings were restored to the default values +4950, A Windows Firewall setting has changed. Profile That Was Changed: %1 New Setting: Type: %2 Value: %3 +4951, A rule has been ignored because its major version number was not recognized by Windows Firewall. Profile: %1 Ignored Rule: ID: %2 Name: %3 +4952, Parts of a rule have been ignored because its minor version number was not recognized by Windows Firewall. The other parts of the rule will be enforced. Profile: %1 Partially Ignored Rule: ID: %2 Name: %3 +4953, A rule has been ignored by Windows Firewall because it could not parse the rule. Profile: %1 Reason for Rejection: %2 Rule: ID: %3 Name: %4 +4954, Windows Firewall Group Policy settings has changed. The new settings have been applied +4956, Windows Firewall has changed the active profile. New Active Profile: %1 +4957, Windows Firewall did not apply the following rule: Rule Information: ID: %1 Name: %2 Error Information: Reason: %3 resolved to an empty set. +4958, Windows Firewall did not apply the following rule because the rule referred to items not configured on this computer: Rule Information: ID: %1 Name: %2 Error Information: Error: %3 Reason: %4 +4960, IPsec dropped an inbound packet that failed an integrity check. If this problem persists, it could indicate a network issue or that packets are being modified in transit to this computer. Verify that the packets sent from the remote computer are the same as those received by this computer. This error might also indicate interoperability problems with other IPsec implementations. Remote Network Address: %1 Inbound SA SPI: %2 +4961, IPsec dropped an inbound packet that failed a replay check. If this problem persists, it could indicate a replay attack against this computer. Remote Network Address: %1 Inbound SA SPI: %2 +4962, IPsec dropped an inbound packet that failed a replay check. The inbound packet had too low a sequence number to ensure it was not a replay. Remote Network Address: %1 Inbound SA SPI: %2 +4963, IPsec dropped an inbound clear text packet that should have been secured. This is usually due to the remote computer changing its IPsec policy without informing this computer. This could also be a spoofing attack attempt. Remote Network Address: %1 Inbound SA SPI: %2 +4964, Special groups have been assigned to a new logon. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Logon GUID: %5 New Logon: Security ID: %6 Account Name: %7 Account Domain: %8 Logon ID: %9 Logon GUID: %10 Special Groups Assigned: %11 +4965, IPsec received a packet from a remote computer with an incorrect Security Parameter Index (SPI). This is usually caused by malfunctioning hardware that is corrupting packets. If these errors persist, verify that the packets sent from the remote computer are the same as those received by this computer. This error may also indicate interoperability problems with other IPsec implementations. In that case, if connectivity is not impeded, then these events can be ignored. Remote Network Address: %1 Inbound SA SPI: %2 +4976, During Main Mode negotiation, IPsec received an invalid negotiation packet. If this problem persists, it could indicate a network issue or an attempt to modify or replay this negotiation. Local Network Address: %1 Remote Network Address: %2 Keying Module Name: %3 +4977, During Quick Mode negotiation, IPsec received an invalid negotiation packet. If this problem persists, it could indicate a network issue or an attempt to modify or replay this negotiation. Local Network Address: %1 Remote Network Address: %2 Keying Module Name: %3 +4978, During Extended Mode negotiation, IPsec received an invalid negotiation packet. If this problem persists, it could indicate a network issue or an attempt to modify or replay this negotiation. Local Network Address: %1 Remote Network Address: %2 Keying Module Name: %3 +4979, IPsec Main Mode and Extended Mode security associations were established. Main Mode Local Endpoint: Principal Name: %1 Network Address: %3 Keying Module Port: %4 Main Mode Remote Endpoint: Principal Name: %2 Network Address: %5 Keying Module Port: %6 Main Mode Cryptographic Information: Cipher Algorithm: %8 Integrity Algorithm: %9 Diffie-Hellman Group: %10 Main Mode Security Association: Lifetime (minutes): %11 Quick Mode Limit: %12 Main Mode SA ID: %16 Main Mode Additional Information: Keying Module Name: AuthIP Authentication Method: %7 Role: %13 Impersonation State: %14 Main Mode Filter ID: %15 Extended Mode Information: Local Principal Name: %17 Remote Principal Name: %18 Authentication Method: %19 Impersonation State: %20 Quick Mode Filter ID: %21 +4980, IPsec Main Mode and Extended Mode security associations were established. Main Mode Local Endpoint: Principal Name: %1 Network Address: %3 Keying Module Port: %4 Main Mode Remote Endpoint: Principal Name: %2 Network Address: %5 Keying Module Port: %6 Main Mode Cryptographic Information: Cipher Algorithm: %8 Integrity Algorithm: %9 Diffie-Hellman Group: %10 Main Mode Security Association: Lifetime (minutes): %11 Quick Mode Limit: %12 Main Mode SA ID: %16 Main Mode Additional Information: Keying Module Name: AuthIP Authentication Method: %7 Role: %13 Impersonation State: %14 Main Mode Filter ID: %15 Extended Mode Local Endpoint: Principal Name: %17 Certificate SHA Thumbprint: %18 Certificate Issuing CA: %19 Certificate Root CA: %20 Extended Mode Remote Endpoint: Principal Name: %21 Certificate SHA Thumbprint: %22 Certificate Issuing CA: %23 Certificate Root CA: %24 Extended Mode Additional Information: Authentication Method: SSL Impersonation State: %25 Quick Mode Filter ID: %26 +4981, IPsec Main Mode and Extended Mode security associations were established. Local Endpoint: Principal Name: %1 Network Address: %9 Keying Module Port: %10 Local Certificate: SHA Thumbprint: %2 Issuing CA: %3 Root CA: %4 Remote Endpoint: Principal Name: %5 Network Address: %11 Keying Module Port: %12 Remote Certificate: SHA Thumbprint: %6 Issuing CA: %7 Root CA: %8 Cryptographic Information: Cipher Algorithm: %13 Integrity Algorithm: %14 Diffie-Hellman Group: %15 Security Association Information: Lifetime (minutes): %16 Quick Mode Limit: %17 Main Mode SA ID: %21 Additional Information: Keying Module Name: AuthIP Authentication Method: SSL Role: %18 Impersonation State: %19 Main Mode Filter ID: %20 Extended Mode Information: Local Principal Name: %22 Remote Principal Name: %23 Authentication Method: %24 Impersonation State: %25 Quick Mode Filter ID: %26 +4982, IPsec Main Mode and Extended Mode security associations were established. Local Endpoint: Principal Name: %1 Network Address: Keying Module Port: %9 Local Certificate: SHA Thumbprint: %2 Issuing CA: %3 Root CA: %4 Remote Endpoint: Principal Name: %5 Network Address: %11 Keying Module Port: %12 Remote Certificate: SHA Thumbprint: %6 Issuing CA: %7 Root CA: %8 Cryptographic Information: Cipher Algorithm: %12 Integrity Algorithm: %13 Diffie-Hellman Group: %14 Security Association Information: Lifetime (minutes): %15 Quick Mode Limit: %16 Main Mode SA ID: %20 Additional Information: Keying Module Name: AuthIP Authentication Method: SSL Role: %17 Impersonation State: %18 Main Mode Filter ID: %19 Extended Mode Local Endpoint: Principal Name: %21 Certificate SHA Thumbprint: %22 Certificate Issuing CA: %23 Certificate Root CA: %24 Extended Mode Remote Endpoint: Principal Name: %25 Certificate SHA Thumbprint: %26 Certificate Issuing CA: %27 Certificate Root CA: %28 Extended Mode Additional Information: Authentication Method: SSL Impersonation State: %29 Quick Mode Filter ID: %30 +4983, An IPsec Extended Mode negotiation failed. The corresponding Main Mode security association has been deleted. Local Endpoint: Principal Name: %1 Network Address: %9 Keying Module Port: %10 Local Certificate: SHA Thumbprint: %2 Issuing CA: %3 Root CA: %4 Remote Endpoint: Principal Name: %5 Network Address: %11 Keying Module Port: %12 Remote Certificate: SHA Thumbprint: %6 Issuing CA: %7 Root CA: %8 Additional Information: Keying Module Name: AuthIP Authentication Method: SSL Role: %16 Impersonation State: %17 Quick Mode Filter ID: %18 Failure Information: Failure Point: %13 Failure Reason: %14 State: %15 +4984, An IPsec Extended Mode negotiation failed. The corresponding Main Mode security association has been deleted. Local Endpoint: Principal Name: %1 Network Address: %3 Keying Module Port: %4 Remote Endpoint: Principal Name: %2 Network Address: %5 Keying Module Port: %6 Additional Information: Keying Module Name: AuthIP Authentication Method: %9 Role: %11 Impersonation State: %12 Quick Mode Filter ID: %13 Failure Information: Failure Point: %7 Failure Reason: %8 State: %10 +4985, The state of a transaction has changed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Transaction Information: RM Transaction ID: %5 New State: %6 Resource Manager: %7 Process Information: Process ID: %8 Process Name: %9 +5024, The Windows Firewall Service has started successfully +5025, The Windows Firewall Service has been stopped +5027, The Windows Firewall Service was unable to retrieve the security policy from the local storage. The service will continue enforcing the current policy. Error Code: %1 +5028, The Windows Firewall Service was unable to parse the new security policy. The service will continue with currently enforced policy. Error Code: %1 +5029, The Windows Firewall Service failed to initialize the driver. The service will continue to enforce the current policy. Error Code: %1 +5030, The Windows Firewall Service failed to start. Error Code: %1 +5031, The Windows Firewall Service blocked an application from accepting incoming connections on the network. Profiles: %1 Application: %2 +5032, Windows Firewall was unable to notify the user that it blocked an application from accepting incoming connections on the network. Error Code: %1 +5033, The Windows Firewall Driver has started successfully +5034, The Windows Firewall Driver has been stopped +5035, The Windows Firewall Driver failed to start. Error Code: %1 +5037, The Windows Firewall Driver detected critical runtime error. Terminating. Error Code: %1 +5038, 0x8000000000000000 message: Code integrity determined that the image hash of a file is not valid. The file could be corrupt due to unauthorized modification or the invalid hash could indicate a potential disk device error. File Name: %1 +5039, A registry key was virtualized. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: Key Name: %5 Virtual Key Name: %6 Process Information: Process ID: %7 Process Name: %8 +5040, A change has been made to IPsec settings. An Authentication Set was added. Profile Changed: %1 Added Authentication Set: ID: %2 Name: %3 +5041, A change has been made to IPsec settings. An Authentication Set was modified. Profile Changed: %1 Modified Authentication Set: ID: %2 Name: %3 +5042, A change has been made to IPsec settings. An Authentication Set was deleted. Profile Changed: %1 Deleted Authentication Set: ID: %2 Name: %3 +5043, A change has been made to IPsec settings. A Connection Security Rule was added. Profile Changed: %1 Added Connection Security Rule: ID: %2 Name: %3 +5044, A change has been made to IPsec settings. A Connection Security Rule was modified. Profile Changed: %1 Modified Connection Security Rule: ID: %2 Name: %3 +5045, A change has been made to IPsec settings. A Connection Security Rule was deleted. Profile Changed: %1 Deleted Connection Security Rule: ID: %2 Name: %3 +5046, A change has been made to IPsec settings. A Crypto Set was added. Profile Changed: %1 Added Crypto Set: ID: %2 Name: %3 +5047, A change has been made to IPsec settings. A Crypto Set was modified. Profile Changed: %1 Modified Crypto Set: ID: %2 Name: %3 +5048, A change has been made to IPsec settings. A Crypto Set was deleted. Profile Changed: %1 Deleted Crypto Set: ID: %2 Name: %3 +5049, An IPsec Security Association was deleted. Profile Changed: %1 Deleted SA: ID: %2 Name: %3 +5050, An attempt to programmatically disable the Windows Firewall using a call to INetFwProfile.FirewallEnabled(FALSE) interface was rejected because this API is not supported on Windows Vista. This has most likely occurred due to a program which is incompatible with Windows Vista. Please contact the program's manufacturer to make sure you have a Windows Vista compatible program version. Error Code: E_NOTIMPL Caller Process Name: %1 Process Id: %2 Publisher: %3 +5051, A file was virtualized. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: File Name: %5 Virtual File Name: %6 Process Information: Process ID: %7 Process Name: %8 +5056, A cryptographic self test was performed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Module: %5 Return Code: %6 +5057, A cryptographic primitive operation failed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Cryptographic Parameters: Provider Name: %5 Algorithm Name: %6 Failure Information: Reason: %7 Return Code: %8 +5058, Key file operation. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Cryptographic Parameters: Provider Name: %5 Algorithm Name: %6 Key Name: %7 Key Type: %8 Key File Operation Information: File Path: %9 Operation: %10 Return Code: %11 +5059, Key migration operation. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Cryptographic Parameters: Provider Name: %5 Algorithm Name: %6 Key Name: %7 Key Type: %8 Additional Information: Operation: %9 Return Code: %10 +5060, Verification operation failed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Cryptographic Parameters: Provider Name: %5 Algorithm Name: %6 Key Name: %7 Key Type: %8 Failure Information: Reason: %9 Return Code: %10 +5061, Cryptographic operation. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Cryptographic Parameters: Provider Name: %5 Algorithm Name: %6 Key Name: %7 Key Type: %8 Cryptographic Operation: Operation: %9 Return Code: %10 +5062, A kernel-mode cryptographic self test was performed. Module: %1 Return Code: %2 +5063, A cryptographic provider operation was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Cryptographic Provider: Name: %5 Module: %6 Operation: %7 Return Code: %8 +5064, A cryptographic context operation was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Configuration Parameters: Scope: %5 Context: %6 Operation: %7 Return Code: %8 +5065, A cryptographic context modification was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 %Configuration Parameters: Scope: %5 Context: %6 Change Information: Old Value: %7 New Value: %8 Return Code: %9 +5066, A cryptographic function operation was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Configuration Parameters: Scope: %5 Context: %6 Interface: %7 Function: %8 Position: %9 Operation: %10 Return Code: %11 +5067, A cryptographic function modification was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Configuration Parameters: Scope: %5 Context: %6 Interface: %7 Function: %8 Change Information: Old Value: %9 New Value: %10 Return Code: %11 +5068, A cryptographic function provider operation was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Configuration Parameters: Scope: %5 Context: %6 Interface: %7 Function: %8 Provider: %9 Position: %10 Operation: %11 Return Code: %12 +5069, A cryptographic function property operation was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Configuration Parameters: Scope: %5 Context: %6 Interface: %7 Function: %8 Property: %9 Operation: %10 Value: %11 Return Code: %12 +5070, A cryptographic function property modification was attempted. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Configuration Parameters: Scope: %5 Context: %6 Interface: %7 Function: %8 Property: %9 Change Information: Old Value: %10 New Value: %11 Return Code: %12 +5120, OCSP Responder Service Started +5121, OCSP Responder Service Stopped +5122, A Configuration entry changed in the OCSP Responder Service. CA Configuration ID: %1 New Value: %2 +5123, A configuration entry changed in the OCSP Responder Service. Property Name: %1 New Value: %2 +5124, A security setting was updated on OCSP Responder Service. New Value: %1 +5125, A request was submitted to OCSP Responder Service +5126, Signing Certificate was automatically updated by the OCSP Responder Service. CA Configuration ID: %1 New Signing Certificate Hash: %2 +5127, The OCSP Revocation Provider successfully updated the revocation information. CA Configuration ID: %1 Base CRL Number: %2 Base CRL This Update: %3 Base CRL Hash: %4 Delta CRL Number: %5 Delta CRL Indicator: %6 Delta CRL This Update: %7 Delta CRL Hash: %8 +5136, A directory service object was modified. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Directory Service: Name: %7 Type: %8 Object: DN: %9 GUID: %10 Class: %11 Attribute: LDAP Display Name: %12 Syntax (OID): %13 Value: %14 Operation: Type: %15 Correlation ID: %1 Application Correlation ID: %2 +5137, A directory service object was created. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Directory Service: Name: %7 Type: %8 Object: DN: %9 GUID: %10 Class: %11 Operation: Correlation ID: %1 Application Correlation ID: %2 +5138, A directory service object was undeleted. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Directory Service: Name: %7 Type: %8 Object: Old DN: %9 New DN: %10 GUID: %11 Class: %12 Operation: Correlation ID: %1 Application Correlation ID: %2 +5139, A directory service object was moved. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Directory Service: Name: %7 Type: %8 Object: Old DN: %9 New DN: %10 GUID: %11 Class: %12 Operation: Correlation ID: %1 Application Correlation ID: %2 +5140, A network share object was accessed. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Network Information: Source Address: %5 Source Port: %6 Share Name: %7 +5141, A directory service object was deleted. Subject: Security ID: %3 Account Name: %4 Account Domain: %5 Logon ID: %6 Directory Service: Name: %7 Type: %8 Object: DN: %9 GUID: %10 Class: %11 Operation: Tree Delete: %12 Correlation ID: %1 Application Correlation ID: %2 +5152, The Windows Filtering Platform blocked a packet. Application Information: Process ID: %1 Application Name: %2 Network Information: Direction: %3 Source Address: %4 Source Port: %5 Destination Address: %6 Destination Port: %7 Protocol: %8 Filter Information: Filter Run-Time ID: %9 Layer Name: %10 Layer Run-Time ID: %11 +5153, A more restrictive Windows Filtering Platform filter has blocked a packet. Application Information: Process ID: %1 Application Name: %2 Network Information: Direction: %3 Source Address: %4 Source Port: %5 Destination Address: %6 Destination Port: %7 Protocol: %8 Filter Information: Filter Run-Time ID: %9 Layer Name: %10 Layer Run-Time ID: %11 +5154, The Windows Filtering Platform has permitted an application or service to listen on a port for incoming connections. Application Information: Process ID: %1 Application Name: %2 Network Information: Source Address: %3 Source Port: %4 Protocol: %5 Filter Information: Filter Run-Time ID: %6 Layer Name: %7 Layer Run-Time ID: %8 +5155, The Windows Filtering Platform has blocked an application or service from listening on a port for incoming connections. Application Information: Process ID: %1 Application Name: %2 Network Information: Source Address: %3 Source Port: %4 Protocol: %5 Filter Information: Filter Run-Time ID: %6 Layer Name: %7 Layer Run-Time ID: %8 +5156, The Windows Filtering Platform has allowed a connection. Application Information: Process ID: %1 Application Name: %2 Network Information: Direction: %3 Source Address: %4 Source Port: %5 Destination Address: %6 Destination Port: %7 Protocol: %8 Filter Information: Filter Run-Time ID: %9 Layer Name: %10 Layer Run-Time ID: %11 +5157, The Windows Filtering Platform has blocked a connection. Application Information: Process ID: %1 Application Name: %2 Network Information: Direction: %3 Source Address: %4 Source Port: %5 Destination Address: %6 Destination Port: %7 Protocol: %8 Filter Information: Filter Run-Time ID: %9 Layer Name: %10 Layer Run-Time ID: %11 +5158, The Windows Filtering Platform has permitted a bind to a local port. Application Information: Process ID: %1 Application Name: %2 Network Information: Source Address: %3 Source Port: %4 Protocol: %5 Filter Information: Filter Run-Time ID: %6 Layer Name: %7 Layer Run-Time ID: %8 +5159, The Windows Filtering Platform has blocked a bind to a local port. Application Information: Process ID: %1 Application Name: %2 Network Information: Source Address: %3 Source Port: %4 Protocol: %5 Filter Information: Filter Run-Time ID: %6 Layer Name: %7 Layer Run-Time ID: %8 +5376, Credential Manager credentials were backed up. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 This event occurs when a user backs up their own Credential Manager credentials. A user (even an Administrator) cannot back up the credentials of an account other than his own. +5377, Credential Manager credentials were restored from a backup. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 This event occurs when a user restores his Credential Manager credentials from a backup. A user (even an Administrator) cannot restore the credentials of an account other than his own. +5378, The requested credentials delegation was disallowed by policy. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Credential Delegation Information: Security Package: %5 User's UPN: %6 Target Server: %7 Credential Type: %8 +5440, The following callout was present when the Windows Filtering Platform Base Filtering Engine started. Provider Information: ID: %1 Name: %2 Callout Information: ID: %3 Name: %4 Type: %5 Run-Time ID: %6 Layer Information: ID: %7 Name: %8 Run-Time ID: %9 +5441, The following filter was present when the Windows Filtering Platform Base Filtering Engine started. Provider Information: ID: %1 Name: %2 Filter Information: ID: %3 Name: %4 Type: %5 Run-Time ID: %6 Layer Information: ID: %7 Name: %8 Run-Time ID: %9 Weight: %10 Additional Information: Conditions: %11 Filter Action: %12 Callout ID: %13 Callout Name: %14 +5442, The following provider was present when the Windows Filtering Platform Base Filtering Engine started. Provider ID: %1 Provider Name: %2 Provider Type: %3 +5443, The following provider context was present when the Windows Filtering Platform Base Filtering Engine started. Provider ID: %1 Provider Name: %2 Provider Context ID: %3 Provider Context Name: %4 Provider Context Type: %5 +5444, The following sub-layer was present when the Windows Filtering Platform Base Filtering Engine started. Provider ID: %1 Provider Name: %2 Sub-layer ID: %3 Sub-layer Name: %4 Sub-layer Type: %5 Weight: %6 +5446, A Windows Filtering Platform callout has been changed. Subject: Security ID: %2 Account Name: %3 Process Information: Process ID: %1 Provider Information: ID: %4 Name: %5 Change Information: Change Type: %6 Callout Information: ID: %7 Name: %8 Type: %9 Run-Time ID: %10 Layer Information: ID: %11 Name: %12 Run-Time ID: %13 +5447, A Windows Filtering Platform filter has been changed. Subject: Security ID: %2 Account Name: %3 Process Information: Process ID: %1 Provider Information: ID: %4 Name: %5 Change Information: Change Type: %6 Filter Information: ID: %7 Name: %8 Type: %9 Run-Time ID: %10 Layer Information: ID: %11 Name: %12 Run-Time ID: %13 Callout Information: ID: %17 Name: %18 Additional Information: Weight: %14 Conditions: %15 Filter Action: %16 +5448, A Windows Filtering Platform provider has been changed. Subject: Security ID: %2 Account Name: %3 Process Information: Process ID: %1 Change Information: Change Type: %4 Provider Information: ID: %5 Name: %6 Type: %7 +5449, A Windows Filtering Platform provider context has been changed. Subject: Security ID: %2 Account Name: %3 Process Information: Process ID: %1 Provider Information: Provider ID: %4 Provider Name: %5 Change Information: Change Type: %6 Provider Context: ID: %7 Name: %8 Type: %9 +5450, A Windows Filtering Platform sub-layer has been changed. Subject: Security ID: %2 Account Name: %3 Process Information: Process ID: %1 Provider Information: Provider ID: %4 Provider Name: %5 Change Information: Change Type: %6 Sub-layer Information: Sub-layer ID: %7 Sub-layer Name: %8 Sub-layer Type: %9 Additional Information: Weight: %10 +5451, An IPsec Quick Mode security association was established. Local Endpoint: Network Address: %1 Network Address mask: %2 Port: %3 Tunnel Endpoint: %4 Remote Endpoint: Network Address: %5 Network Address Mask: %6 Port: %7 Private Address: %8 Tunnel Endpoint: %9 Protocol: %10 Keying Module Name: %11 Cryptographic Information: Integrity Algorithm - AH: %12 Integrity Algorithm - ESP: %13 Encryption Algorithm: %14 Security Association Information: Lifetime - seconds: %15 Lifetime - data: %16 Lifetime - packets: %17 Mode: %18 Role: %19 Quick Mode Filter ID: %20 Main Mode SA ID: %21 Quick Mode SA ID: %22 Additional Information: Inbound SPI: %23 Outbound SPI: %24 +5452, An IPsec Quick Mode security association ended. Local Endpoint: Network Address: %1 Port: %2 Tunnel Endpoint: %3 Remote Endpoint: Network Address: %4 Port: %5 Tunnel Endpoint: %6 Additional Information: Protocol: %7 Quick Mode SA ID: %8 +5453, An IPsec negotiation with a remote computer failed because the IKE and AuthIP IPsec Keying Modules (IKEEXT) service is not started +5456, PAStore Engine applied Active Directory storage IPsec policy on the computer. Policy: %1 +5457, PAStore Engine failed to apply Active Directory storage IPsec policy on the computer. DN: %1 Error code: %2 +5458, PAStore Engine applied locally cached copy of Active Directory storage IPsec policy on the computer. Policy: %1 +5459, PAStore Engine failed to apply locally cached copy of Active Directory storage IPsec policy on the computer. Policy: %1 Error Code: %2 +5460, PAStore Engine applied local registry storage IPsec policy on the computer. Policy: %1 +5461, PAStore Engine failed to apply local registry storage IPsec policy on the computer. Policy: %1 Error Code: %2 +5462, PAStore Engine failed to apply some rules of the active IPsec policy on the computer. Use the IP Security Monitor snap-in to diagnose the problem. Policy: %1 Error Code: %2 +5463, PAStore Engine polled for changes to the active IPsec policy and detected no changes +5464, PAStore Engine polled for changes to the active IPsec policy, detected changes, and applied them to IPsec Services +5465, PAStore Engine received a control for forced reloading of IPsec policy and processed the control successfully +5466, PAStore Engine polled for changes to the Active Directory IPsec policy, determined that Active Directory cannot be reached, and will use the cached copy of the Active Directory IPsec policy instead. Any changes made to the Active Directory IPsec policy since the last poll could not be applied +5467, PAStore Engine polled for changes to the Active Directory IPsec policy, determined that Active Directory can be reached, and found no changes to the policy. The cached copy of the Active Directory IPsec policy is no longer being used +5468, PAStore Engine polled for changes to the Active Directory IPsec policy, determined that Active Directory can be reached, found changes to the policy, and applied those changes. The cached copy of the Active Directory IPsec policy is no longer being used +5471, PAStore Engine loaded local storage IPsec policy on the computer. Policy: %1 +5472, PAStore Engine failed to load local storage IPsec policy on the computer. Policy: %1 Error Code: %2 +5473, PAStore Engine loaded directory storage IPsec policy on the computer. Policy: %1 +5474, PAStore Engine failed to load directory storage IPsec policy on the computer. Policy: %1 Error Code: %2 +5477, PAStore Engine failed to add quick mode filter. Quick Mode Filter: %1 Error Code: %2 +5478, IPsec Services has started successfully +5479, IPsec Services has been shut down successfully. The shutdown of IPsec Services can put the computer at greater risk of network attack or expose the computer to potential security risks +5480, IPsec Services failed to get the complete list of network interfaces on the computer. This poses a potential security risk because some of the network interfaces may not get the protection provided by the applied IPsec filters. Use the IP Security Monitor snap-in to diagnose the problem +5483, IPsec Services failed to initialize RPC server. IPsec Services could not be started. Error Code: %1 +5484, IPsec Services has experienced a critical failure and has been shut down. The shutdown of IPsec Services can put the computer at greater risk of network attack or expose the computer to potential security risks. Error Code: %1 +5485, IPsec Services failed to process some IPsec filters on a plug-and-play event for network interfaces. This poses a potential security risk because some of the network interfaces may not get the protection provided by the applied IPsec filters. Use the IP Security Monitor snap-in to diagnose the problem +5632, A request was made to authenticate to a wireless network. Subject: Security ID: %2 Account Name: %3 Account Domain: %4 Logon ID: %5 Network Information: Name (SSID): %1 Interface GUID: %8 Local MAC Address: %7 Peer MAC Address: %6 Additional Information: Reason Code: %10 (%9) Error Code: %11 +5633, A request was made to authenticate to a wired network. Subject: Security ID: %2 Account Name: %3 Account Domain: %4 Logon ID: %5 Interface: Name: %1 Additional Information Reason Code: %7 (%6) Error Code: %8 +5712, A Remote Procedure Call (RPC) was attempted. Subject: SID: %1 Name: %2 Account Domain: %3 LogonId: %4 Process Information: PID: %5 Name: %6 Network Information: Remote IP Address: %7 Remote Port: %8 RPC Attributes: Interface UUID: %9 Protocol Sequence: %10 Authentication Service: %11 Authentication Level: %12 +5888, An object in the COM+ Catalog was modified. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: COM+ Catalog Collection: %5 Object Name: %6 Object Properties Modified: %7 +5889, An object was deleted from the COM+ Catalog. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: COM+ Catalog Collection: %5 Object Name: %6 Object Details: %7 This event occurs when an object is deleted from the COM+ catalog. +5890, An object was added to the COM+ Catalog. Subject: Security ID: %1 Account Name: %2 Account Domain: %3 Logon ID: %4 Object: COM+ Catalog Collection: %5 Object Name: %6 Object Details: %7 +6144, Security policy in the group policy objects has been applied successfully. Return Code: %1 GPO List: %2 +6145, One or more errors occured while processing security policy in the group policy objects. Error Code: %1 GPO List: %2 +6272, Network Policy Server granted access to a user. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Quarantine Information: Result: %25 Session Identifier: %26 +6273, Network Policy Server denied access to a user. Contact the Network Policy Server administrator for more information. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Reason Code: %25 Reason: %26 +6274, Network Policy Server discarded the request for a user. Contact the Network Policy Server administrator for more information. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Reason Code: %25 Reason: %26 +6275, Network Policy Server discarded the accounting request for a user. Contact the Network Policy Server administrator for more information. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Reason Code: %25 Reason: %26 +6276, Network Policy Server quarantined a user. Contact the Network Policy Server administrator for more information. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Quarantine Information: Result: %25 Extended-Result: %26 Session Identifier: %27 Help URL: %28 System Health Validator Result(s): %29 +6277, 0x8000000000000000 message: Network Policy Server granted access to a user but put it on probation because the host did not meet the defined health policy. Contact the Network Policy Server administrator for more information. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Quarantine Information: Result: %25 Extended-Result: %26 Session Identifier: %27 Help URL: %28 System Health Validator Result(s): %29 Quarantine Grace Time: %30 +6278, Network Policy Server granted full access to a user because the host met the defined health policy. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 Client Machine: Security ID: %5 Account Name: %6 Fully Qualified Account Name: %7 OS-Version: %8 Called Station Identifier: %9 Calling Station Identifier: %10 NAS: NAS IPv4 Address: %11 NAS IPv6 Address: %12 NAS Identifier: %13 NAS Port-Type: %14 NAS Port: %15 RADIUS Client: Client Friendly Name: %16 Client IP Address: %17 Authentication Details: Proxy Policy Name: %18 Network Policy Name: %19 Authentication Provider: %20 Authentication Server: %21 Authentication Type: %22 EAP Type: %23 Account Session Identifier: %24 Quarantine Information: Result: %25 Extended-Result: %26 Session Identifier: %27 Help URL: %28 System Health Validator Result(s): %29 +6279, Network Policy Server locked the user account due to repeated failed authentication attempts. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 +6280, Network Policy Server unlocked the user account. User: Security ID: %1 Account Name: %2 Account Domain: %3 Fully Qualified Account Name: %4 diff --git a/src/win32/win_agent.c b/src/win32/win_agent.c new file mode 100644 index 000000000..b11ee89ad --- /dev/null +++ b/src/win32/win_agent.c @@ -0,0 +1,542 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef WIN32 + +#include "shared.h" +#include "client-agent/agentd.h" +#include "logcollector/logcollector.h" +#include "os_win.h" +#include "os_net/os_net.h" +#include "os_execd/execd.h" +#include "os_crypto/md5/md5_op.h" + +#ifndef ARGV0 +#define ARGV0 "openarmor-agent" +#endif + +time_t __win32_curr_time = 0; +time_t __win32_shared_time = 0; +char *__win32_uname = NULL; +char *__win32_shared = NULL; +HANDLE hMutex; + +/** Prototypes **/ +int Start_win32_Syscheck(); +void send_win32_info(time_t curr_time); + + +/* Help message */ +void agent_help() +{ + printf("\n%s %s %s .\n", __openarmor_name, ARGV0, __openarmor_version); + printf("Available options:\n"); + printf("\t/? This help message.\n"); + printf("\t-h This help message.\n"); + printf("\thelp This help message.\n"); + printf("\tinstall-service Installs as a service\n"); + printf("\tuninstall-service Uninstalls as a service\n"); + printf("\tstart Manually starts (not from services)\n"); + exit(1); +} + +/* syscheck main thread */ +void *skthread() +{ + verbose("%s: Starting syscheckd thread.", ARGV0); + + Start_win32_Syscheck(); + + return (NULL); +} + +int main(int argc, char **argv) +{ + char *tmpstr; + char mypath[OS_MAXSTR + 1]; + char myfinalpath[OS_MAXSTR + 1]; + char myfile[OS_MAXSTR + 1]; + + /* Set the name */ + OS_SetName(ARGV0); + + /* Find where we are */ + mypath[OS_MAXSTR] = '\0'; + myfinalpath[OS_MAXSTR] = '\0'; + myfile[OS_MAXSTR] = '\0'; + + /* mypath is going to be the whole path of the file */ + strncpy(mypath, argv[0], OS_MAXSTR); + tmpstr = strrchr(mypath, '\\'); + if (tmpstr) { + /* tmpstr is now the file name */ + *tmpstr = '\0'; + tmpstr++; + strncpy(myfile, tmpstr, OS_MAXSTR); + } else { + strncpy(myfile, argv[0], OS_MAXSTR); + mypath[0] = '.'; + mypath[1] = '\0'; + } + chdir(mypath); + getcwd(mypath, OS_MAXSTR - 1); + snprintf(myfinalpath, OS_MAXSTR, "\"%s\\%s\"", mypath, myfile); + + if (argc > 1) { + if (strcmp(argv[1], "install-service") == 0) { + return (InstallService(myfinalpath)); + } else if (strcmp(argv[1], "uninstall-service") == 0) { + return (UninstallService()); + } else if (strcmp(argv[1], "start") == 0) { + return (local_start()); + } else if (strcmp(argv[1], "/?") == 0) { + agent_help(); + } else if (strcmp(argv[1], "-h") == 0) { + agent_help(); + } else if (strcmp(argv[1], "help") == 0) { + agent_help(); + } else { + merror("%s: Unknown option: %s", ARGV0, argv[1]); + exit(1); + } + } + + /* Start it */ + if (!os_WinMain(argc, argv)) { + ErrorExit("%s: Unable to start WinMain.", ARGV0); + } + + return (0); +} + +/* Locally start (after service/win init) */ +int local_start() +{ + int debug_level; + int accept_manager_commands = 0; + char *cfg = DEFAULTCPATH; + WSADATA wsaData; + DWORD threadID; + DWORD threadID2; + extern agent *agt; + + /* Start agent */ + agt = (agent *)calloc(1, sizeof(agent)); + if (!agt) { + ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); + } + agt->port = DEFAULT_SECURE; + + /* Get debug level */ + debug_level = getDefine_Int("windows", "debug", 0, 2); + while (debug_level != 0) { + nowDebug(); + debug_level--; + } + accept_manager_commands = getDefine_Int("logcollector", + "remote_commands", 0, 1); + loop_timeout = getDefine_Int("logcollector", "loop_timeout", 1, 120); + open_file_attempts = getDefine_Int("logcollector", "open_attempts", 2, 998); + + /* Configuration file not present */ + if (File_DateofChange(cfg) < 0) { + ErrorExit("%s: Configuration file '%s' not found", ARGV0, cfg); + } + + /* Start Winsock */ + if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { + ErrorExit("%s: WSAStartup() failed", ARGV0); + } + + /* Read agent config */ + debug1("%s: DEBUG: Reading agent configuration.", ARGV0); + if (ClientConf(cfg) < 0) { + ErrorExit(CLIENT_ERROR, ARGV0); + } + if (agt->notify_time == 0) { + agt->notify_time = NOTIFY_TIME; + } + if (agt->max_time_reconnect_try == 0 ) { + agt->max_time_reconnect_try = NOTIFY_TIME * 3; + } + if (agt->max_time_reconnect_try <= agt->notify_time) { + agt->max_time_reconnect_try = (agt->notify_time * 3); + verbose("%s: Max time to reconnect can't be less than notify_time(%d), using notify_time*3 (%d)", ARGV0, agt->notify_time, agt->max_time_reconnect_try); + } + verbose("%s: Using notify time: %d and max time to reconnect: %d", ARGV0, agt->notify_time, agt->max_time_reconnect_try); + + /* Read logcollector config file */ + debug1("%s: DEBUG: Reading logcollector configuration.", ARGV0); + if (LogCollectorConfig(cfg, accept_manager_commands) < 0) { + ErrorExit(CONFIG_ERROR, ARGV0, cfg); + } + + /* Check auth keys */ + if (!OS_CheckKeys()) { + ErrorExit(AG_NOKEYS_EXIT, ARGV0); + } + + /* If there is no file to monitor, create a clean entry + * for the mark messages. + */ + if (logff == NULL) { + os_calloc(2, sizeof(logreader), logff); + logff[0].file = NULL; + logff[0].ffile = NULL; + logff[0].logformat = NULL; + logff[0].fp = NULL; + logff[1].file = NULL; + logff[1].logformat = NULL; + + merror(NO_FILE, ARGV0); + } + + /* Read execd config */ + if (!WinExecd_Start()) { + agt->execdq = -1; + } + + /* Read keys */ + verbose(ENC_READ, ARGV0); + + OS_ReadKeys(&keys); + OS_StartCounter(&keys); + os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, agt->profile); + + /* Initialize random numbers */ + srandom(time(0)); + random(); + + /* Socket connection */ + agt->sock = -1; + StartMQ("", 0); + + /* Start mutex */ + debug1("%s: DEBUG: Creating thread mutex.", ARGV0); + hMutex = CreateMutex(NULL, FALSE, NULL); + if (hMutex == NULL) { + ErrorExit("%s: Error creating mutex.", ARGV0); + } + + /* Start syscheck thread */ + if (CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)skthread, + NULL, + 0, + (LPDWORD)&threadID) == NULL) { + merror(THREAD_ERROR, ARGV0); + } + + /* Check if server is connected */ + os_setwait(); + start_agent(1); + os_delwait(); + + /* Send integrity message for agent configs */ + intcheck_file(cfg, ""); + intcheck_file(openarmor_DEFINES, ""); + + /* Start receiver thread */ + if (CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)receiver_thread, + NULL, + 0, + (LPDWORD)&threadID2) == NULL) { + merror(THREAD_ERROR, ARGV0); + } + + /* Send agent information message */ + send_win32_info(time(0)); + + /* Start logcollector -- main process here */ + LogCollectorStart(); + + WSACleanup(); + return (0); +} + +/* SendMSG for Windows */ +int SendMSG(__attribute__((unused)) int queue, const char *message, const char *locmsg, char loc) +{ + int _ssize; + time_t cu_time; + const char *pl; + char tmpstr[OS_MAXSTR + 2]; + char crypt_msg[OS_MAXSTR + 2]; + DWORD dwWaitResult; + extern agent *agt; + + tmpstr[OS_MAXSTR + 1] = '\0'; + crypt_msg[OS_MAXSTR + 1] = '\0'; + + debug2("%s: DEBUG: Attempting to send message to server.", ARGV0); + + /* Using a mutex to synchronize the writes */ + while (1) { + dwWaitResult = WaitForSingleObject(hMutex, 1000000L); + + if (dwWaitResult != WAIT_OBJECT_0) { + switch (dwWaitResult) { + case WAIT_TIMEOUT: + merror("%s: Error waiting mutex (timeout).", ARGV0); + sleep(5); + continue; + case WAIT_ABANDONED: + merror("%s: Error waiting mutex (abandoned).", ARGV0); + return (0); + default: + merror("%s: Error waiting mutex.", ARGV0); + return (0); + } + } else { + /* Lock acquired */ + break; + } + } /* end - while for mutex... */ + + cu_time = time(0); + +#ifndef ONEWAY_ENABLED + /* Check if the server has responded */ + if ((cu_time - available_server) > agt->notify_time) { + debug1("%s: DEBUG: Sending info to server (c1)...", ARGV0); + verbose("%s: More than %d seconds without server response...sending win32info", ARGV0, agt->notify_time); + send_win32_info(cu_time); + + /* Attempt to send message again */ + if ((cu_time - available_server) > agt->notify_time) { + /* Try again */ + sleep(1); + send_win32_info(cu_time); + sleep(1); + + if ((cu_time - available_server) > agt->notify_time) { + send_win32_info(cu_time); + } + } + + /* If we reached here, the server is unavailable for a while */ + if ((cu_time - available_server) > agt->max_time_reconnect_try) { + int wi = 1; + verbose("%s: More than %d seconds without server response...is server alive? and Is there connection?", ARGV0, agt->max_time_reconnect_try); + + /* Last attempt before going into reconnect mode */ + debug1("%s: DEBUG: Sending info to server (c3)...", ARGV0); + sleep(1); + send_win32_info(cu_time); + if ((cu_time - available_server) > agt->max_time_reconnect_try) { + sleep(1); + send_win32_info(cu_time); + sleep(1); + } + + /* Check and generate log if unavailable */ + cu_time = time(0); + if ((cu_time - available_server) > agt->max_time_reconnect_try) { + int global_sleep = 1; + int mod_sleep = 12; + + /* If response is not available, set lock and wait for it */ + verbose(SERVER_UNAV, ARGV0); + + /* Go into reconnect mode */ + while ((cu_time - available_server) > agt->max_time_reconnect_try) { + /* Send information to see if server replies */ + if (agt->sock != -1) { + send_win32_info(cu_time); + } + + sleep(wi); + cu_time = time(0); + + if (wi < 20) { + wi++; + } else { + global_sleep++; + } + + /* If we have more than one server, try all */ + if (wi > 12 && agt->rip[1]) { + int curr_rip = agt->rip_id; + merror("%s: INFO: Trying next server ip in " + "line: '%s'.", + ARGV0, + agt->rip[agt->rip_id + 1] != NULL ? + agt->rip[agt->rip_id + 1] : + agt->rip[0]); + + connect_server(agt->rip_id + 1); + + if (agt->rip_id != curr_rip) { + wi = 1; + } + } else if (global_sleep == 2 || ((global_sleep % mod_sleep) == 0) || + (agt->sock == -1)) { + connect_server(agt->rip_id + 1); + if (agt->sock == -1) { + sleep(wi + global_sleep); + } else { + sleep(global_sleep); + } + + if (global_sleep > 30) { + mod_sleep = 50; + } + } + } + + verbose(AG_CONNECTED, ARGV0, agt->rip[agt->rip_id], + agt->port); + verbose(SERVER_UP, ARGV0); + } + } + } +#else + if (0) { + } +#endif + + /* Send notification */ + else if ((cu_time - __win32_curr_time) > (NOTIFY_TIME - 200)) { + debug1("%s: DEBUG: Sending info to server (ctime2)...", ARGV0); + send_win32_info(cu_time); + } + + /* locmsg cannot have the C:, as we use it as delimiter */ + pl = strchr(locmsg, ':'); + if (pl) { + /* Set pl after the ":" if it exists */ + pl++; + } else { + pl = locmsg; + } + + + debug2("%s: DEBUG: Sending message to server: '%s'", ARGV0, message); + + snprintf(tmpstr, OS_MAXSTR, "%c:%s:%s", loc, pl, message); + _ssize = CreateSecMSG(&keys, tmpstr, crypt_msg, 0); + + /* Returns NULL if can't create encrypted message */ + if (_ssize == 0) { + merror(SEC_ERROR, ARGV0); + if (!ReleaseMutex(hMutex)) { + merror("%s: Error releasing mutex.", ARGV0); + } + + return (-1); + } + + /* Send _ssize of crypt_msg */ + if (OS_SendUDPbySize(agt->sock, _ssize, crypt_msg) < 0) { + merror(SEND_ERROR, ARGV0, "server"); + sleep(1); + } + + if (!ReleaseMutex(hMutex)) { + merror("%s: Error releasing mutex.", ARGV0); + } + return (0); +} + +/* StartMQ for Windows */ +int StartMQ(const char *path, short int type) +{ + /* Connect to the server */ + connect_server(0); + + if ((path == NULL) && (type == 0)) { + return (0); + } + + return (0); +} + +/* Send win32 info to server */ +void send_win32_info(time_t curr_time) +{ + int msg_size; + char tmp_msg[OS_MAXSTR + 2]; + char crypt_msg[OS_MAXSTR + 2]; + + tmp_msg[OS_MAXSTR + 1] = '\0'; + crypt_msg[OS_MAXSTR + 1] = '\0'; + + extern agent *agt; + + debug1("%s: DEBUG: Sending keep alive message.", ARGV0); + + /* Fix time */ + __win32_curr_time = curr_time; + + /* Get uname */ + if (!__win32_uname) { + __win32_uname = getuname(); + if (!__win32_uname) { + merror("%s: Error generating system information.", ARGV0); + os_strdup("Microsoft Windows - Unknown (unable to get system info)", __win32_uname); + } + } + + /* Get shared files list -- every 30 seconds only */ + if ((__win32_curr_time - __win32_shared_time) > 30) { + if (__win32_shared) { + free(__win32_shared); + __win32_shared = NULL; + } + + __win32_shared_time = __win32_curr_time; + } + + /* Get shared files */ + if (!__win32_shared) { + __win32_shared = getsharedfiles(); + if (!__win32_shared) { + __win32_shared = strdup("\0"); + if (!__win32_shared) { + merror(MEM_ERROR, ARGV0, errno, strerror(errno)); + return; + } + } + } + + /* Create message */ + if (File_DateofChange(AGENTCONFIGINT) > 0) { + os_md5 md5sum; + if (OS_MD5_File(AGENTCONFIGINT, md5sum, OS_TEXT) != 0) { + snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared); + } else { + snprintf(tmp_msg, OS_SIZE_1024, "#!-%s / %s\n%s", __win32_uname, md5sum, __win32_shared); + } + } else { + snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared); + } + + /* Create message */ + debug1("%s: DEBUG: Sending keep alive: %s", ARGV0, tmp_msg); + + msg_size = CreateSecMSG(&keys, tmp_msg, crypt_msg, 0); + + if (msg_size == 0) { + merror(SEC_ERROR, ARGV0); + return; + } + + /* Send UDP message */ + if (OS_SendUDPbySize(agt->sock, msg_size, crypt_msg) < 0) { + merror(SEND_ERROR, ARGV0, "server"); + sleep(1); + } + + return; +} + +#endif diff --git a/src/win32/win_service.c b/src/win32/win_service.c new file mode 100644 index 000000000..806478f0d --- /dev/null +++ b/src/win32/win_service.c @@ -0,0 +1,315 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation. + */ + +#ifdef WIN32 + +#include "shared.h" +#include "os_win.h" +#include + +#ifndef ARGV0 +#define ARGV0 "openarmor-agent" +#endif + +static LPTSTR g_lpszServiceName = "openarmorSvc"; +static LPTSTR g_lpszServiceDisplayName = "openarmor HIDS"; +static LPTSTR g_lpszServiceDescription = "openarmor HIDS Windows Agent"; + +static SERVICE_STATUS openarmorServiceStatus; +static SERVICE_STATUS_HANDLE openarmorServiceStatusHandle; + +void WINAPI openarmorServiceStart (DWORD argc, LPTSTR *argv); + + +/* Start openarmor-HIDS service */ +int os_start_service() +{ + int rc = 0; + SC_HANDLE schSCManager, schService; + + /* Start the database */ + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (schSCManager) { + schService = OpenService(schSCManager, g_lpszServiceName, + SC_MANAGER_ALL_ACCESS); + if (schService) { + if (StartService(schService, 0, NULL)) { + rc = 1; + } else { + if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { + rc = -1; + } + } + + CloseServiceHandle(schService); + } + + CloseServiceHandle(schSCManager); + } + + return (rc); +} + +/* Stop openarmor-HIDS service */ +int os_stop_service() +{ + int rc = 0; + SC_HANDLE schSCManager, schService; + + /* Stop the service database */ + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (schSCManager) { + schService = OpenService(schSCManager, g_lpszServiceName, + SC_MANAGER_ALL_ACCESS); + if (schService) { + SERVICE_STATUS lpServiceStatus; + + if (ControlService(schService, SERVICE_CONTROL_STOP, &lpServiceStatus)) { + rc = 1; + } + + CloseServiceHandle(schService); + } + + CloseServiceHandle(schSCManager); + } + + return (rc); +} + +/* Check if the openarmor-HIDS agent service is running + * Returns 1 on success (running) or 0 if not running + */ +int CheckServiceRunning() +{ + int rc = 0; + SC_HANDLE schSCManager, schService; + + /* Check service status */ + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (schSCManager) { + schService = OpenService(schSCManager, g_lpszServiceName, + SC_MANAGER_ALL_ACCESS); + if (schService) { + /* Check status */ + SERVICE_STATUS lpServiceStatus; + + if (QueryServiceStatus(schService, &lpServiceStatus)) { + if (lpServiceStatus.dwCurrentState == SERVICE_RUNNING) { + rc = 1; + } + } + CloseServiceHandle(schService); + } + + CloseServiceHandle(schSCManager); + } + + return (rc); +} + +/* Install the openarmor-HIDS agent service */ +int InstallService(char *path) +{ + int ret; + SC_HANDLE schSCManager, schService; + LPCTSTR lpszBinaryPathName = NULL; + SERVICE_DESCRIPTION sdBuf; + + /* Uninstall service (if it exists) */ + if (!UninstallService()) { + verbose("%s: ERROR: Failure running UninstallService().", ARGV0); + return (0); + } + + /* Executable path -- it must be called with the full path */ + lpszBinaryPathName = path; + + /* Opening the service database */ + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + if (schSCManager == NULL) { + goto install_error; + } + + /* Create the service */ + schService = CreateService(schSCManager, + g_lpszServiceName, + g_lpszServiceDisplayName, + SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + lpszBinaryPathName, + NULL, NULL, NULL, NULL, NULL); + + if (schService == NULL) { + CloseServiceHandle(schSCManager); + goto install_error; + } + + /* Set description */ + sdBuf.lpDescription = g_lpszServiceDescription; + ret = ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdBuf); + + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + + /* Check for errors */ + if (!ret) { + goto install_error; + } + + verbose("%s: INFO: Successfully added to the service database.", ARGV0); + return (1); + +install_error: { + char local_msg[1025]; + LPVOID lpMsgBuf; + + memset(local_msg, 0, 1025); + + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL); + + verbose("%s: ERROR: Unable to create service entry: %s", ARGV0, (LPCTSTR)lpMsgBuf); + return (0); + } +} + +/* Uninstall the openarmor-HIDS agent service */ +int UninstallService() +{ + int ret; + int rc = 0; + SC_HANDLE schSCManager, schService; + SERVICE_STATUS lpServiceStatus; + + /* Remove from the service database */ + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (schSCManager) { + schService = OpenService(schSCManager, g_lpszServiceName, SERVICE_STOP | DELETE); + if (schService) { + if (CheckServiceRunning()) { + verbose("%s: INFO: Found (%s) service is running going to try and stop it.", ARGV0, g_lpszServiceName); + ret = ControlService(schService, SERVICE_CONTROL_STOP, &lpServiceStatus); + if (!ret) { + verbose("%s: ERROR: Failure stopping service (%s) before removing it (%ld).", ARGV0, g_lpszServiceName, GetLastError()); + } else { + verbose("%s: INFO: Successfully stopped (%s).", ARGV0, g_lpszServiceName); + } + } else { + verbose("%s: INFO: Found (%s) service is not running.", ARGV0, g_lpszServiceName); + ret = 1; + } + + if (ret && DeleteService(schService)) { + verbose("%s: INFO: Successfully removed (%s) from the service database.", ARGV0, g_lpszServiceName); + rc = 1; + } + CloseServiceHandle(schService); + } else { + verbose("%s: INFO: Service does not exist (%s) nothing to remove.", ARGV0, g_lpszServiceName); + rc = 1; + } + CloseServiceHandle(schSCManager); + } + + if (!rc) { + verbose("%s: ERROR: Failure removing (%s) from the service database.", ARGV0, g_lpszServiceName); + } + + return (rc); +} + +/* "Signal" handler */ +VOID WINAPI openarmorServiceCtrlHandler(DWORD dwOpcode) +{ + switch (dwOpcode) { + case SERVICE_CONTROL_STOP: + openarmorServiceStatus.dwCurrentState = SERVICE_STOPPED; + openarmorServiceStatus.dwWin32ExitCode = 0; + openarmorServiceStatus.dwCheckPoint = 0; + openarmorServiceStatus.dwWaitHint = 0; + + verbose("%s: INFO: Received exit signal.", ARGV0); + SetServiceStatus (openarmorServiceStatusHandle, &openarmorServiceStatus); + verbose("%s: INFO: Exiting...", ARGV0); + return; + default: + break; + } + return; +} + +/* Set the error code in the service */ +void WinSetError() +{ + openarmorServiceCtrlHandler(SERVICE_CONTROL_STOP); +} + +/* Initialize openarmor-HIDS dispatcher */ +int os_WinMain(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) +{ + SERVICE_TABLE_ENTRY steDispatchTable[] = { + { g_lpszServiceName, openarmorServiceStart }, + { NULL, NULL } + }; + + if (!StartServiceCtrlDispatcher(steDispatchTable)) { + verbose("%s: INFO: Unable to set service information.", ARGV0); + return (1); + } + + return (1); +} + +/* Start openarmor service */ +void WINAPI openarmorServiceStart (__attribute__((unused)) DWORD argc, __attribute__((unused)) LPTSTR *argv) +{ + openarmorServiceStatus.dwServiceType = SERVICE_WIN32; + openarmorServiceStatus.dwCurrentState = SERVICE_START_PENDING; + openarmorServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + openarmorServiceStatus.dwWin32ExitCode = 0; + openarmorServiceStatus.dwServiceSpecificExitCode = 0; + openarmorServiceStatus.dwCheckPoint = 0; + openarmorServiceStatus.dwWaitHint = 0; + + openarmorServiceStatusHandle = + RegisterServiceCtrlHandler(g_lpszServiceName, + openarmorServiceCtrlHandler); + + if (openarmorServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { + verbose("%s: INFO: RegisterServiceCtrlHandler failed.", ARGV0); + return; + } + + openarmorServiceStatus.dwCurrentState = SERVICE_RUNNING; + openarmorServiceStatus.dwCheckPoint = 0; + openarmorServiceStatus.dwWaitHint = 0; + + if (!SetServiceStatus(openarmorServiceStatusHandle, &openarmorServiceStatus)) { + verbose("%s: INFO: SetServiceStatus error.", ARGV0); + return; + } + +#ifdef openarmorHIDS + /* Start process */ + local_start(); +#endif +} + +#endif /* WIN32 */